Die bisher erstellten SDI- und MDI-Anwendungen verfügen nicht nur über Standardmenüs, sondern weisen auch einfache Symbolleisten auf, die mit den Menüs korrespondieren. Die Symbolleisten sind mit Standardfunktionen (Neu, Öffnen, Speichern, Drucken, Ausschneiden, Kopieren und Einfügen) ausgestattet, die sich in den Symbolleisten der meisten Windows-Anwendungen finden. Die Mehrzahl der Anwendungen beschränkt sich jedoch nicht auf diese vorgegebene Auswahl von Funktionen, sondern paßt die Symbolleisten an, um die konkrete Funktionalität der Anwendung widerzuspiegeln.
Neben den Symbolleisten verfügen die SDI- und MDI-Anwendungen über eine Statusleiste am unteren Rand des Anwendungsfensters, um eine textuelle Beschreibung der Symbolleistenschaltflächen und Menübefehle bereitzustellen. Die Statusleiste verfügt ebenfalls über Standardbereiche, die den Zustand der Feststelltasten für Großbuchstaben, Zahlen und Bildlauf anzeigen.
Heute lernen Sie insbesondere, wie man ...
Eine der treibenden Kräfte hinter der Entwicklung von grafischen Benutzeroberflächen wie Windows ist das Ziel, die Benutzerfreundlichkeit von Computern zu verbessern. In diesem Zusammenhang haben die Entwickler der Oberflächen festgelegt, daß alle Anwendungen mit einem Standardsatz von Menüs auszustatten sind und daß die Menüs in einer standardisierten Art und Weise organisiert sein sollen. Der Gestaltung des Betriebssystems Microsoft Windows liegt die gleiche Philosophie zugrunde, d.h., in den meisten Anwendungen kommt ein standardisierter Satz von Menüs zum Einsatz, die in einer standardisierten Reihenfolge angeordnet sind.
Mit der zunehmenden Verbreitung von Windows ereignete sich etwas Wundersames. Die Anwendungsentwickler stellten fest, daß neue Benutzer trotzdem noch Schwierigkeiten hatten, sich in neue Anwendungen einzuarbeiten, und daß fortgeschrittene Benutzer die Menüs zu umständlich fanden. Daraufhin erfanden die Anwendungsgestalter die Symbolleisten als Lösung für beide Probleme.
Eine Symbolleiste ist ein schmales Band, das an einem Fensterrahmen angebunden oder als unverankertes Dialogfeld im Anwendungsrahmen verschiebbar ist. Dieses Band (oder Dialogfeld) verfügt über eine Anzahl kleiner Schaltflächen, die mit Bildern »beschriftet« sind, die man als Alternative zu Menübefehlen verwenden kann. Die Anwendungsentwickler plazieren die am häufigsten benutzten Funktionen ihrer Anwendungen auf diesen Symbolleisten und versuchen, die Bilder auf den Schaltflächen möglichst so zu gestalten, daß der Benutzer die Funktionen ohne weiteres erkennen kann.
Nachdem sich die fortgeschrittenen Benutzer an die Symbolleistenschaltflächen gewöhnt hatten, traten die Symbolleisten ihren Siegeszug an. Allerdings hatten neue Benutzer immer noch Probleme, sich mit dem Zweck der Symbolleistenschaltflächen bekanntzumachen. Daraufhin setzten sich die Entwickler wieder ans Reißbrett, um neue Wege auszuknobeln, wie man neuen Benutzern den Umgang mit Symbolleistenschaltflächen erleichtern kann.
Heraus kam eine Lösung, bei der in einer Informationsleiste, die bereits viele Anwendungen am unteren Rand des Anwendungsfensters vorgesehen hatten, detaillierte Beschreibungen sowohl zu den Menüeinträgen als auch den Symbolleistenschaltflächen angezeigt wurden. Eine weitere Lösung war die Anzeige eines kleinen Hilfe-Popup- Fensters mit einer kurzen Beschreibung der Schaltfläche. Dieses Fenster erscheint, wenn man die Maus ein paar Sekunden über der jeweiligen Schaltfläche ruhen läßt. Die erste Lösung wurde als Statusleiste bekannt, die zweite als QuickInfo. Beide Verfahren sind in den meisten heutigen Windows-Anwendungen gängige Praxis.
Wenn Sie eigene Symbolleisten und Statusleisten in Ihren Anwendungen entwerfen und verwenden möchten, sollten Sie daran denken, daß Visual C++ eine Menge Unterstützung für Ihre Anstrengungen bereitstellt und sogar die Implementierung erleichtert. Immerhin haben selbst die Anwendungsentwickler von Microsoft den Vorreiter bei der Entwicklung dieser Elemente gespielt, und viele, wenn auch nicht alle, Windows-Anwendungen von Microsoft werden mit dem Visual C++ aus dem eigenen Hause entwickelt. Diese Tatsache ist sogar in den Tips und Tricks - die beim Start des Visual Studio erscheinen oder sich über das Hilfe-Menü aufrufen lassen - dokumentiert: »Wir haben es vor Ihnen verwendet! Visual C++ wurde mit Hilfe von Visual C++ entwickelt.« Und auch Sie sitzen heute in der ersten Reihe und erfahren, wie Sie eigene Symbolleisten und Statusleisten für Ihre Anwendungen erstellen.
Zur Einführung in das Thema Symbolleistenentwurf modifizieren wir die am Tag 10 erstellte SDI-Zeichenanwendung. Hier fügen wir eine Symbolleiste ein, mit der sich die Zeichenfarben auswählen lassen.
Wenn Sie lediglich ein paar zusätzliche Symbolleistenschaltflächen in die vom Anwendungs-Assistenten für eine SDI- oder MDI-Anwendung erzeugte Standardsymbolleiste aufnehmen möchten, können Sie die Symbolleiste im Symbolleisten-Editor (erreichbar über die Registerkarte Ressourcen des Arbeitsbereichs) von Visual C++ bearbeiten. Genau wie im Menü-Editor befindet sich am Ende der Symbolleiste ein leeres Feld, das Sie mit einer weiteren Symbolleistenschaltfläche ausgestalten können, wie es Abbildung 12.1 zeigt. Dazu brauchen Sie lediglich die leere Schaltfläche zu markieren und nach rechts ziehen, wenn ein Zwischenraum (ein Separator) zwischen ihr und der daneben liegenden Schaltfläche entstehen soll, oder die Schaltfläche an eine andere Position ziehen, wenn Sie die Schaltfläche verschieben möchten. Nachdem Sie die Schaltfläche auf der gewünschten Zielposition plaziert haben, zeichnen Sie ein Symbol auf die Schaltfläche, das deren Funktion charakterisiert, wenn man die Schaltfläche anklickt. Schließlich doppelklicken Sie auf die Schaltfläche in der Symbolleistenansicht, um das Eigenschaftsdialogfeld der Schaltfläche zu öffnen. Hier geben Sie der Schaltfläche die gleiche ID wie dem Menübefehl, der die betreffende Funktion auslöst. Sobald Sie Ihre Anwendung kompilieren und ausführen, haben Sie eine neue Symbolleistenschaltfläche, die den jeweiligen Menübefehl realisiert. Wenn Sie eine Symbolleistenschaltfläche entfernen möchten, ziehen Sie sie in der Symbolleistenansicht aus der Symbolleiste heraus.
Abbildung 12.1:
Der Symbolleisten-Editor
Um eine neue Symbolleiste einzufügen, klicken Sie mit der rechten Maustaste auf den
Ordner Toolbar
und wählen Toolbar einfügen aus dem Kontextmenü. Daraufhin wird
eine leere Symbolleiste mit einer einzigen leeren Schaltfläche erzeugt. Sobald Sie ein
Symbol auf die jeweils leeren Schaltflächen in der Symbolleiste zeichnen, kommt eine
weitere leere Schaltfläche am Ende der Symbolleiste hinzu.
Für unsere Zeichenanwendung füllen Sie acht Schaltflächen mit den acht verfügbaren Farben des Zeichenprogramms.
Nachdem Sie die Schaltflächen in der Symbolleiste mit Symbolen ausgestattet haben, doppelklicken Sie in der Symbolleistenansicht auf die erste Schaltfläche. Daraufhin erscheint das Dialogfeld Schaltfläche für Symbolleiste Eigenschaften.
Im Feld ID geben Sie die ID des Menübefehls ein, den die Schaltfläche realisieren soll
(die ID können Sie auch aus der Dropdown-Liste auswählen). In das Feld Statuszeilentext
tragen Sie die Beschreibung ein, die in der Statusleiste für diese Schaltfläche erscheinen
soll. (Wenn Sie bereits eine Aufforderung für den Menübefehl eingegeben
haben, ist in diesem Feld schon die Menübeschreibung enthalten.) Am Ende der Beschreibung
für die Statusleiste fügen Sie die Zeichen \n
und einen kurzen Text für die
QuickInfo der Symbolleistenschaltfläche an.
Beispielsweise können Sie ID_COLOR_BLACK
als ID und Zeichenfarbe
Schwarz\nSchwarz
als Statuszeilentext für die schwarze Schaltfläche auf der Symbolleiste,
die Sie für Ihr Zeichenprogramm erstellen, festlegen, wie es Abbildung 12.2
verdeutlicht.
Abbildung 12.2:
Das Dialogfeld Schaltfläche für Symbolleiste Eigenschaften
Nachdem Sie den Entwurf der Symbolleiste fertiggestellt - die Schaltflächen mit Symbolen ausgestattet und die Eigenschaften für jede Schaltfläche festgelegt - haben, ändern Sie die ID der Symbolleiste. Im Arbeitsbereich klicken Sie mit der rechten Maustaste auf die neu hinzugefügte Symbolleiste und öffnen deren Eigenschaftsdialogfeld. Ändern Sie die ID der Symbolleiste in einen aussagekräftigen Namen.
Beispielsweise können Sie für die Symbolleiste Farben, die Sie für das Zeichenprogramm
erstellen, die ID der Symbolleiste in IDR_TBCOLOR
ändern.
In den bisherigen SDI- und MDI-Anwendungen haben Sie keinerlei Funktionalität hinzufügt,
die eine Arbeit mit dem Rahmenfenster erfordert hätte. Jetzt, da die Symbolleiste
mit dem Rahmen verbunden wird, müssen Sie den Code in diesem Modul hinzufügen
und modifizieren. Wenn Sie die Klasse CMainFrame
öffnen und zur Funktion
OnCreate
gehen, sehen Sie, wo die vorhandene Symbolleiste erzeugt und (weiter unten
in der Funktion) mit dem Rahmen verbunden wird.
Bevor Sie die Symbolleiste mit dem Anwendungsgerüst verbinden können, müssen
Sie zunächst eine Variable in die Klasse CMainFrame
hinzufügen, um den Wert der
neuen Symbolleiste aufzunehmen. Für diese Variable vom Typ CToolBar
legen Sie
den Zugriffsstatus Protected
fest.
Um die Symbolleiste Farben in Ihre Zeichenanwendung aufzunehmen, klicken Sie mit
der rechten Maustaste auf der Registerkarte Klassen des Arbeitsbereichs auf die Klasse
CMainFrame
. Wählen Sie Member-Variable hinzufügen aus dem Kontextmenü, und legen
Sie den Variablentyp mit CToolBar
, den Namen als m_wndColorBar
und den Zugriff
als Protected fest.
Jetzt schreiben Sie noch etwas Code in die Funktion OnCreate
der Klasse CMainFrame
,
um die Symbolleiste hinzuzufügen und sie mit dem Gerüst zu verbinden. Übernehmen
Sie die Modifikationen aus Listing 12.1, um die Symbolleiste Farben in Ihre Zeichenanwendung
einzubauen.
Listing 12.1: Die modifizierte Funktion OnCreate der Klasse CMainFrame
1: int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
2: {
3: if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
4: return -1;
5:
6: if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE |
ÂCBRS_TOP
7: | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
8: !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
9: {
10: TRACE0("Symbolleiste konnte nicht erstellt werden\n");
11: return -1; // Fehler bei Erstellung
12: }
13:
14: ///////////////////////
15: // EIGENER CODE, ANFANG
16: ///////////////////////
17:
18: // Symbolleiste Farben hinzufügen
19: int iTBCtlID;
20: int i;
21:
22: // Symbolleiste Farben erzeugen
23: if (!m_wndColorBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD |
24: WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS |
25: CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
26: !m_wndColorBar.LoadToolBar(IDR_TBCOLOR))
27: {
28: TRACE0("Symbolleiste konnte nicht erstellt werden\n");
29: return -1; // Fehler bei Erstellung
30: }
31: // Schaltfläche Schwarz auf der Symbolleiste suchen
32: iTBCtlID = m_wndColorBar.CommandToIndex(ID_COLOR_BLACK);
33: if (iTBCtlID >= 0)
34: {
35: // Schleife durch die Schaltflächen, um sie als Optionsfelder wirken
Âzu lassen
36: for (i= iTBCtlID; i < (iTBCtlID + 8); i++)
37: m_wndColorBar.SetButtonStyle(i, TBBS_CHECKGROUP);
38: }
39:
40: ///////////////////////
41: // EIGENER CODE, ENDE
42: ///////////////////////
43:
44: if (!m_wndStatusBar.Create(this) ||
45: !m_wndStatusBar.SetIndicators(indicators,
46: sizeof(indicators)/sizeof(UINT)))
47: {
48: TRACE0("Statusleiste konnte nicht erstellt werden\n");
49: return -1; // Fehler bei Erstellung
50: }
51:
52: // ZU ERLEDIGEN: Löschen Sie diese drei Zeilen, wenn Sie nicht wollen,
Âdass die Symbolleiste
53: // andockbar ist.
54: m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
55:
56: ///////////////////////
57: // EIGENER CODE, ANFANG
58: ///////////////////////
59:
60: // Andocken für Symbolleiste Farben aktivieren
61: m_wndColorBar.EnableDocking(CBRS_ALIGN_ANY);
62:
63: ///////////////////////
64: // EIGENER CODE, ENDE
65: ///////////////////////
66:
67: EnableDocking(CBRS_ALIGN_ANY);
68: DockControlBar(&m_wndToolBar);
69:
70: ///////////////////////
71: // EIGENER CODE, ANFANG
72: ///////////////////////
73:
74: // Symbolleiste Farben andocken
75: DockControlBar(&m_wndColorBar);
76:
77: ///////////////////////
78: // EIGENER CODE, ENDE
79: ///////////////////////
80:
81: return 0;
82: }
Der erste hinzugefügte Codeabschnitt
23: if (!m_wndColorBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD |
24: WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS |
25: CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
26: !m_wndColorBar.LoadToolBar(IDR_TBCOLOR))
enthält zwei separate Funktionen, die für das Erstellen einer Symbolleiste erforderlich
sind. Die erste Funktion, CreateEx
, erstellt die Symbolleiste selbst, während die zweite
Funktion, LoadToolBar
, die Symbolleiste lädt, die Sie im Symbolleisten-Editor entworfen
haben. Die zweite Funktion, LoadToolBar
, erfordert ein Argument: die ID für die
zu erzeugende Symbolleiste.
Der Funktion CreateEx
können Sie mehrere Argumente übergeben. Das erste - und
einzige erforderliche - Argument ist ein Zeiger auf das übergeordnete Fenster. In diesem
Fall (der den Normalfall darstellt) ist dieses Argument ein Zeiger auf das Rahmenfenster,
mit dem die Symbolleiste verbunden wird.
Das zweite Argument gibt den Stil der Steuerelemente in der zu erzeugenden Symbolleiste an. Es stehen mehrere Stile zur Auswahl, von denen einige mit den beiden letzten Versionen des Internet Explorer eingeführt wurden. Tabelle 12.1 listet die verfügbaren Stile auf.
Das dritte Argument gibt den Stil der Symbolleiste selbst an. Dieses Argument ist normalerweise eine Kombination von Fenster- und Steuerelementstilen. In der Regel verwendet man nur zwei oder drei Fensterstile, während es sich beim Rest der Symbolleistenstile um Steuerelementstile handelt. In Tabelle 12.2 finden Sie die üblicherweise verwendeten Symbolleistenstile.
Das vierte Argument, welches Sie in Ihrem Code nicht bereitstellen, gibt die Größe
der Symbolleistenrahmen an. Dieses Argument wird als normale CRect
-Klasse übergeben,
um die gewünschte Länge und Höhe für die Symbolleiste bereitzustellen. Der
Standardwert ist 0
für alle Abmessungen des Rechtecks, so daß die Symbolleiste keine
Rahmen aufweist.
Das fünfte und letzte Argument, das Sie ebenfalls nicht in Ihrem Code verwenden,
stellt die ID des untergeordneten Symbolleistenfensters bereit. Der Standardwert lautet
AFX_IDW_TOOLBAR
, man kann aber alle definierten IDs verwenden, die für die Symbolleiste
erforderlich sind oder geeignet erscheinen.
An das Erstellen der Symbolleiste schließt sich ein etwas eigentümlicher Codeabschnitt an:
31: // Schaltfläche Schwarz auf der Symbolleiste suchen
32: iTBCtlID = m_wndColorBar.CommandToIndex(ID_COLOR_BLACK);
33: if (iTBCtlID >= 0)
34: {
35: // Schleife durch die Schaltflächen, um sie als Optionsfelder wirken
Âzu lassen
36: for (i= iTBCtlID; i < (iTBCtlID + 8); i++)
37: m_wndColorBar.SetButtonStyle(i, TBBS_CHECKGROUP);
38: }
Die erste Zeile in diesem Codefragment verwendet die Symbolleistenfunktion CommandToIndex
, um die Steuerelementnummer der Schaltfläche ID_COLOR_BLACK
zu ermitteln.
Wenn Sie die Symbolleiste in der Reihenfolge der Farben, wie sie im Menü erscheinen,
erstellt haben, sollte es sich dabei um das erste Steuerelement mit einem
Index von 0
handeln. Es empfiehlt sich, den Index aller Symbolleistenschaltflächen, die
man ändern muß, mit der Funktion CommandToIndex
zu ermitteln, einfach deshalb,
weil man nicht immer davon ausgehen kann, daß die Schaltfläche an der erwarteten
Position sitzt. Die Funktion liefert den Index des angegebenen Symbolleistensteuerelements
zurück. Diesen Wert verwendet man als Ausgangspunkt, um den Schaltflächenstil
der Farbschaltflächen festzulegen.
In der Schleife, in der Sie alle acht Farbschaltflächen der Symbolleiste durchlaufen,
steuern Sie mit der Funktion SetButtonStyle
das Verhalten der Symbolleistenschaltflächen.
Das erste Argument an diese Funktion ist der Index der Schaltfläche, die zu
ändern ist. Das zweite Argument gibt den Stil für die betreffende Schaltfläche an. In
diesem Fall legen wir fest, daß alle Schaltflächen den Stil TBBS_CHECKGROUP
aufweisen.
Damit verhalten sich die Schaltflächen wie Optionsfelder, wobei nur eine Schaltfläche
in der Gruppe zu einem bestimmten Zeitpunkt ausgewählt sein kann. Die Liste der
verfügbaren Schaltflächenstile gibt Tabelle 12.3 wieder.
Der letzte Codeabschnitt, den Sie in die Funktion OnCreate
der Klasse CMainFrame
aufgenommen haben, sieht folgendermaßen aus:
60: // Andocken für Symbolleiste Farben aktivieren
61: m_wndColorBar.EnableDocking(CBRS_ALIGN_ANY);
...
67: EnableDocking(CBRS_ALIGN_ANY); // (Vom Anwendungs-Assistenten generierte
ÂZeile)
...
73:
74: // Symbolleiste Farben andocken
75: DockControlBar(&m_wndColorBar);
In der ersten Zeile steht der Aufruf der Funktion EnableDocking
. Diese Funktion erlaubt
das Verankern der Symbolleiste mit dem Rahmenfenster. Der an diese Symbolleistenfunktion
übergebene Wert muß mit dem Wert übereinstimmen, der im nachfolgenden
Aufruf der Funktion EnableDocking
für das Rahmenfenster übergeben wird.
Die verfügbaren Werte für diese Funktionen sind in Tabelle 12.4 aufgeführt. Mit diesen
Funktionen lassen sich die Rahmen der Symbolleiste und das Rahmenfenster für
das Andocken aktivieren. Ruft man diese Funktionen nicht auf, kann man die Symbolleiste
nicht mit dem Rahmenfenster verankern. Übergibt man eine bestimmte Seite für
das Andocken in diesen Funktionen, und die Seite entspricht nicht diesem Wert, läßt
sich die Symbolleiste ebenfalls nicht am Rahmenfenster verankern.
Als letzte Funktion wurde die Fensterfunktion DockControlBar
hinzugefügt, der die
Adresse der Symbolleistenvariablen übergeben wird. Diese Funktion verankert die
Symbolleiste physisch mit dem Rahmenfenster. Da der gesamte Code in der Funktion
OnCreate
für das Rahmenfenster erscheint, wird die Symbolleiste verankert, bevor der
Benutzer das Fenster oder die Symbolleiste zu Gesicht bekommt.
Nachdem Sie nun den gesamten Code in die Funktion OnCreate
der Klasse CMainFrame
aufgenommen haben, können Sie Ihre Anwendung kompilieren und ausführen. Sie
finden eine funktionsfähige Symbolleiste Farben vor, über die sich die Zeichenfarbe
auswählen läßt (siehe Abbildung 12.3).
Abbildung 12.3:
Die Symbolleiste Farben im Zeichenprogramm
Nunmehr verfügen Sie über eine Symbolleiste Farben, die Sie mit dem Rahmen Ihres Zeichenprogramms verankern können. Es wäre schön, wenn man die Symbolleiste genauso über das Menü Ansicht anzeigen und ausblenden könnte, wie es mit der Standardsymbolleiste und der Statusleiste möglich ist. Diese Funktionalität läßt sich recht einfach implementieren, aber es funktioniert nicht unbedingt so, wie Sie es vielleicht erwarten.
Als erstes ist ein Menübefehl hinzuzufügen, um die Sichtbarkeit der Farbpalette umzuschalten. Diese Aufgabe erledigen Sie über den Menü-Editor, mit dem Sie einen neuen Menübefehl in das Menü Ansicht aufnehmen. Legen Sie die Eigenschaften des Menüs gemäß Tabelle 12.5 fest.
Um zu ermitteln, ob die Symbolleiste sichtbar oder ausgeblendet ist, kann man den aktuellen
Stil der Symbolleiste lesen und das Stilflag WS_VISIBLE
ausmaskieren. Wenn
das Flag im aktuellen Symbolleistenstil enthalten ist, ist die Symbolleiste sichtbar. Indem
man diese Auswertung in die Funktion SetCheck
in der Behandlungsroutine
UPDATE_COMMAND_UI
schreibt, läßt sich das Kontrollhäkchen neben dem Menüeintrag
für die Farbpalette umschalten.
Diese Funktionalität läßt sich im Zeichenprogramm mit einer Behandlungsroutine für
das Ereignis UPDATE_COMMAND_UI
des Menüs ID_VIEW_COLORBAR
realisieren. Achten
Sie darauf, diese Behandlungsroutine in die Klasse CMainFrame
aufzunehmen. In die
Funktion schreiben Sie den Code von Listing 12.2.
Listing 12.2: Die Funktion OnUpdateViewColorbar der Klasse CMainFrame
1: void CMainFrame::OnUpdateViewColorbar(CCmdUI* pCmdUI)
2: {
3: // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der
ÂBenutzeroberfläche hier einfügen
4: ///////////////////////
5: // EIGENER CODE, ANFANG
6: ///////////////////////
7:
8: // Zustand der Farbpalette prüfen
9: pCmdUI->SetCheck(((m_wndColorBar.GetStyle() & WS_VISIBLE) != 0));
10:
11: ///////////////////////
12: // EIGENER CODE, ENDE
13: ///////////////////////
14: }
Da die Klasse CToolBar
von der Klasse CWnd
(über die Klasse CControlBar
) abgeleitet
ist, könnte man meinen, daß man die Funktion ShowWindow
auf der Symbolleiste selbst
aufrufen kann, um die Symbolleiste anzuzeigen und auszublenden. Das ist zwar möglich,
aber der Hintergrund für die Symbolleiste wird nicht zusammen mit der Symbolleiste
ausgeblendet. Der Benutzer stellt lediglich fest, daß die Symbolleistenschaltflächen
erscheinen und verschwinden. (Natürlich ist das die Wirkung, die Sie erzielen
möchten, aber Ihre Benutzer werden davon nicht sehr angetan sein.)
Statt dessen greifen Sie auf eine Funktion ShowControlBar
für das Rahmenfenster zurück,
um die Symbolleiste anzuzeigen und auszublenden. Diese Funktion übernimmt
drei Argumente. Das erste Argument ist die Adresse für die Symbolleistenvariable.
Das zweite Argument ist ein Boolescher Wert, der angibt, ob die Symbolleiste anzuzeigen
ist. (TRUE
zeigt die Symbolleiste an, FALSE
blendet sie aus.) Schließlich spezifiziert
das dritte Argument, ob die Symbolleiste verzögert erscheinen soll. (TRUE
zeigt die
Symbolleiste verzögert, FALSE
sofort an.)
Nachdem eine Symbolleiste ein- oder ausgeschaltet ist, müssen Sie eine weitere Funktion
für das Rahmenfenster, RecalcLayout
, aufrufen. Diese Funktion bewirkt, daß der
Rahmen alle Symbolleisten, Statusleisten und alles innerhalb des Rahmenbereichs neu
positioniert. Diese Funktion ist dafür verantwortlich, daß sich die Symbolleiste Farben
nach oben oder unten verschiebt, wenn Sie die Standardsymbolleiste ein- und ausschalten.
Diese Funktionalität nehmen Sie in Ihr Zeichenprogramm mit Hilfe einer Behandlungsfunktion
für das Ereignis COMMAND
des Menübefehls ID_VIEW_COLORBAR
auf. Achten
Sie darauf, daß Sie diese Behandlungsfunktion in die Klasse CMainFrame
aufnehmen.
In die Funktion schreiben Sie den Code aus Listing 12.3.
Listing 12.3: Die Funktion OnViewColorbar der Klasse CMainFrame
1: void CMainFrame::OnViewColorbar()
2: {
3: // TODO: Code für Befehlsbehandlungsroutine hier einfügen
4:
5: ///////////////////////
6: // EIGENER CODE, ANFANG
7: ///////////////////////
8: BOOL bVisible;
9:
10: // Zustand der Farbpalette prüfem
11: bVisible = ((m_wndColorBar.GetStyle() & WS_VISIBLE) != 0);
12:
13: // Symbolleiste Farben umschalten
14: ShowControlBar(&m_wndColorBar, !bVisible, FALSE);
15: // Elemente im Rahmenfenster neu anordnen
16: RecalcLayout();
17:
18: ///////////////////////
19: // EIGENER CODE, ENDE
20: ///////////////////////
21: }
Wenn Sie Ihre Anwendung jetzt kompilieren und ausführen, sollten Sie die Symbolleiste Farben über das Menü Ansicht ein- und ausschalten können.
Mittlerweile ist es üblich, daß die Symbolleisten einer Anwendung neben einfachen Schaltflächen auch noch andere Elemente enthalten. Sehen Sie sich zum Beispiel das Visual Studio an. Hier finden Sie Kombinationsfelder, die Ihnen die Navigation durch den Code erlauben, indem Sie die Klasse, die ID und die zu bearbeitende Funktion einfach über die Symbolleiste auswählen. Wie fügt man nun ein Kombinationsfeld in eine Symbolleiste ein? Der Symbolleisten-Editor stellt es nicht zur Verfügung. Hier finden Sie nur Schaltflächen, auf die Sie Symbole zeichnen können. Mit den Assistenten von Visual C++ lassen sich keine Kombinationsfelder in Symbolleisten aufnehmen. Zu diesem Zweck müssen Sie ein wenig C++-Code schreiben.
Als Einstieg fügen Sie ein Kombinationsfeld in die Symbolleiste Farben ein, die Sie gerade erstellt haben. Mit dem Kombinationsfeld wählt der Benutzer die Breite des Zeichenstifts aus. (Wenn Sie die Unterstützung für unterschiedliche Zeichenbreiten gemäß Übung am Ende von Tag 10 noch nicht realisiert haben, sollten Sie das jetzt nachholen.)
Um ein Kombinationsfeld in die Symbolleiste aufzunehmen, ist zuerst das zu tun, was Ihnen Visual C++ verweigert. Sie müssen die Ressourcendatei selbst bearbeiten. Über das Visual Studio für Visual C++ ist das nicht möglich. Wenn Sie versuchen, die Ressourcendatei im Visual Studio zu öffnen, gelangen Sie unweigerlich auf die Registerkarte Ressourcen des Arbeitsbereichs, wo die verschiedenen Ressourcen-Editoren untergebracht sind. Nein, Sie müssen diese Datei in einem anderen Editor, wie etwa dem normalen Windows-Editor, bearbeiten.
Schließen Sie Visual C++. Nur so läßt sich garantieren, daß Sie nicht über Ihre Änderungen
schreiben. Öffnen Sie den Editor, und gehen Sie in Ihr Projektverzeichnis. Öffnen
Sie die Ressourcendatei, die nach dem Projekt benannt ist und eine .rc
-Erweiterung
aufweist. Blättern Sie in der Datei nach unten bis zu den Symbolleistendefinitionen.
(Sie können nach dem Wort »Toolbar« suchen.) Dann gehen Sie ans Ende der
Symbolleistendefinition und fügen zwei Separatorlinien am unteren Rand der Symbolleistendefinition
ein.
In Ihrer Zeichenanwendung müssen Sie zum Beispiel in das Projektverzeichnis Toolbar
gehen und die Datei Toolbar.rc
öffnen. (Falls Sie diese Symbolleisten in die MDI-
Zeichenanwendung einfügen, wäre das die Datei Tag11.rc
.) Suchen Sie nach dem
Symbolleistenabschnitt, und fügen Sie dann zwei SEPARATOR
-Zeilen unmittelbar vor
dem Ende des Abschnitts IDR_TBCOLOR
ein, wie es Listing 12.4 zeigt. Dann speichern
Sie die Datei, verlassen den Editor, starten Visual C++ erneut und laden wieder das
Projekt.
Listing 12.4: Die modifizierte Ressourcendatei des Projekts (Toolbar.rc)
1: /////////////////////////////////////////////////////////////////////////////
2: //
3: // Toolbar
4: //
5:
6: IDR_MAINFRAME TOOLBAR DISCARDABLE 16, 15
7: BEGIN
8: BUTTON ID_FILE_NEW
9: BUTTON ID_FILE_OPEN
10: BUTTON ID_FILE_SAVE
11: SEPARATOR
12: BUTTON ID_EDIT_CUT
13: BUTTON ID_EDIT_COPY
14: BUTTON ID_EDIT_PASTE
15: SEPARATOR
16: BUTTON ID_FILE_PRINT
17: BUTTON ID_APP_ABOUT
18: END
19:
20: IDR_TBCOLOR TOOLBAR DISCARDABLE 16, 15
21: BEGIN
22: BUTTON ID_COLOR_BLACK
23: BUTTON ID_COLOR_BLUE
24: BUTTON ID_COLOR_GREEN
25: BUTTON ID_COLOR_CYAN
26: BUTTON ID_COLOR_RED
27: BUTTON ID_COLOR_MAGENTA
28: BUTTON ID_COLOR_YELLOW
29: BUTTON ID_COLOR_WHITE
30: SEPARATOR
31: SEPARATOR
32: END
Die beiden SEPARATOR
-Zeilen haben Sie in die Symbolleistendefinition aufgenommen,
damit der zweite Separator als Platzhalter für das Kombinationsfeld dienen kann, das
Sie in die Symbolleiste einbauen wollen. Es gibt zwei Gründe dafür, daß Sie diese Bearbeitung
manuell erledigen müssen und nicht den Symbolleisten-Editor von Visual
C++ bemühen können. Erstens erlaubt der Symbolleisten-Editor nicht, daß man mehrere
Separatoren an das Ende der Symbolleiste anfügt. Zweitens: Wenn Sie nichts anderes
nach dem Separator an das Ende der Symbolleiste anfügen, nimmt der Symbolleisten-Editor
einen Fehler an und entfernt den Separator. Mit anderen Worten: Mit
dem Symbolleisten-Editor von Visual C++ läßt sich kein Platzhalter für das Kombinationsfeld
in die Symbolleiste einbauen.
Als nächstes sind die Textzeichenfolgen hinzuzufügen, die Sie in das Kombinationsfeld laden. Um diese Strings aufzunehmen, öffnen Sie die Zeichenfolgentabelle auf der Registerkarte Ressourcen des Arbeitsbereichs. Hier finden Sie alle Strings, die Sie als Statuszeilentext in verschiedenen Eigenschaftsdialogfeldern eingegeben haben. Diese Tabelle enthält eine Anzahl von IDs, die Werte dieser IDs und die Strings, die mit diesen IDs verbunden sind (siehe Abbildung 12.4). Die Strings, die Sie in das Kombinationsfeld eintragen möchten, müssen Sie in die Zeichenfolgentabelle schreiben. Jede Zeile in der Dropdown-Liste muß über eine eindeutige ID und einen Eintrag in der Zeichenfolgentabelle verfügen.
Abbildung 12.4:
Der Zeichenfolgen-Editor
Um zum Beispiel die Strings für das Kombinationsfeld hinzuzufügen, das Sie in die Symbolleiste Farben einbauen möchten, wählen Sie entweder Einfügen / Neue Zeichenfolge oder klicken mit der rechten Maustaste auf die Zeichenfolgentabelle und wählen Neue Zeichenfolge aus dem Kontextmenü.
Im Eigenschaftsdialogfeld des Strings legen Sie die ID für den String fest und geben dann den String so ein, wie er in der Dropdown-Liste erscheinen soll. Schließen Sie das Eigenschaftsdialogfeld, um den String hinzuzufügen. Für die Strings im Kombinationsfeld Breite, das Sie in die Symbolleiste Farben aufnehmen, tragen Sie die Strings gemäß Tabelle 12.6 ein.
Bevor Sie das Kombinationsfeld in die Symbolleiste Farben aufnehmen können, müssen
Sie eine Variable für das Kombinationsfeld erzeugen. Da sich das Kombinationsfeld
nicht über die Editoren hinzufügen läßt, müssen Sie es als Variable in die Klasse
CMainFrame
aufnehmen.
Die Variable für das Kombinationsfeld nehmen Sie über die Registerkarte Klassen des
Arbeitsbereichs in die Hauptrahmenklasse für die Symbolleiste Farben auf. Klicken Sie
mit der rechten Maustaste auf die Klasse CMainFrame
, und wählen Sie dann Member-
Variable hinzufügen aus dem Kontextmenü. Legen Sie den Variablentyp als CComboBox
, den Namen als m_ctlWidth
und den Zugriff als Protected fest.
Nachdem Sie die Variable für das Kombinationsfeld in die Hauptrahmenklasse aufgenommen haben, sind verschiedene Aufgaben zu erledigen, wenn die Symbolleiste erzeugt wurde:
1. Die Breite und die ID des Platzhalters für das Kombinationsfeld in der Symbolleiste auf die Breite und die ID des Kombinationsfelds setzen.
2. Die Position des Platzhalters in der Symbolleiste ermitteln und danach Größe und Lage des Kombinationsfelds festlegen.
3. Das Kombinationsfeld erzeugen. Dabei die Symbolleiste als übergeordnetes Fenster des Kombinationsfelds spezifizieren.
4. Die Strings in die Dropdown-Liste des Kombinationsfelds laden.
Damit diese Abläufe einigermaßen übersichtlich bleiben, empfiehlt es sich, das Erstellen
der Symbolleiste Farben in einer eigenen Funktion zu realisieren, die sich aus der
Funktion OnCreate
der Hauptrahmenklasse aufrufen läßt. Um diese Funktion zu erzeugen,
klicken Sie im Arbeitsbereich mit der rechten Maustaste auf die Klasse CMainFrame
und wählen Member-Funktion hinzufügen aus dem Kontextmenü. Legen Sie
den Funktionstyp mit BOOL
, die Funktionsdeklaration als CreateColorBar
und den Zugriffsstatus
als Public fest. In die Funktion schreiben Sie den Code von Listing 12.5.
Listing 12.5: Die Funktion CreateColorBar der Klasse CMainFrame
1: BOOL CMainFrame::CreateColorBar()
2: {
3: int iTBCtlID;
4: int i;
5:
6: if (!m_wndColorBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE |
ÂCBRS_TOP
7: | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
8: !m_wndColorBar.LoadToolBar(IDR_TBCOLOR))
9: {
10: TRACE0("Symbolleiste konnte nicht erstellt werden\n");
11: return FALSE; // Fehler bei Erstellung
12: }
13: iTBCtlID = m_wndColorBar.CommandToIndex(ID_COLOR_BLACK);
14: if (iTBCtlID >= 0)
15: {
16: for (i= iTBCtlID; i < (iTBCtlID + 8); i++)
17: m_wndColorBar.SetButtonStyle(i, TBBS_CHECKGROUP);
18: }
19: // Kombinationsfeld hinzufügen
20: int nWidth = 100;
21: int nHeight = 125;
22:
23: // Platzhalter des Kombinationsfelds konfigurieren
24: m_wndColorBar.SetButtonInfo(9, IDC_CBWIDTH, TBBS_SEPARATOR, nWidth);
25:
26: // Höhe der Farbpalette ermitteln
27: CRect rect;
28: m_wndColorBar.GetItemRect(9, &rect);
29: rect.bottom = rect.top + nHeight;
30:
31: // Kombinationsfeld erzeugen
32: m_ctlWidth.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL |
33: CBS_DROPDOWNLIST, rect, &m_wndColorBar, IDC_CBWIDTH);
34:
35: // Kombinationsfeld füllen
36: CString szStyle;
37: if (szStyle.LoadString(IDS_WIDTH_VTHIN))
38: m_ctlWidth.AddString((LPCTSTR)szStyle);
39: if (szStyle.LoadString(IDS_WIDTH_THIN))
40: m_ctlWidth.AddString((LPCTSTR)szStyle);
41: if (szStyle.LoadString(IDS_WIDTH_MEDIUM))
42: m_ctlWidth.AddString((LPCTSTR)szStyle);
43: if (szStyle.LoadString(IDS_WIDTH_THICK))
44: m_ctlWidth.AddString((LPCTSTR)szStyle);
45: if (szStyle.LoadString(IDS_WIDTH_VTHICK))
46: m_ctlWidth.AddString((LPCTSTR)szStyle);
47:
48: return TRUE;
49: }
Zeile 24 von Listing 12.5 gibt an, daß das Kombinationsfeld mit der Objekt-ID
IDC_CBWIDTH
zu erstellen ist. Diese Objekt-ID kennzeichnet das Kombinationsfeld,
wenn es eine Ereignisnachricht an die Anwendung sendet oder wenn man festlegen
muß, welcher Listeneintrag im Bearbeitungsfeld anzuzeigen ist. Allerdings existiert diese
Objekt-ID nicht in Ihrer Anwendung. Bevor Sie die Anwendung kompilieren können,
müssen Sie diese ID zu den Projektressourcen-IDs hinzufügen, wie Sie es am Tag
4 bei der Behandlung von Timern kennengelernt haben. Gehen Sie dazu im Arbeitsbereich
auf die Registerkarte Ressourcen. Markieren Sie den Beginn des Ressourcenbaumes,
und klicken Sie mit der rechten Maustaste, um das Kontextmenü einzublenden.
Wählen Sie Ressourcensymbole aus dem Kontextmenü, und fügen Sie die
Objekt-ID IDC_CBWIDTH
hinzu. Vergewissern Sie sich, daß Sie für die neue Objekt-ID
einen eindeutigen numerischen Wert vergeben, damit keine Konflikte mit anderen
Objekten Ihrer Anwendung auftreten.
Nachdem die Symbolleiste erstellt und die Symbolleisteneigenschaften festgelegt sind,
konfigurieren Sie als nächstes den Separator, der als Platzhalter für das zu erzeugende
Kombinationsfeld dient. Dazu verwenden Sie die Symbolleistenfunktion SetButtonInfo
wie folgt:
m_wndColorBar.SetButtonInfo(9, IDC_CBWIDTH, TBBS_SEPARATOR, nWidth);
Diese Funktion übernimmt vier Argumente. Das erste gibt den aktuellen Index des Steuerelements in der Symbolleiste an - in diesem Fall das zehnte Steuerelement in der Symbolleiste (acht Farbschaltflächen und zwei Separatoren). Im zweiten Argument übergibt man die neue ID des Symbolleistensteuerelements. Dabei handelt es sich um die ID, die in die Nachrichtenwarteschlange gestellt wird, wenn ein Steuerelementereignis auftritt. Das dritte Argument ist der Typ des Symbolleistensteuerelements. Das vierte und letzte Argument ist etwas irreführend. Wenn Sie sich die Funktionsdokumentation ansehen, gibt das vierte Argument den neuen Index des Steuerelements in der Symbolleiste an. Das ist die Position, auf die das Steuerelement verschoben wird. Wenn das Steuerelement jedoch ein Separator ist, gibt dieses Argument die Breite des Steuerelements an und verschiebt es nicht an eine andere Stelle. Da es sich im vorliegenden Fall um einen Separator handelt, legt man mit diesem Argument die Breite des zu erzeugenden Kombinationsfelds fest.
Der Separator als Platzhalter für das Kombinationsfeld in der Symbolleiste ist nun konfiguriert. Als nächstes ermitteln Sie die Position des Platzhalters auf der Symbolleiste, damit sich die Lage des Kombinationsfelds festlegen läßt:
m_wndColorBar.GetItemRect(9, &rect);
rect.bottom = rect.top + nHeight;
In der ersten Zeile steht der Aufruf der Funktion GetItemRect
, um die Position und
Größe des Platzhalters für das Kombinationsfeld zu ermitteln. Die nächste Zeile addiert
die Höhe der Dropdown-Liste zur Höhe, die das Kombinationsfeld schließlich
einnimmt.
Die Größe des Platzhalters ist nun genau festgelegt, und Sie verfügen über Lage und
Größe für das Kombinationsfeld. Nun ist es an der Zeit, das Kombinationsfeld zu erzeugen.
Dazu dient die Funktion Create
des Kombinationsfelds:
m_ctlWidth.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL |
CBS_DROPDOWNLIST, rect, &m_wndColorBar, IDC_CBWIDTH);
Das erste Argument der Funktion Create
für das Kombinationsfeld ist der Stil des
Kombinationsfelds. Normalerweise kombiniert man verschiedene Stilattribute, um einen
Stilwert zu bilden. Tabelle 12.7 listet die Attribute auf, die Sie in diesem Wert verwenden
können.
Das zweite Argument beschreibt das Rechteck, das das Kombinationsfeld einnehmen soll. Dieses Argument gibt die Position innerhalb des übergeordneten Fensters - in diesem Fall der Symbolleiste - an, wo das Kombinationsfeld untergebracht ist. Es verschiebt sich mit dem übergeordneten Fenster (der Symbolleiste) und bleibt immer auf der gleichen Relativposition.
Das dritte Argument ist ein Zeiger auf das übergeordnete Fenster. Es handelt sich hierbei um die Adresse der Variablen für die Symbolleiste Farben.
Im vierten Argument wird die Objekt-ID für das Kombinationsfeld übergeben.
Als letztes beim Erstellen des Kombinationsfelds auf der Symbolleiste Farben ist noch die Dropdown-Liste mit den verfügbaren Elementen, aus denen der Benutzer auswählen kann, zu füllen. Das Ganze wird mit einer Kombination von zwei Funktionen realisiert:
if (szStyle.LoadString(IDS_WIDTH_VTHIN))
m_ctlWidth.AddString((LPCTSTR)szStyle);
Die erste Funktion ist die Funktion LoadString
der Klasse CString
. Diese Funktion
übernimmt eine String-ID und lädt den zugehörigen String aus der Zeichenfolgentabelle.
Die zweite Funktion ist die Funktion AddString
des Kombinationsfelds, die den als
Argument übergebenen String in die Dropdown-Liste hinzufügt. Indem man diese
Kombination von Funktionen für alle Elemente, die in der Dropdown-Liste erscheinen
sollen, aufruft, kann man das Kombinationsfeld aus der Zeichenfolgentabelle der Anwendung
füllen.
Nachdem wir den gesamten Code zum Erstellen der Symbolleiste Farben in eine separate
Funktion verschoben haben, können wir die Funktion OnCreate
auf den neuesten
Stand bringen, so daß sie die Funktion CreateColorBar
aufruft, wo die Symbolleiste
Farben erzeugt wird. Der entsprechende Code ist in Listing 12.6 wiedergegeben.
Listing 12.6: Die modifizierte Funktion OnCreate der Klasse CMainFrame
1: int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
2: {
3: if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
4: return -1;
5:
6: if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE |
ÂCBRS_TOP
7: | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
8: !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
9: {
10: TRACE0("Symbolleiste konnte nicht erstellt werden\n");
11: return -1; // Fehler bei Erstellung
12: }
13:
14: ///////////////////////
15: // EIGENER CODE, ANFANG
16: ///////////////////////
17:
18: // Symbolleiste Farben hinzufügen
19: if (!CreateColorBar())
20: {
21: TRACE0("Symbolleiste Farben konnte nicht erstellt werden\n");
22: return -1; // // Fehler bei Erstellung
23: }
24:
25: ///////////////////////
26: // EIGENER CODE, ENDE
27: ///////////////////////
28:
29: if (!m_wndStatusBar.Create(this) ||
30: !m_wndStatusBar.SetIndicators(indicators,
31: sizeof(indicators)/sizeof(UINT)))
32: {
33: TRACE0("Statusleiste konnte nicht erstellt werden\n");
34: return -1; // Fehler bei Erstellung
35: }
36:
37: // ZU ERLEDIGEN: Löschen Sie diese drei Zeilen, wenn Sie nicht wollen,
Âdass die Symbolleiste
38: // andockbar ist.
39: m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
40:
41: ///////////////////////
42: // EIGENER CODE, ANFANG
43: ///////////////////////
44:
45: // Andocken für Symbolleiste Farben aktivieren
46: m_wndColorBar.EnableDocking(CBRS_ALIGN_ANY);
47:
48: ///////////////////////
49: // EIGENER CODE, ENDE
50: ///////////////////////
51:
52: EnableDocking(CBRS_ALIGN_ANY);
53: DockControlBar(&m_wndToolBar);
54:
55: ///////////////////////
56: // EIGENER CODE, ANFANG
57: ///////////////////////
58:
59: // Symbolleiste Farben andocken
60: DockControlBar(&m_wndColorBar);
61:
62: ///////////////////////
63: // EIGENER CODE, ENDE
64: ///////////////////////
65:
66: return 0;
67: }
Wenn Sie nun die Anwendung kompilieren und ausführen, sollte sich am Ende der Symbolleiste Farben ein Kombinationsfeld befinden, wie es Abbildung 12.5 zeigt. Allerdings bewirkt das Kombinationsfeld noch keine Aktionen.
Abbildung 12.5:
Die Symbolleiste Farben mit dem Kombinationsfeld Breite
Eine Behandlungsroutine für das Kombinationsfeld läßt sich leicht erstellen, auch
wenn man das manuell erledigen muß (da der Klassen-Assistent gar nicht weiß, daß
das Kombinationsfeld existiert). Es ist ein Eintrag ON_CBN_SELCHANGE
in die Nachrichtenzuordnungstabelle
aufzunehmen und dann die eigentliche Behandlungsfunktion in
die Klasse CMainFrame
einzufügen.
Als erstes nehmen wir die Behandlungsfunktion auf. Markieren Sie dazu die Klasse
CMainFrame
im Arbeitsbereich, und wählen Sie Member-Funktion hinzufügen aus dem
Kontextmenü. Geben Sie den Funktionstyp mit afx_msg void
, die Funktionsdeklaration
mit OnSelChangeWidth
und den Zugriff mit Protected an. Den Code für die Funktion
übernehmen Sie aus dem ersten Teil von Listing 12.7. Um die Breite im Dokument
zu setzen, wird in OnSelChangeWidth
die Funktion SetWidth
aufgerufen.
Diese Funktion müssen Sie noch in die Klasse CToolbarDoc
einfügen. Markieren Sie
im Arbeitsbereich auf der Registerkarte Klassen die Klasse CToolbarDoc
, und wählen
Sie Member-Funktion hinzufügen aus dem Kontextmenü. Legen Sie als Funktionstyp
void
, als Deklaration SetWidth(UINT nWidth)
und als Zugriff Public fest. In die Funktion
schreiben Sie den zweiten Teil von Listing 12.7.
Listing 12.7: Die Funktionen OnSelChangeWidth und SetWidth
1: void CMainFrame::OnSelChangeWidth()
2: {
3: // Neue Auswahl des Kombinationsfelds ermitteln
4: int nIndex = m_ctlWidth.GetCurSel();
5: if (nIndex == CB_ERR)
6: return;
7:
8: // Aktives Dokument ermitteln
9: CToolbarDoc* pDoc = (CToolbarDoc*)GetActiveDocument();
10: // Handelt es sich um ein gültiges Dokument?
11: if (pDoc)
12: // Neue Zeichenbreite setzen
13: pDoc->SetWidth(nIndex);
14:
15: }
16:
17: void CToolbarDoc::SetWidth(UINT nWidth)
18: {
19: // Breite setzen
20: m_nWidth = nWidth;
21: }
Die Funktion OnSelChangeWidth
ermittelt zuerst die aktuelle Auswahl des Kombinationsfelds.
Da wir die Einträge in der richtigen Reihenfolge eingetragen und beim Erstellen
des Kombinationsfelds das Flag CBS_SORT
(zum Sortieren der Einträge) nicht
angegeben haben, entspricht der Index den Breiten im Dokument. Daher kann man
einen Zeiger auf die aktuelle Instanz des Dokuments mit der Funktion GetActiveDocument
ermitteln und dann die neue Breite an das Dokument mit der Funktion SetWidth
übergeben.
Um die Behandlungsfunktion aufzurufen, wenn der Benutzer die Auswahl im Kombinationsfeld
ändert, müssen Sie den entsprechenden Eintrag in die Nachrichtenzuordnungstabelle
von CMainFrame
einfügen. Gehen Sie im Quellcode von CMainFrame
nach
oben, bis Sie den Abschnitt der Nachrichtenzuordnungstabelle finden, und fügen Sie
hier Zeile 12 von Listing 12.8 ein.
Listing 12.8: Die modifizierte Nachrichtenzuordnungstabelle von CMainFrame
1: ///////////////////////////////////////////////////////////////////////////
2: // CMainFrame
3:
4: IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
5:
6: BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
7: //{{AFX_MSG_MAP(CMainFrame)
8: ON_WM_CREATE()
9: ON_COMMAND(ID_VIEW_COLORBAR, OnViewColorbar)
10: ON_UPDATE_COMMAND_UI(ID_VIEW_COLORBAR, OnUpdateViewColorbar)
11: //}}AFX_MSG_MAP
12: ON_CBN_SELCHANGE(IDC_CBWIDTH, OnSelChangeWidth)
13: END_MESSAGE_MAP()
ON_CBN_SELCHANGE(IDC_CBWIDTH, OnSelChangeWidth)
in der Nachrichtenzuordnungstabelle legt fest, daß die Funktion OnSelChangeWidth
aufzurufen ist, wenn Ereignisse mit der Objekt-ID des Kombinationsfelds in der Symbolleiste
Farben aufgrund von Änderungen der Auswahl im Kombinationsfeld auftreten.
Wenn Sie nun die Anwendung kompilieren und ausführen, sollten Sie die Stiftbreite
zum Zeichnen über das Kombinationsfeld der Symbolleiste Farben ändern
können.
Für das Kombinationsfeld ist noch ein Problem zu lösen. Falls der Benutzer einen neuen Wert aus dem Menü und nicht über das Kombinationsfeld auswählt, soll das Kombinationsfeld ebenfalls den neuen Wert widerspiegeln. Die aktuelle Auswahl im Kombinationsfeld läßt sich am effizientesten setzen, wenn das beim Auslösen irgendeines Menübefehls geschieht. Dazu ist eine Funktion in der Hauptrahmenklasse erforderlich, die sich von der Dokumentklasse aufrufen läßt. Die Funktion im Hauptrahmen muß lediglich die aktuelle Auswahl im Kombinationsfeld setzen.
Um diese Funktion im Hauptrahmen zu implementieren, fügen Sie eine neue Member-Funktion
in die Klasse CMainFrame
ein und legen den Funktionstyp mit void
, die
Deklaration mit UpdateWidthCB(int nIndex)
und den Zugriff mit Public fest. In die
Funktion schreiben Sie den Code aus Listing 12.9.
Listing 12.9: Die Funktion UpdateWidthCB der Klasse CMainFrame
1: void CMainFrame::UpdateWidthCB(int nIndex)
2: {
3: // Die neue Auswahl im Kombinationsfeld setzen
4: m_wndColorBar.m_ctlWidth.SetCurSel(nIndex);
5: }
Die Funktion UpdateWidthCB
ruft die Kombinationsfeldfunktion SetCurSel
auf, die die
aktuelle Auswahl in der Dropdown-Liste des Kombinationsfelds auf den Eintrag mit
dem angegeben Index setzt. Das Eingabefeld des Kombinationsfelds wird mit dem neu
ausgewählten Listeneintrag aktualisiert. Wenn man dem Kombinationsfeld einen Index
anbietet, der nicht in der Dropdown-Liste existiert, liefert die Funktion einen Fehler
zurück.
Auf der Seite des Dokuments muß man die Funktion im Hauptrahmen immer dann
aufrufen, wenn die entsprechenden Behandlungsfunktionen für das Menü aufgerufen
werden. Da das in verschiedenen Funktionen vorkommen kann, ist es sinnvoll, die erforderliche
Funktionalität in einer einzigen Funktion unterzubringen. Diese Funktion
benötigt einen Zeiger auf die mit dem Dokument verbundene Ansicht und ermittelt
dann - über die Ansicht - einen Zeiger auf den Rahmen. Diesen Zeiger kann man
dann im Aufruf der Funktion UpdateWidthCB
, die wir eben der Hauptrahmenklasse
hinzugefügt haben, verwenden.
Um die Funktion in die Anwendung aufzunehmen, markieren Sie die Klasse CToolbarDoc
im Arbeitsbereich und wählen Member-Funktion hinzufügen aus dem Kontextmenü.
Legen Sie als Funktionstyp void
, als Funktionsdeklaration UpdateColorbar(int
nIndex)
und als Zugriffsstatus Privat fest. In die Funktion übernehmen Sie
den Code aus Listing 12.10.
Listing 12.10: Die Funktion UpdateColorbar der Klasse CToolbarDoc
1: void CToolbarDoc::UpdateColorbar(int nIndex)
2: {
3: // Position der ersten Ansicht ermitteln
4: POSITION pos = GetFirstViewPosition();
5: // Ist die Position gültig?
6: if (pos != NULL)
7: {
8: // Zeiger auf Ansicht in dieser Position holen
9: CView* pView = GetNextView(pos);
10: // Ist Zeiger auf Ansicht gültig?
11: if (pView)
12: {
13: // Zeiger auf Rahmen über Ansicht holen
14: CMainFrame* pFrame = (CMainFrame*)pView->GetTopLevelFrame();
15: // Zeiger auf Rahmen erhalten?
16: if (pFrame)
17: // Kombinationsfeld in Symbolleiste Farben
18: // über den Rahmen aktualisieren
19: pFrame->UpdateWidthCB(nIndex);
20: }
21: }
22: }
Diese Funktion folgt dem Pfad, um den Anwendungsrahmen aus der Dokumentklasse
zu erhalten. Da in einem Dokument mehrere Ansichten gleichzeitig geöffnet sein können,
ermitteln Sie mit der Funktion GetFirstViewPosition
die Position der ersten
Ansicht, die mit dem Dokument verbunden ist.
Die nächste Funktion, GetNextView
, gibt einen Zeiger auf die Ansicht zurück, die
durch die Position spezifiziert wird. Diese Funktion aktualisiert ebenfalls die Positionsvariable
mit dem Zeiger auf die nächste Ansicht in der Liste der Ansichten, die mit
dem aktuellen Dokument verbunden sind.
Nachdem Sie über einen Zeiger auf die Ansicht verfügen, können Sie die Fensterfunktion
GetTopLevelFrame
aufrufen, die einen Zeiger auf das Rahmenfenster der Anwendung
zurückgibt. Diese Funktion müssen Sie über die Ansicht aufrufen, da das Dokument
nicht von der Klasse CWnd
abgeleitet ist, während das bei der Ansicht der Fall ist.
Nunmehr besitzen Sie einen Zeiger auf das Rahmenfenster und können diesen Zeiger verwenden, um die weiter vorn erzeugte Funktion aufzurufen und das Kombinationsfeld in der Symbolleiste zu aktualisieren. Wenn Sie jetzt diese neue Funktion aus der Behandlungsroutine des Menübefehls Breite aufrufen, wie es in Listing 12.11 geschieht, wird das Kombinationsfeld in der Symbolleiste Farben automatisch aktualisiert und spiegelt die momentan ausgewählte Stiftbreite zum Zeichnen wider, unabhängig davon, ob die Auswahl über das Menü oder das Kombinationsfeld erfolgt ist.
Listing 12.11: Eine aktualisierte Behandlungsroutine für den Menübefehl Breite
1: void CToolbarDoc::OnWidthVthin()
2: {
3: // TODO: Code für Befehlsbehandlungsroutine hier einfügen
4: // Neue Breite setzen
5: m_nWidth = 0;
6: // Kombinationsfeld in der Symbolleiste Farben aktualisieren
7: UpdateColorbar(0);
8: }
Weiter oben in der heutigen Lektion haben Sie gelernt, wie man Meldungen in der Statusleiste und QuickInfos für Symbolleistenschaltflächen und Menübefehle spezifiziert. Wie verhält es sich nun, wenn Sie dem Benutzer in der Statusleiste weitergehende Informationen anbieten möchten? Wie läßt sich analog zu Visual Studio für Visual C++ erreichen, daß man Informationen über die momentan ausgeführten Aktionen, die gerade im Dokument bearbeitete Stelle oder den aktuellen Zustand der Anwendung anzeigen kann? Diese Angaben gehen über die Anzeigen der Feststelltasten hinaus, die Visual C++ automatisch in der Statusleiste meldet.
Es ist tatsächlich einfach, zusätzliche Ausschnitte in die Statusleiste aufzunehmen oder auch bereits vorhandene Ausschnitte zu entfernen. Um sich mit diesen Vorgängen bekannt zu machen, nehmen Sie einen neuen Ausschnitt in die Statusleiste Ihrer Zeichenanwendung auf, der die momentan gültige Farbe meldet.
Bevor Sie einen neuen Ausschnitt in die Statusleiste einbinden, müssen Sie einen neuen Eintrag in der Zeichenfolgentabelle der Anwendung für den Statusleisten-Ausschnitt erstellen. Der Eintrag in der Zeichenfolgentabelle realisiert für den Statusleisten-Ausschnitt zwei Aufgaben. Erstens stellt er die Objekt-ID für den Statusleisten- Ausschnitt bereit. Diese ID verwenden Sie, um den Ausschnitt in der Statusleiste zu aktualisieren, wenn ein neuer Text in diesem Feld auszugeben ist. Die zweite Funktion des Eintrags in der Zeichenfolgentabelle bezieht sich auf die Größe des Ausschnitts. Um die korrekte Größe des Ausschnitts festzulegen, müssen Sie einen Titel für den Eintrag in der Zeichenfolgentabelle bereitstellen, der mindestens so lang wie der längste String ist, den Sie im Statusleisten-Ausschnitt anzeigen möchten.
In die Zeichenfolgentabelle fügen Sie einen neuen Eintrag mit den gleichen Schritten
hinzu, die Sie weiter vorn beim Text für das Kombinationsfeld in der Symbolleiste Farben
ausgeführt haben. Legen Sie die String-ID mit ID_INDICATOR_COLOR
und den Titel
mit MAGENTA
(der längste String, der im Ausschnitt der Statusleiste anzuzeigen ist) fest.
Ein kleiner Teil im ersten Abschnitt des Quellcodes für den Hauptrahmen definiert das Layout der Statusleiste. Diese kleine Tabelle enthält die Objekt-IDs der Statusleisten- Ausschnitte als Tabellenelemente, und zwar in der Reihenfolge, in der sie von links nach rechts in der Statusleiste erscheinen.
Um den Ausschnitt für die Farbe in die Statusleiste aufzunehmen, fügen Sie die ID des Farbenausschnittes in die Tabellendefinition für die Statusleistenanzeige unmittelbar im Anschluß an die Nachrichtenzuordnungstabelle in der Quellcodedatei für den Hauptrahmen ein. Schreiben Sie die ID für den Farbenausschnitt in der Tabellendefinition an die Stelle, die der Ausschnitt auf der Statusleiste einnehmen soll, wie es aus Zeile 18 von Listing 12.12 hervorgeht.
Listing 12.12: Eine modifizierte Tabellendefinition für Statusleistenanzeigen
1: ///////////////////////////////////////////////////////////////////////////
2: // CMainFrame
3:
4: IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
5:
6: BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
7: //{{AFX_MSG_MAP(CMainFrame)
8: ON_WM_CREATE()
9: ON_COMMAND(ID_VIEW_COLORBAR, OnViewColorbar)
10: ON_UPDATE_COMMAND_UI(ID_VIEW_COLORBAR, OnUpdateViewColorbar)
11: //}}AFX_MSG_MAP
12: ON_CBN_SELCHANGE(IDC_CBWIDTH, OnSelChangeWidth)
13: END_MESSAGE_MAP()
14:
15: static UINT indicators[] =
16: {
17: ID_SEPARATOR, // Statusleistenanzeige
18: ID_INDICATOR_COLOR,
19: ID_INDICATOR_CAPS,
20: ID_INDICATOR_NUM,
21: ID_INDICATOR_SCRL,
22: };
23:
24: ///////////////////////////////////////////////////////////////////////////
25: // CMainFrame Konstruktion/Zerstörung
Falls Sie eine der Anzeigen für die Feststelltasten aus der Statusleiste entfernen möchten,
löschen Sie einfach den entsprechenden Eintrag in der Tabellendefinition. Weiter
unten in der Funktion OnCreate
, die die Statusleiste (unmittelbar nach den Symbolleisten)
erstellt, sehen Sie auch, wo diese Tabelle zum Einsatz kommt, um die Statusleiste
mit dem folgenden Code zu erzeugen:
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
Nachdem die Statusleiste erzeugt wurde, folgt ein Aufruf der Funktion SetIndicators
auf der Statusleiste, um die Ausschnitte gemäß der Definition in der Tabelle der Statusleistenanzeigen
in die Statusleiste aufzunehmen. Die mit den IDs in der Tabelle der
Statusleistenanzeigen verbundenen Strings dienen dazu, die Ausschnitte zu initialisieren
und deren Größe festzulegen. Wenn Sie jetzt die Anwendung kompilieren und
ausführen, sehen Sie den neuen Farbenausschnitt in der Statusleiste. Der Ausschnitt
zeigt den Titel aus der Zeichenfolgentabelle an.
Nachdem Sie den Ausschnitt in die Statusleiste aufgenommen haben, können Sie
über das Ereignis UPDATE_COMMAND_UI
alle Aktualisierungen des Ausschnitts erledigen
lassen. Dazu müssen Sie lediglich eine Behandlungsroutine für das Ereignis auf der
Objekt-ID des Ausschnitts hinzufügen und dieses Ereignis verwenden, um den Text im
Ausschnitt festzulegen. Da die Statusleiste immer sichtbar ist, wird das Ereignis
UPDATE_COMMAND_UI
für die Ausschnitte in der Statusleiste jedesmal ausgelöst, wenn
die Anwendung im Leerlauf arbeitet. Das bedeutet, daß das Ereignis auftritt, nachdem
die Anwendung die Abarbeitung aller Tastenbetätigungen und Mausbewegungen abgeschlossen
hat. In etwa einer Woche, am Tag 18, lernen Sie bei der Behandlung des
Multitasking, wie häufig und wann Tasks, die im Leerlauf einer Anwendung arbeiten,
ausgelöst werden.
In der Behandlungsroutine müssen Sie einen String erzeugen, der den Namen der aktuellen Farbe enthält (oder was auch immer für ein Text im Ausschnitt der Statusleiste erscheinen soll). Als nächstes ist sicherzustellen, daß der Ausschnitt aktiviert ist. Schließlich müssen Sie den Text des Ausschnitts auf den erzeugten String setzen.
Um das Ganze in Ihrer Anwendung zu implementieren, erzeugen Sie eine Behandlungsroutine
für die Nachricht UPDATE_COMMAND_UI
. Auch in diesem Fall ist der Klassen-Assistent
nicht über den Ausschnitt in der Statusleiste informiert, so daß Sie die
Behandlungsroutine manuell erzeugen und in die Nachrichtenzuordnungstabelle eintragen
müssen. Um die Behandlungsroutine zu erstellen, fügen Sie der Dokumentklasse
(CToolbarDoc
) eine neue Member-Funktion mit dem Typ afx_msg void
, der Deklaration
OnUpdateIndicatorColor (CCmdUI * pCmdUI)
und dem Zugriffsstatus
Protected hinzu. In die Funktion nehmen Sie den Code von Listing 12.13 auf.
Listing 12.13: Die Funktion OnUpdateIndicatorColor
1: void CToolbarDoc::OnUpdateIndicatorColor(CCmdUI *pCmdUI)
2: {
3: CString strColor;
4:
5: // Wie heißt die aktuelle Farbe?
6: switch (m_nColor)
7: {
8: case 0: // Schwarz
9: strColor = "SCHWARZ";
10: break;
11: case 1: // Blau
12: strColor = "BLAU";
13: break;
14: case 2: // Grün
15: strColor = "GRÜN";
16: break;
17: case 3: // Cyan
18: strColor = "CYAN";
19: break;
20: case 4: // Rot
21: strColor = "ROT";
22: break;
23: case 5: // Magenta
24: strColor = "MAGENTA";
25: break;
26: case 6: // Gelb
27: strColor = "GELB";
28: break;
29: case 7: // Weiß
30: strColor = "WEISS";
31: break;
32: }
33: // Statusleisten-Ausschnitt aktivieren
34: pCmdUI->Enable(TRUE);
35: // Text im Ausschnitt der Statusleiste
36: // auf die aktuelle Farbe setzen
37: pCmdUI->SetText(strColor);
38: }
Diese Funktion befolgt genau drei Schritte: sie erzeugt einen String mit dem Namen der aktuellen Farbe, stellt sicher, daß der Ausschnitt in der Statusleiste aktiviert ist, und setzt den Text im Feld auf den erzeugten String.
Um nun sicherzustellen, daß der Aufruf der neuen Behandlungsroutine wie erwartet
erfolgt, müssen Sie einen ON_UPDATE_COMMAND_UI
-Eintrag in die Nachrichtenzuordnungstabelle
am Beginn des Quellcodes der Dokumentdatei aufnehmen, wie es Listing
12.14 zeigt.
Listing 12.14: Die modifizierte Nachrichtenzuordnungstabelle von CToolbarDoc
1: ///////////////////////////////////////////////////////////////////////////
2: // CToolbarDoc
3:
4: IMPLEMENT_DYNCREATE(CToolbarDoc, CDocument)
5:
6: BEGIN_MESSAGE_MAP(CToolbarDoc, CDocument)
7: ON_UPDATE_COMMAND_UI(ID_INDICATOR_COLOR, OnUpdateIndicatorColor)
8: //{{AFX_MSG_MAP(CToolbarDoc)
9: ON_UPDATE_COMMAND_UI(ID_WIDTH_VTHIN, OnUpdateWidthVthin)
10: .
11: .
12: ON_COMMAND(ID_WIDTH_VTHIN, OnWidthVthin)
13: //}}AFX_MSG_MAP
14: END_MESSAGE_MAP()
Nachdem Sie die Behandlungsroutine und den Eintrag in die Nachrichtenzuordnungstabelle hinzugefügt haben, können Sie nun Ihre Anwendung kompilieren und ausführen. In der Statusleiste sollte der Farbenausschnitt automatisch aktualisiert werden, um die momentane Zeichenfarbe anzugeben, wie es Abbildung 12.6 zeigt.
Abbildung 12.6:
Die Zeichenanwendung zeigt die aktuelle Farbe in der Statusleiste an.
Der heutige Lehrstoff war recht umfangreich. (Zeichnet sich hier ein Trend ab?) Sie haben gelernt, wie man eigene Symbolleisten entwirft und erstellt. In diesem Zusammenhang haben Sie auch erfahren, wie man Aufforderungen in der Statusleiste für die Symbolleistenschaltflächen und Menüs festlegt sowie QuickInfos anzeigt, wenn man die Maus ein paar Sekunden über einer Symbolleistenschaltfläche ruhen läßt. Sie wissen nun, wie man diese Symbolleisten erstellt und sie mit dem Anwendungsgerüst verbindet. Weiterhin haben Sie gelernt, wie man über einen Menübefehl steuert, ob die Symbolleiste sichtbar ist.
Als nächstes sind wir darauf eingegangen, wie man ein Kombinationsfeld in einer Symbolleiste unterbringt, damit man dem Benutzer der Anwendung die gleiche Bequemlichkeit bieten kann, die er von anderen bekannten Softwarepaketen her gewohnt ist. Gleichzeitig haben Sie erfahren, wie man ein Kombinationsfeld per Code erzeugt, ohne daß man mit dem Dialog-Editor arbeiten muß, und wie man die Dropdown-Liste des Kombinationsfelds mit Texteinträgen füllt. Dann wurde gezeigt, wie man das Kombinationsfeld in die Anwendung einbindet, indem man Behandlungsroutinen für die Ereignisse des Kombinationsfelds erstellt, und wie man das Kombinationsfeld aktualisiert, um die am Anwendungsmenü vorgenommenen Änderungen widerzuspiegeln.
Schließlich hat der heutige Tag gezeigt, wie man eigene Ausschnitte in die Statusleiste aufnimmt und wie man den Ausschnitt aktualisiert, um den momentanen Status der Anwendung wiederzugeben.
Frage:
In manchen Anwendungen hat man bei Symbolleisten die Option, Text anzuzeigen,
beispielsweise im Internet Explorer. Wie läßt sich Text für meine Symbolleistenschaltflächen
hinzufügen?
Antwort:
Leider bietet der Symbolleisten-Editor keine Möglichkeit, um Symbolleistenschaltflächen
einen Text zuzuordnen. Das bedeutet, daß man den Text per
Anwendungscode in die Schaltflächen aufnehmen muß, genauso wie man für
alle Schaltflächen der Symbolleiste Farbe das Verhalten als Optionsfelder realisiert.
Mit der Funktion SetButtonText legen Sie den Text auf jeder Symbolleistenschaltfläche
individuell fest. Diese Funktion übernimmt zwei Argumente:
das erste ist der Index der Schaltfläche, das zweite enthält den Text für die
Schaltfläche. Wenn Sie wirklich Text auf den Symbolleistenschaltflächen unterbringen
möchten, müssen Sie außerdem die Symbolleiste in der Größe ändern,
um Platz für den anzuzeigenden Text zu schaffen.
Frage:
Ich habe im Symbolleisten-Editor einige Änderungen an der Symbolleiste Farben
vorgenommen und erhalte nun jedesmal einen Assertion-Fehler, wenn ich die Anwendung
auszuführen versuche. Was ist passiert?
Antwort:
Das Problem besteht darin, daß der Symbolleisten-Editor die Separatoren gefunden
hat, die Sie in die Ressourcendatei als Platzhalter für das Kombinationsfeld
aufgenommen haben. Der Symbolleisten-Editor nimmt an, daß es sich
hier um Fehler handelt, und entfernt die Platzhalter automatisch. Der Fehler,
den Sie erhalten, tritt deshalb auf, weil Sie versuchen, mit einem Steuerelement
in der Symbolleiste Farben zu arbeiten, das nicht existiert. Um das Problem
zu umgehen, öffnen Sie die Ressourcendatei erneut im Editor und fügen
die beiden Separatoren wieder am Ende der Definition der Farben-Symbolleiste
an. Laden Sie dann das Projekt in Visual C++, und kompilieren Sie die
Anwendung neu.
Frage:
Das Kombinationsfeld in meinen Symbolleisten sieht zu groß aus. Wie kann ich
erreichen, daß es sich harmonischer in die Symbolleiste einfügt?
Antwort:
Um das Kombinationsfeld in die Symbolleiste einzupassen, wie es zum Beispiel
im Visual Studio von Visual C++ zu sehen ist, sind eine Reihe von Dingen
zu erledigen. Zuerst verringern Sie den oberen Teil des Kombinationsfelds
um 3. Damit entsteht ein schmaler Rand zwischen dem oberen Rand des
Kombinationsfelds und dem Rand der Symbolleiste. Als nächstes wählen Sie
für das Kombinationsfeld eine kleinere Schrift, die sich besser in die Symbolleiste
einfügt. Experimentieren Sie etwas mit Schriften und Schriftabständen,
bis Sie das Optimum für das Kombinationsfeld in der Symbolleiste gefunden
haben.
Frage:
Wie kann ich den Text im ersten Abschnitt der Statusleiste festlegen, ohne Menü-
und Symbolleistenaufforderungen zu verwenden?
Antwort:
Mit SetWindowText können Sie den Text im ersten Ausschnitt der Statusleiste
festlegen. Per Voreinstellung ist der erste Ausschnitt in der Statusleiste
ein Separator, der sich automatisch erweitert und dann die Breite der Statusleiste
abzüglich der anderen nach rechts ausgerichteten Ausschnitte in der
Leiste einnimmt. Ruft man die Funktion SetWindowText auf der Statusleistenvariablen
auf, wird nur der Text im ersten Ausschnitt festgelegt. Wenn
Sie den Text in einem der anderen Ausschnitte ändern möchten und das zu
anderen Zeiten als in der Behandlungsroutine der Nachricht
ON_UPDATE_COMMAND_UI, können Sie mit der Funktion SetPaneText arbeiten.
Es gibt zwei Möglichkeiten, um den Text im Hauptteil der Statusleiste
zu setzen. Die erste sieht folgendermaßen aus:
CString myString = "Das ist mein Statusleistentext"
m_wndStatusBar.SetWindowText(myString);
CString* myString = " Das ist mein Statusleistentext "
m_wndStatusBar.SetPaneText(0, myString);
1. Wie verbinden Sie eine Symbolleistenschaltfläche mit einem Menübefehl, der dieselbe Funktion auslöst?
2. Wie kann man sicherstellen, daß eine Symbolleiste mit dem Rahmenfenster verankert ist?
3. Wie läßt sich die Statusanzeige für die numerische Feststelltaste aus der Statusleiste entfernen?
4. Warum muß man die Ressourcendatei bearbeiten, um ein Kombinationsfeld in eine Symbolleiste aufzunehmen?
1. Fügen Sie einen weiteren Ausschnitt in die Statusleiste ein, um die momentan ausgewählte Breite anzuzeigen.
2. Nehmen Sie in die Hauptsymbolleiste eine Schaltfläche auf, mit der man die Symbolleiste Farben ein-/ausschalten kann, wie es Abbildung 12.7 zeigt.
Abbildung 12.7:
Der Umschalter für die Symbolleiste Farben