Cursor
Genauso wie bei den Icons gibt es auch beim Cursor System-Cursor und anwenderdefinierte
Cursor. Und auch hier können anwenderdefinierte Cursor sowohl in einer Ressource
als auch in einer externen Datei, einer ICO-oder ANI-Datei, abgelegt sein.
Standardmäßig besitzen Cursor eine Ausdehnung von 32x32 Pixel und sind monochrom.
Seit WINDOWS95 können Cursor jedoch auch farbig oder sogar animiert sein.
 |
Beachten Sie den Unterschied zwischen einem Cursor und dem in Kapitel
Eingaben behandelten Caret. Der Cursor ist der Mauszeiger und das Caret
die Schreibmarkierung in einem Editfeld. |
Aber steigen wir auch hier gleich wieder in die Praxis ein.
 |
Erzeugen Sie zunächst wieder ein SDI-Projekt und geben Sie
diesem den Namen Cursor. Nachdem Sie das Projekt erstellt haben, gehen
Sie wieder in die Ressourcen-Ansicht. Da vom Anwendungs-Assistenten standardmäßig
keine Cursor-Ressource angelegt wird, müssen Sie sich eine Cursor-Ressource
zunächst selbst erstellen. Klicken Sie dazu eine beliebige Ressource mit der
rechten Maustaste an und wählen aus dem eingeblendeten Kontext-Menü den Eintrag
Einfügen... aus. Sie erhalten darauf folgenden Dialog einblendet:

Selektieren Sie im Dialog den Eintrag Cursor und klicken dann den
Button Neu an. Daraufhin wird eine neue, monochrome Cursor-Ressource
mit der Standard-Auflösung 32x32 erzeugt. Wir wollen jedoch gleich einen farbigen
Cursor erstellen. Klicken Sie dazu den Button neben dem Gerät-Auswahlfeld
an und im eingeblendeten Dialog dann den Button Benutzerdefiniert....
Wählen Sie als Größe für den Cursor die Standard-Auflösung 32x32 und als Farbtiefe
16 Farben aus. Erstellen Sie anschließend mit dem Cursor-Editor einen eigenen,
farbigen Cursor. Die Vorgehensweise dazu ist gleich wie bei der Erstellung eines
Icons. Cursor können genauso wie Icons transparente und inverse Bereiche besitzen.
Beachten Sie dies bitte bei der Erstellung des Cursors.
Cursor besitzen jedoch noch eine zusätzliche Eigenschaft zu Icons: sie haben
einen sogenannten Hotspot. Der Hotspot ist der Punkt des Cursors, auf den WINDOWS
sich bezieht um die Cursorposition zu bestimmen. Standardmäßig liegt dieser
Hotspot auf der Cursor-Koordinate 0,0. Sie können diesen Hotspot jedoch durch
anklicken des Hotspot-Buttons oberhalb des Editorfensters umsetzen.
Nach dem Sie Ihren Cursor erstellt haben, sollten Sie ihm noch eine aussagekräftigere
ID als IDC_CURSOR1 geben. Klicken Sie dazu die ID mit der rechten Maustaste
an und wählen Sie im Kontext-Menü den Eintrag Eigenschaften aus. Überschreiben
Sie im dann eingeblendeten Dialog einfach die vorgegebene ID. Für das Beispiel
verwenden Sie bitte die ID IDC_MYCUR.
 |
Die IDs für Cursor sollten immer mit dem Präfix IDC_xxx beginnen |
|
Damit haben Sie Ihren ersten Cursor erstellt. Bevor Sie den Cursor nun zur Anzeige
bringen können, müssen sie diesen laden, genauso wie die in der vorherigen Lektion
behandelten Icons. Hierbei muss nun unterschieden werden, ob Sie einen System-Cursor
oder einen anwenderdefinierten Cursor laden wollen. Um einen der System-Cursor zu
laden, rufen Sie die CWinApp Methode LoadStandardCursor(...) auf.
Diese Methode erhält als Parameter die ID des zu ladenden Cursors laut nachfolgender
Tabelle:
Als Returnwert liefert LoadStandardCursor(...) ein Handle HCURSOR auf
den geladenen Cursor. Um den geladenen Cursor dann mit einem Fenster zu verbinden,
wird die API-Funktion SetCursor(...) aufgerufen, die als Parameter das
Handle des geladenen Cursors erhält.
 |
Der Cursor gehört zu den sogenannten Fensterklassen-Attributen! Alle Fenster,
die zu einer Fensterklasse gehören, besitzen immer den gleichen Cursor! |
Doch das Setzen des Cursor über die Funktion SetCursor(...) alleine
reicht leider noch nicht aus. Zusätzlich muss der Cursor noch in die Fensterklasse
eingetragen werden. Dies erfolgt durch den Aufruf der bereits früher besprochenen
API-Funktion SetClassLong(...). Als Index ist hierbei die Konstante GCL_HCURSOR
anzugeben und im LONG-Parameter das Handle des Cursors.
 |
Vergessen Sie einmal den Aufruf von SetClassLong(...), so wird
zunächst der neue Cursor dargestellt. Sobald Sie aber die Maus bewegen, erhalten
Sie wieder den alten Cursor angezeigt! |
So, und auf geht's wieder. Jetzt sind Sie wieder dran.
 |
Versuchen Sie einmal alle System-Cursor nacheinander darzustellen.
Jedes Mal wenn die linke Maustaste gedrückt wird, soll ein anderer System-Cursor
dargestellt werden. Überlegen Sie sich zuerst, in welcher Methode Sie den Cursor-Wechsel
unterbringen.
 |
Wenn Sie genug geschwitzt haben kann ich Ihnen auch meine Lösung anzeigen. |
Lösung zur Darstellung der System-Cursor
Der Cursor-Wechsel erfolgt (natürlich) in der Methode
OnLButtonDown(...). Damit könnte diese Methode etwa wie folgt aussehen:
void CCursorView::OnLButtonDown(UINT
nFlags, CPoint point)
{
// TODO: Code für die Behandlungsroutine für Nachrichten hier
einfügen...
// Aktueller Cursorindex
static int nCurNum =
0;
// System-Cursor
static const char* ahSysCursor[]
=
{IDC_IBEAM, IDC_ARROW, IDC_WAIT, IDC_CROSS,
IDC_UPARROW, IDC_SIZENWSE, IDC_SIZENESW,
IDC_SIZEWE,
IDC_SIZENS, IDC_SIZEALL, IDC_NO,
IDC_APPSTARTING,
IDC_HELP};
// System-Cursor laden
HCURSOR hCur = AfxGetApp()->LoadStandardCursor(ahSysCursor[nCurNum]);
// und als Fensterklassen-Cursor
eintragen
::SetCursor(hCur);
::SetClassLong(*this,GCL_HCURSOR,(LONG)hCur);
// Cursorindex erhoehen
nCurNum++;
if (nCurNum == sizeof(ahSysCursor)/sizeof(char*))
nCurNum = 0;
} |
Zu Testzwecken können Sie auch einmal einen der beiden Aufrufe von
SetCursor(...) bzw. SetClassLong(...) auskommentieren
um die Wirkungsweise der Funktionen zu beobachten.
Ende der Lösung
|
|
So, als nächstes werden wir unseren eigenen, am Anfang der Lektion erstellen,
Cursor sowie einen vorgegebenen animierten Cursor (abgelegt in einer externen ANI-Datei)
darstellen. Um einen Cursor aus einer Ressource zu laden, rufen Sie die CWinApp
Methode LoadCursor(...) auf, die als Parameter die ID des zu ladenden Cursors
erhält. Als Returnwert erhalten Sie wieder das Cursor-Handle.
 |
Es gibt noch eine weitere Methode LoadCursor(...),
die als Parameter einen char-Zeiger besitzt. Diese Methode lädt eine
Cursor-Ressource über einen Namen anstatt über eine ID. Der Cursor-Editor des
Visual Studios erzeugt aber in der Regel immer eine ID, so dass Sie diese Methode
relativ selten benötigen. |
Soll ein Cursor aus einer externen Datei geladen werden, so verwenden Sie hierzu
die API-Funktion LoadCursorFromFile(...).
 |
Und weiter geht's mit dem Beispiel. Unser eigener Cursor sowie
der animierte Cursor aus der Datei 99Templates\globle.ani soll immer
dann anzeigt werden, wenn die rechte Maustaste gedrückt wird, wobei bei jedem
Drücken der rechten Maustaste zwischen den beiden Cursor umgeschaltet werden
soll. Kopieren Sie sich nun den animierten Cursor zuerst in Ihr Arbeitsverzeichnis.
Anschließen fügen Sie der Klasse CCursorView die Methode OnRButtonDown(...)
hinzu sowie die beiden Membervariablen m_hCur1 und m_hCur2,
beide vom Typ HCURSOR. Die beiden Membervariablen dienen zur Aufnahme der entsprechenden
Cursor-Handle. Die Cursor selbst sollen selbstverständlich nur einmal geladen
werden. Dies erfolgt wiederum in der Methode OnInitialUpdate(...).
Fügen Sie diese Methode ebenfalls zur Klasse hinzu. Modifizieren Sie den Code
der beiden neuen Methoden wie folgt:
void CCursorView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: Speziellen Code hier einfügen und/oder Basisklasse aufrufen
// Cursor aus Ressource
sowie aus Datei laden
m_hCur1 = AfxGetApp()->LoadCursor(IDC_MYCUR);
m_hCur2 = (HCURSOR)::LoadCursorFromFile("globe.ani");
// Geladenen Cursor nun
setzen
::SetCursor(m_hCur1);
// Sehr wichtig, sonst wird
Cursor sofort wieder zurueckgesetzt!
::SetClassLong(*this,GCL_HCURSOR,(LONG)m_hCur1);
}
void CCursorView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Code für die Behandlungsroutine für Nachrichten hier
einfügen...
// Cursor umsetzen
if (::GetClassLong(*this,GCL_HCURSOR)
== (DWORD)m_hCur2)
{
::SetClassLong(*this,GCL_HCURSOR,(LONG)m_hCur1);
::SetCursor(m_hCur1);
}
else
{
::SetClassLong(*this,GCL_HCURSOR,(LONG)m_hCur2);
::SetCursor(m_hCur2);
}
} |
Übersetzen und starten Sie das Programm nun. Welchen Cursor erhalten Sie?
|
Nun, vermutlich werden Sie zunächst überhaupt keinen Cursor sehen. Erst durch
drücken der linken Maustaste sehen Sie nacheinander die verschiedenen System-Cursor.
Was passiert hier? Erinnern Sie sich noch an den Anfang der Lektion? Dort haben
wir einen anwenderdefinierten farbigen Cursor erstellt. Der leere Standard-Cursor
(schwarz/weiß) unter dieser ID ist jedoch immer noch vorhanden. Und genau dieser
Cursor wird in unserem Programm geladen. Um den farbigen Cursor zu laden, müssen
Sie zuerst den Standard-Cursor entfernen.
 |
Entfernen Sie den Standard-Cursor wie folgt: Wählen Sie zunächst
den eigenen Cursor in der Ressource-Ansicht aus. Im Auswahlfeld Gerät
selektieren Sie dann den Cursor Monochrom (32.x32). Anschließend öffnen Sie
das Menü Bild und wählen dort den Menüpunkt Geräteabbild löschen
aus. Der Standard-Cursor wird aus der Ressource entfernt und es bleibt nur noch
der eigene farbige Cursor übrig. Übersetzen Sie das Programm erneut und Sie
werden die gewünschten Cursor anzeigt bekommen.
|
Das fertige Beispiel finden Sie unter 07Ressourcen\Cursor.
Damit beenden wir die Einführung in die Cursor-Ressource und sehen uns in der
nächsten Lektion die String-Ressource an. Bei den Tipps&Tricks zu diesem Kapitel
erfahren Sie dann noch, wie Sie einen Cursor durch die Anwendung zeichnen lassen
können.
|