vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbacknächstes Kapitel


Woche 2

Tag 11

MDI-Anwendungen

Heute lernen Sie, wie man mit Visual C++ MDI-Anwendungen erstellt. MDI steht für Multiple Document Interface, zu deutsch Mehrfachdokumentschnittstelle. Damit lassen sich Anwendungen erstellen, bei denen der Benutzer an mehreren Dokumenten gleichzeitig arbeiten und zwischen den Fenstern der Anwendung umschalten kann. In diesem Kapitel erfahren Sie, ...

Was sind MDI-Anwendungen?

In bezug auf die Codierung mit Visual C++ gibt es kaum einen Unterschied zwischen SDI- und MDI-Anwendungen. Erst wenn man tiefer in die beiden Anwendungsstile einsteigt, treten die Unterschiede zutage. Eine SDI-Anwendung erlaubt dem Benutzer lediglich, an einem Dokument zu einem bestimmten Zeitpunkt zu arbeiten und läßt dabei nur einen einzigen Dokumenttyp zu. MDI-Anwendungen erlauben dagegen dem Benutzer nicht nur, an mehreren Dokumenten gleichzeitig zu arbeiten, sondern bieten auch die Möglichkeit, mehrere Arten von Dokumenten zu behandeln.

Eine MDI-Anwendung ist in einer Art Fenster-in-Fenster aufgebaut, wobei ein Rahmenfenster ein oder mehrere untergeordnete Fenster umschließt. Diesen Anwendungsstil findet man in vielen bekannten Softwarepaketen wie zum Beispiel Word und Excel.

Die Architektur einer MDI-Anwendung entspricht weitgehend der einer SDI-Anwendung. Praktisch besteht der einzige Unterschied bei einer einfachen MDI-Anwendung nur darin, daß der Anwendungs-Assistent neben den üblichen Klassen noch eine zweite Rahmenklasse erzeugt, wie es Abbildung 11.1 zeigt. Der Abbildung können Sie auch entnehmen, daß die Herangehensweise bei der Entwicklung von MDI-Anwendungen der für SDI-Anwendungen sehr ähnlich ist.

Abbildung 11.1:
Die Dokument/Ansicht-Architektur einer MDI-Anwendung

Für eine MDI-Anwendung erstellen Sie lediglich eine Klasse mehr als bei einer SDI- Anwendung. Zu diesen Klassen gehören:

Die beiden MDI-spezifischen Klassen CMDIFrameWnd (die Klasse CMainFrame in Ihrem Projekt) und CMDIChildWnd (die Klasse CChildFrame in Ihrem Projekt) sind die beiden einzigen Klassen, die sich von den bisher erstellten SDI-Anwendungen unterscheiden.

Die von CMDIFrameWnd abgeleitete Klasse CMainFrame stellt den Hauptrahmen der Anwendung dar und liefert einen abgeschlossenen Bereich auf dem Desktop, in dem die gesamte Interaktion der Anwendung stattfindet. Mit dem Rahmenfenster sind das Menü und die Symbolleisten verbunden.

Die von CMDIChildWnd abgeleitete Klasse CChildFrame bildet den Rahmen, der die CView-Klassen aufnimmt. Dieser Rahmen leitet die Nachrichten und Ereignisse an die Ansichtsklasse zur Verarbeitung oder Anzeige weiter.

Gewissermaßen ist die Funktionalität der Rahmenklasse einer SDI-Anwendung in die beiden MDI-spezifischen Klassen einer MDI-Anwendung aufgeteilt worden. Gleichzeitig gibt es eine zusätzliche Unterstützung für die Ausführung mehrerer untergeordneter Rahmen in deren eigenen Dokument/Ansicht-Klasseninstanzen.

Ein MDI-Zeichenprogramm erstellen

Damit Sie sich selbst davon überzeugen können, wie ähnlich sich die Dokument/Ansicht-Architekturen von SDI- und MDI-Anwendungen sind, erstellen Sie heute die gleiche Zeichenanwendung wie gestern - nur eben als MDI-Anwendung.

Das Anwendungsgerüst erstellen

Das Gerüst für die heutige Beispielanwendung erstellen Sie in folgenden Schritten:

1. Legen Sie mit dem Anwendungs-Assistenten ein neues Projekt namens Tag11 an.

2. Im ersten Dialogfeld des Anwendungs-Assistenten wählen Sie die Option Mehrere Dokumente (MDI), wie es Abbildung 11.2 zeigt.

Abbildung 11.2:
Eine MDI-Anwendung festlegen

3. Übernehmen Sie die Voreinstellungen im zweiten Schritt des Assistenten.

4. Im dritten Dialogfeld des Anwendungs-Assistenten schalten Sie die Unterstützung für ActiveX-Steuerelemente aus.

5. Im vierten Dialogfeld lassen Sie die Voreinstellungen unverändert und klicken auf die Schaltfläche Weitere Optionen.

6. Im Dialogfeld Weitere Optionen geben Sie eine aus drei Buchstaben bestehende Erweiterung für die Dateien ein, die Ihre Anwendung generiert (beispielsweise dhc oder dvp). Klicken Sie auf die Schaltfläche Schliessen, um das Dialogfeld zu schließen, und dann auf Weiter, um zum nächsten Schritt des Anwendungs-Assistenten zu gelangen.

7. Übernehmen Sie die Standardeinstellungen im fünften Schritt des Assistenten.

8. Im sechsten und letzten Dialogfeld des Anwendungs-Assistenten übernehmen Sie CView als Basisklasse und klicken auf Fertigstellen. Der Anwendungs-Assistent generiert nun das Gerüst der Anwendung.

Die Zeichenfunktionalität realisieren

Da Sie die gleiche Anwendung wie gestern, allerdings jetzt als MDI-Version, erstellen, nehmen Sie auch die gleiche Funktionalität in die Anwendung auf, die Sie bereits aus der vergangenen Lektion kennen. Um Zeit zu sparen und noch einmal die Ähnlichkeit der beiden Anwendungsarchitekturen zu betonen, führen Sie die gleichen Schritte wie gestern aus, um die Klasse CLine zu erstellen und die Funktionalität - diesmal in die Klassen CTag11Doc und CTag11View - hinzuzufügen. Bauen Sie auch die Unterstützung für die Auswahl der Farben und der Stiftbreite (wie in der Übung zu Tag 10) in die Klassen CTag11Doc und CLine ein, nehmen Sie aber noch keine Behandlungsfunktionen für Menüereignisse auf, und lassen Sie auch noch das Farbmenü außen vor. Bei diesem Entwicklungsstand haben Sie nun eine Anwendung vor sich, bei der Sie mehrere Zeichnungen öffnen können, wobei aber nur die Zeichenfarbe Schwarz zur Verfügung steht.

Da die Menüs noch nicht erstellt sind und die Initialisierung der Farben auf die IDs des Farbmenüs zurückgreift, sollten Sie vorerst die Initialisierung der Farbe mit 0 fest codieren, damit sich die Anwendung kompilieren läßt. Nachdem Sie das Farbmenü hinzugefügt haben, stehen auch die Menü-IDs zur Verfügung, so daß Sie wieder die IDs in Ihrem Code verwenden können. In der Zwischenzeit ändern Sie in der Funktion OnNewDocument der Klasse CTag11Doc die Zeile

m_nColor = ID_COLOR_BLACK - ID_COLOR_BLACK;

in

m_nColor = 0;

In der Funktion GetColor ist eine äquivalente Änderung erforderlich, da auch diese Funktion eine der IDs des Farbmenüs verwendet.

Die Funktionalität zur Menübehandlung realisieren

Nachdem nun die gesamte Funktionalität in die Anwendung eingebunden ist, möchten Sie sicherlich das Farbmenü hinzufügen, damit sich alle Farben für die Zeichnungen verwenden lassen. Wenn Sie den Baum auf der Registerkarte Ressourcen erweitern und in den Ordner Menu sehen, finden Sie nicht nur ein, sondern zwei definierte Menüs. In welches nehmen Sie nun das Farbmenü auf?

Das Menü IDR_MAINFRAME ist verfügbar, wenn keine untergeordneten Fenster geöffnet sind. Wenn Sie Ihre Anwendung ausführen und alle untergeordneten Fenster schließen, wechselt die Menüleiste, und es verschwinden alle Menüs, die sich auf untergeordnete Fenster beziehen. Sobald Sie ein anderes Dokument - entweder ein neues oder ein vorhandenes - öffnen, ändert sich die Menüleiste erneut und zeigt alle Menüs an, die für die Dokumente maßgeblich sind.

Das Menü IDR_TAG11TYPE erscheint, wenn ein untergeordnetes Fenster geöffnet ist. Dieses Menü enthält alle Funktionen, die sich auf Dokumente beziehen. Demzufolge fügen Sie das Farbmenü in dieses Menü ein. Dabei gehen Sie genauso vor, wie am gestrigen Tag, und verwenden auch die gleichen Menüeigenschaften.

Für das Menü Farbe müssen Sie jetzt eine andere Zugriffstaste festlegen, da der - gestern verwendete - Buchstabe F in der heutigen MDI-Anwendung bereits für das Menü Fenster vergeben ist.

Nachdem Sie alle Menübefehle hinzugefügt haben, sind noch die Behandlungsroutinen für die Menüereignisse zu realisieren. Heute implementieren wir die Behandlungsroutinen nach einem anderen Ansatz als gestern. Der Abschnitt »Fragen und Antworten« am Ende des gestrigen Kapitels hat die Frage nach einer einzigen Behandlungsroutine für alle Befehle des Farbmenüs aufgeworfen. Heute setzen Sie diesen Gedanken in die Tat um. Leider versteht der Klassen-Assistent nicht, wie sich mehrere Menünachrichten an dieselbe Funktion weiterleiten lassen, so daß Sie das in eigener Regie nach den folgenden Schritten realisieren müssen:

1. Öffnen Sie die Header-Datei Tag11Doc.h.

2. Gehen Sie in der Header-Datei nach unten, bis Sie zum geschützten (protected) Abschnitt mit der Deklaration der Nachrichtenzuordnungstabelle AFX_MSG gelangen (suchen Sie nach //{{AFX_MSG(CTag11Doc)).

3. Fügen Sie die Funktionsdeklarationen aus Listing 11.1 vor der gesuchten Zeile hinzu. (Der Suchstring kennzeichnet den Beginn der vom Klassen-Assistenten verwalteten Nachrichtenzuordnungstabelle. Alles, was Sie zwischen diese Markierung und die Endemarkierung //}}AFX_MSG schreiben, betrachtet der Klassen-Assistent als sein »Eigentum« und wird es möglicherweise entfernen oder verstümmeln.)

Listing 11.1: Die Deklarationen der Behandlungsroutine in Tag11Doc.h

.
.
.
1: #ifdef _DEBUG
2: virtual void AssertValid() const;
3: virtual void Dump(CDumpContext& dc) const;
4: #endif
5:
6: protected:
7:
8: // Generierte Message-Map-Funktionen
9: protected:
10: afx_msg void OnColorCommand(UINT nID);
11: afx_msg void OnUpdateColorUI(CCmdUI* pCmdUI);
12: //{{AFX_MSG(CTag11Doc)
13: // HINWEIS - An dieser Stelle werden Member-Funktionen vom Klassen- ÂAssistenten eingefügt und entfernt.
14: // Innerhalb dieser generierten Quelltextabschnitte NICHTS ÂVERÄNDERN!
15: //}}AFX_MSG
16: DECLARE_MESSAGE_MAP()
17: private:
18: UINT m_nColor;
19: CObArray m_oaLines;
20: };

4. Öffnen Sie die Quellcodedatei Tag11Doc.cpp.

5. Suchen Sie nach der Zeile BEGIN_MESSAGE_MAP, und fügen Sie unmittelbar danach die Zeilen aus Listing 11.2 ein. Es ist wichtig, daß dieser Code zwischen der Zeile BEGIN_MESSAGE_MAP und der Zeile //{{AFX_MSG_MAP steht. Wenn Sie diese Befehle zwischen die Zeilen //{{AFX_MSG_MAP und //}}AFX_MSG_MAP schreiben, entfernt oder verstümmelt sie der Klassen-Assistent.

Listing 11.2: Die Einträge der Nachrichtenzuordnungstabelle in Tag11Doc.cpp

1: /////////////////////////////////////////////////////////////////////////////
2: // CTag11Doc
3:
4: IMPLEMENT_DYNCREATE(CTag11Doc, CDocument)
5:
6: BEGIN_MESSAGE_MAP(CTag11Doc, CDocument)
7: ON_COMMAND_RANGE(ID_COLOR_BLACK, ID_COLOR_WHITE, OnColorCommand)
8: ON_UPDATE_COMMAND_UI_RANGE(ID_COLOR_BLACK, ID_COLOR_WHITE, ÂOnUpdateColorUI)
9: //{{AFX_MSG_MAP(CTag11Doc)
10: // HINWEIS - Hier werden Mapping-Makros vom Klassen-Assistenten Âeingefügt und entfernt.
11: // Innerhalb dieser generierten Quelltextabschnitte NICHTS ÂVERÄNDERN!
12: //}}AFX_MSG_MAP
13: END_MESSAGE_MAP()
14:
15: const COLORREF CTag11Doc::m_crColors[8] = {
16: RGB( 0, 0, 0), // Schwarz
17: RGB( 0, 0, 255), // Blau
18: .
19: .
20: .

6. Gehen Sie ans Ende der Datei, und fügen Sie die beiden Behandlungsroutinen gemäß Listing 11.3 hinzu.

Listing 11.3: Die Behandlungsroutinen für das Farbmenü

1: void CTag11Doc::OnColorCommand(UINT nID)
2: {
3: // Aktuelle Farbe setzen
4: m_nColor = nID - ID_COLOR_BLACK;
5: }
6:
7: void CTag11Doc::OnUpdateColorUI(CCmdUI* pCmdUI)
8: {
9: // Prüfen, ob Menübefehl mit Kontrollhäkchen zu versehen ist
10: pCmdUI->SetCheck(GetColor() == pCmdUI->m_nID ? 1 : 0);
11: }

In Listing 11.1 sind die beiden hinzugefügten Funktionsdeklarationen als Behandlungsroutinen für Nachrichten durch die Deklaration des Funktionstyps afx_msg spezifiziert. Diese Art der Funktionsdeklarationen muß mit geschütztem Zugriff versehen sein. Ansonsten sind diese Funktionen praktisch identisch mit jeder anderen Funktionsdeklaration von Klassenelementen.

In Listing 11.2 handelt es sich bei den beiden Einträgen ON_COMMAND_RANGE und ON_UPDATE_COMMAND_UI_RANGE in der Nachrichtenzuordnungstabelle um Standardeinträge, die aber der Klassen-Assistent weder unterstützt noch versteht. Wenn Sie sich die Einträge der Nachrichtenzuordnungstabelle in den Anwendungen der vergangenen Tage ansehen, finden Sie die Einträge ON_COMMAND und ON_UPDATE_COMMAND_UI. Diese Makros haben zwei Argumente, die Nachrichten-ID und der Name der Behandlungsfunktion, die für die Nachricht aufzurufen ist. Die neuen Einträge in der Nachrichtenzuordnungstabelle funktionieren genauso, weisen aber zwei Argumente für Nachrichten-IDs statt nur ein Argument auf. Die beiden ID-Argumente markieren Anfang und Ende eines Bereichs von Nachrichten-IDs, der an die spezifizierte Funktion zu übergeben ist. Die beiden Nachrichten-IDs beziehen sich auf den ersten und letzten Menübefehl, die Sie im Farbmenü erstellt haben.

Die Nachrichtenzuordnungstabelle ist ein von Visual C++ und MFC verwendeter Mechanismus, um in einfacher Weise Ereignisnachrichten und die jeweils aufzurufenden Behandlungsfunktionen zu spezifizieren. Die Befehle in der Nachrichtenzuordnungstabelle konvertiert der Visual C++-Compiler in eine schnelle und effiziente Tabelle für den Aufruf der passenden Behandlungsroutine, wenn die Anwendung eine Nachricht erhält. Immer, wenn Sie eine Funktion über den Klassen-Assistenten aufnehmen, fügen Sie nicht nur die Funktion in den Code hinzu, sondern auch einen Eintrag in die Nachrichtenzuordnungstabelle für diese Klasse.

Wenn Sie den Eintrag ON_COMMAND_RANGE der Nachrichtenzuordnungstabelle verwenden, wird die Nachrichten-ID automatisch als Argument an die Behandlungsfunktion übergeben. Dadurch ist es möglich, die Funktion entsprechend Listing 11.3 zu erstellen, um die Nachrichten der Farbauswahl zu behandeln. Wenn Sie die Anwendung zum jetzigen Zeitpunkt kompilieren und ausführen, sollte die Farbauswahl genau wie in der gestrigen Anwendung funktionieren (siehe Abbildung 11.3).

Abbildung 11.3:
Die MDI-Anwendung ausführen

Ein Kontextmenü hinzufügen

In den meisten Windows-Anwendungen kann man mit der rechten Maustaste klicken, und es erscheint ein sogenanntes Kontextmenü oder Popup-Menü. In Lektion 6 haben Sie bereits ein einfaches Kontextmenü erstellt. Allerdings gibt es einen bestimmten Mechanismus für das Erstellen und Verwenden dieser Kontextmenüs, wenn Windows annimmt, daß das Menü geöffnet werden sollte. Nach diesem Verfahren können Sie Kontextmenüs hinzufügen, die sich genau wie bei jeder anderen Windows-Anwendung verhalten (und wenn Microsoft den Auslösemechanismus von Kontextmenüs bei einer neueren Version von Windows ändert, verhält sich Ihre Anwendung weiterhin dem Windows-Standard entsprechend).

Windows schreibt in die Ereigniswarteschlange die Nachricht WM_CONTEXTMENU, wenn der Benutzer die rechte Maustaste losläßt oder die Taste für das Kontextmenü (bei neueren Windows-Tastaturen) betätigt. Wenn Sie eine Behandlungsroutine für die Nachricht WM_CONTEXTMENU vorsehen, können Sie ein Kontextmenü anzeigen und darauf vertrauen, daß es genau zum richtigen Zeitpunkt erscheint.

Um die Anwendung mit einem Kontextmenü auszustatten, erstellen Sie ein neues Menü, das als Kontextmenü dient. Führen Sie dazu die folgenden Schritte aus:

1. Klicken Sie im Arbeitsbereich auf der Registerkarte Ressourcen mit der rechten Maustaste auf den Ordner Menu.

2. Wählen Sie den Befehl Menu einfügen aus dem Kontextmenü.

3. Markieren Sie (immer noch im Arbeitsbereich) das neue Menü, öffnen Sie das zugehörige Eigenschaftsdialogfeld, und nennen Sie das Menü IDR_CONTEXTMENU.

4. Im Menü-Editor geben Sie als Titel für die Hauptmenüebene ein einzelnes Leerzeichen an. Das bewirkt, daß Visual C++ den ersten Menübefehl in den Dropdown- Bereich des Menüs hinzufügt.

5. Legen Sie für den ersten Menübefehl den Titel Brei&te fest, und schalten Sie das Kontrollkästchen Popup ein. (Daraufhin wird das Kombinationsfeld ID deaktiviert, der Titel des gerade modifizierten Menübefehls zeigt einen Pfeil, und rechts daneben erscheint ein weiterer Menübefehl.)

6. Fügen Sie zu diesem Zeitpunkt noch keine Menübefehle in das überlappende Menü Breite hinzu (das heben wir uns für eine Übung am Ende des Kapitels auf). Markieren Sie statt dessen den Menübefehl unterhalb des Befehls Breite, und öffnen Sie dessen Eigenschaftsdialogfeld. Legen Sie die Beschriftung mit Fa&rben fest, und schalten Sie das Kontrollkästchen Popup ein.

7. Nehmen Sie in das überlappende Farbmenü die Menübefehle für die Farben auf, wie Sie es bereits für das Menü IDR_TAG11TYPE vorgenommen haben. Verwenden Sie auch die gleichen Eigenschaftseinstellungen. Wenn Sie die ID lieber suchen, statt per Hand einzutippen, können Sie sie auch aus der Dropdown-Liste ID auswählen. Wenn Sie damit fertig sind, sollte das Menü wie in Abbildung 11.4 aussehen.

Abbildung 11.4:
Der Entwurf des Kontextmenüs

8. Gehen Sie im Arbeitsbereich auf die Registerkarte Klassen.

9. Markieren Sie die Klasse CTag11View. Öffnen Sie den Klassen-Assistenten über Ansicht / Klassen-Assistent.

10. Fügen Sie eine Funktion für die Nachricht WM_CONTEXTMENU in die Klasse CTag11View ein.

11. Schreiben Sie in die Funktion den Code aus Listing 11.4.

Listing 11.4: Die Funktion OnContextMenu der Klasse CTag11View

1: void CTag11View::OnContextMenu(CWnd* pWnd, CPoint point)
2: {
3: // TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen
4:
5: ///////////////////////
6: // EIGENER CODE, ANFANG
7: ///////////////////////
8:
9: CMenu menu;
10:
11: // Kontextmenü laden
12: menu.LoadMenu(IDR_CONTEXTMENU);
13: // Erstes Untermenü (das eigentliche Menü) holen
14: CMenu *pContextMenu = menu.GetSubMenu(0);
15:
16: // Kontextmenü anzeigen
17: pContextMenu->TrackPopupMenu(TPM_LEFTALIGN |
18: TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
19: point.x, point.y, AfxGetMainWnd());
20:
21: ///////////////////////
22: // EIGENER CODE, ENDE
23: ///////////////////////
24: }

Dieser Code sollte Ihnen aus Lektion 6 bekannt vorkommen. Wenn Sie die Anwendung jetzt kompilieren und ausführen, können Sie mit der rechten Maustaste auf das untergeordnete Fenster klicken und eine Zeichenfarbe aus dem daraufhin geöffneten Kontextmenü auswählen, wie es Abbildung 11.5 zeigt.

Abbildung 11.5:
Die Zeichenfarben über das Kontextmenü ändern

Zusammenfassung

Das war nicht schlecht, oder? Nach dem anstrengenden gestrigen Tag haben Sie sich sicherlich eine kleine Verschnaufpause mit der heutigen Lektion verdient. Außerdem konnten Sie viele Dinge aus der gestrigen Lektion vertiefen. Es ist aber auch einiges Neues hinzugekommen. Sie haben gelernt, was MDI-Anwendungen sind und wie sie sich von SDI-Anwendungen unterscheiden. Es wurde gezeigt, wie man eine Reihe von Menübefehlen mit einer einzigen Behandlungsroutine bearbeitet. Weiterhin haben Sie gelernt, wie man ein Menü erstellt, das speziell als Kontextmenü vorgesehen ist, und wie man es in eine MDI-Anwendung integriert.

Fragen und Antworten

Frage:
Da es sich bei einer MDI-Anwendung grundsätzlich um den gleichen Code handelt wie bei einer SDI-Anwendung, warum soll ich dann überhaupt eine SDI-Anwendung erstellen? Warum soll ich nicht einfach nur noch MDI-Anwendungen schreiben?

Antwort:
Das hängt von der konkreten Anwendung und deren vorgesehenem Einsatz ab. Wahrscheinlich werden beide Anwendungstypen in Ihrer Programmiertätigkeit zur Routine gehören. Wenn Sie ein Memo schreiben oder an einem Tabellenblatt arbeiten, werden Sie eine MDI-Anwendung bevorzugen. Wollen Sie durch das World Wide Web browsen, wird Ihr Webbrowser wahrscheinlich eine SDI-Anwendung sein. Ein einfacher Texteditor wie der Windows-Editor wäre als MDI-Anwendung für den Benutzer sicherlich unnötig kompliziert. Für die vorgesehenen Aufgaben ist eine SDI-Anwendung besser geeignet. Bei bestimmten Anwendungen ist es von vornherein sinnvoller, sie als SDI- und nicht als MDI-Anwendung zu konzipieren. Stellen Sie sich einfach den möglichen Einsatzbereich der geplanten Anwendung vor, und entscheiden Sie sich dann für das besser geeignete Modell.

Frage:
Einige Befehle in meinem Farbmenü führen zur Auswahl der falschen Farbe. Wie kann ich das Problem ermitteln?

Antwort:
Die Ursache des Problems liegt wahrscheinlich darin, daß die Menü-IDs des Farbmenüs nicht in der richtigen Reihenfolge aufeinanderfolgen. Das können Sie nachprüfen, indem Sie mit der rechten Maustaste im Arbeitsbereich auf der Registerkarte Ressourcen auf Tag11 Ressourcen klicken. Wählen Sie aus dem Kontextmenü den Befehl Ressourcensymbole, um eine Liste der IDs mit den zugeordneten Nummern in alphabetischer Ordnung anzuzeigen. Beginnen Sie mit der ID für Schwarz, und stellen Sie sicher, daß die Nummern mit einem Abstand von 1 aufeinanderfolgen, ohne Nummern zu überspringen. Überprüfen Sie, ob diese IDs in der Reihenfolge stehen, wie sie im Farbmenü (und in der Farbtabelle in der Datei Tag11Doc.cpp) eingetragen sind und nicht in alphabetischer Reihenfolge, wie sie in der Liste erscheinen. Wenn Sie auf Fehler stoßen sollen, müssen Sie Visual C++ schließen und die Datei Resource.h in einem Texteditor öffnen, um die IDs in der richtigen Weise neu zu numerieren. Nachdem Sie diese Korrekturen vorgenommen haben (achten Sie darauf, Duplikate zu löschen), speichern Sie sie, starten Visual C++ erneut und kompilieren die Anwendung. Das Farbmenü sollte nun ordnungsgemäß funktionieren.

Workshop

Kontrollfragen

1. Welche fünf Basisklassen kommen in MDI-Anwendungen zum Einsatz?

2. Warum müssen Sie den Eintrag ON_COMMAND_RANGE außerhalb des Abschnitts der vom Klassen-Assistenten verwalteten Nachrichtenzuordnungstabelle unterbringen?

3. Welches Argument übergibt ON_COMMAND_RANGE an die Behandlungsfunktion?

4. Welche Nachricht sollten Sie verwenden, um ein Kontextmenü anzuzeigen?

Übung

Fügen Sie die Pulldown- und Kontextmenüs für die Breite hinzu. Verwenden Sie die gleichen Stiftbreiten wie in der gestrigen Lektion.



vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbackKapitelanfangnächstes Kapitel


Ein Imprint des Markt&Technik Buch- und Software-Verlag GmbH.
Elektronische Fassung des Titels: Visual C++ 6 in 21 Tagen, ISBN: 3-8272-2035-1