Icons
Icons sind Symbole die unter anderem bei der Darstellung einer Anwendung im Explorer
oder auch oben links in der Titelzeile eines Fensters verwendet werden. Icons können
aber auch als grafische Elemente in Fenstern und Dialogboxen eingesetzt werden.
Sie können eine (fast) beliebige Größe annehmen. Standardgrößen für Icons sind 16x16
Pixel (small icon) und 32x32 Pixel (standard icon). Soll ein Icon als Fenstersymbol
verwendet werden, so muss es zumindest in der Größe 32x32 Pixel vorhanden sein.
Das kleine Icon (16x16) wird u.a. für die Darstellung in der Titelzeile eingesetzt.
Außerdem wird es angezeigt wenn im Explorer die Darstellung 'kleine Symbole' verwendet
wird. Die Farbtiefe für Icons kann 2, 16 oder 256 Farben betragen.
 |
Viele der in diesem Kapitel behandelten Ressourcen lassen sich
entweder aus einer zum Programm gelinkten Ressource oder aus einer separaten
Datei (z.B. ICO-Datei für Icons) laden. Versuchen Sie aber trotzdem soweit wie
möglich Ihre Ressourcen in einer Ressource-Datei unterzubringen. Sie brauchen
dann bei der Weitergabe Ihrer Anwendung nur die EXE/DLL-Datei weitergeben und
nicht noch zusätzliche Ressource-Dateien. |
Und gehen wir jetzt auch gleich wieder zur Praxis über.
 |
Erstellen Sie nun zunächst, wie gewohnt, ein SDI-Rahmenprogramm
mit Hilfe des Anwendungs-Assistenten. Geben Sie dem Projekt den Namen 'Icons'.
Nach dem das Rahmenprogramm erstellt wurde, werden wir uns nun die Handhabung
des Icon-Editors einmal kurz ansehen. Klicken Sie im Arbeitsbereich einmal
auf den Tabellenreiter Ressourcen. Sie erhalten dann in Baumdarstellung
alle vom Anwendungs-Assistenten erstellten Ressourcen aufgelistet. Öffnen Sie
nun die Icon-Ressourcen durch einen Doppelklick auf den Ordner Icon.
Daraufhin werden alle im Projekt verwendeten Icon-IDs aufgelistet. Um ein bestimmtes
Icon im Icon-Editor zu öffnen, führen Sie erneut einen Doppelklick auf die ID
des gewünschten Icons aus. Im Beispiel unten wurde das Icon IDR_MAINFRAME
im Editor geöffnet.

Das Icon mit der ID IDR_MAINFRAME wird zur Darstellung der Anwendung
im Explorer verwendet wenn Sie unter Ansicht die Option 'Große
Symbole' eingestellt haben. Doch wo ist das kleine Icon, das z.B. in der
Titelleiste darstellt wird? Klicken Sie einmal auf den Pfeil im Auswahlfeld
Gerät, oberhalb des Icon-Editors. Im aufgeklappten Auswahlfeld erscheint
der Eintrag 'Klein (16x16)'. Klicken Sie diesen Eintrag an und das
kleine Icon wird im Icon-Editor dargestellt. Wie Sie sehen, können sich unter
einer ID mehrere Icons mit unterschiedlichen Auflösungen befinden. Wie innerhalb
einer Anwendung verschiedene Icons mit der gleichen ID auswählt werden, das
erfahren Sie später.
Um nun zu sehen, dass dies wirklich zwei verschiedene Icons sind, füllen
Sie die Rechtecke über den Buchstaben MFC beim kleinen Icon einmal mit der Farbe
gelb und beim großen Icon mit der Farbe rot aus. Übersetzen Sie das Programm
und starten Sie es. In der Titelzeile wird das kleine Icon (mit gelb ausgefüllten
Rechtecken) dargestellt werden. Rufen Sie anschließend den Explorer auf und
gehen Sie in das Verzeichnis, in dem die EXE-Datei des Beispiels abgelegt ist.
Je nach dem, ob Sie die Ansicht auf 'Große Symbole' eingestellt haben
oder nicht, wird das das Icon mit den roten oder mit den gelben Rechtecken dargestellt
werden.
|
 |
Und noch ein Hinweis zum Schluss dieser kleinen Demonstration.
Icons besitzen transparente und inverse Bereiche. Transparente Bereiche werden
bei der Darstellung des Icons nicht gezeichnet, d.h. der Hintergrund bleibt
erhalten. Die inversen Bereiche verwenden zur Darstellung der aktuellen Iconfarbe
die invertierte Farbe des Hintergrunds. Um einen bestimmten Bereich innerhalb
eines Icons als transparenten bzw. inversen Bereich zu kennzeichnen, klicken
Sie das entsprechende Symbol lt. nachfolgendem Bild in der Farbauswahl an. Sie
können die zur Darstellung der Bereiche im Icon-Editor verwendeten Farben
ändern, in dem Sie einen Doppelklick auf die Symbole durchführen.

|
Sehen wir uns jetzt die verschiedenen Icon-Arten an. WINDOWS kennt im Prinzip
drei verschiedene Arten von Icons:
- System-Icon: vordefinierte Icons z.B. für die Darstellung innerhalb von Messageboxen.
- Shell-Icon: vordefinierte Icons für Laufwerke, Verzeichnisse usw.
- Anwender-Icon: vom Anwender mittels Icon-Editor erstellte Icons.
Bevor eines dieser Icon dargestellt werden kann, muss es zunächst geladen werden.
Und je nach Icon-Typ sind hierfür verschiedene Methoden/Funktionen einzusetzen.
Um ein System-Icon zu laden muss die CWinApp-Methode LoadStandardIcon(...)
aufgerufen werden. Diese Methode erhält als Parameter die ID des zu ladenden Icons
laut nachfolgender Tabelle:
|
ID
|
Icon
|
ID
|
Icon
|
| IDI_APPLICATION |
 |
IDI_ERROR |
 |
| IDI_INFORMATION |
 |
IDI_QUESTION |
 |
| IDI_WARNING |
 |
IDI_WINLOGO |
 |
Als Returnwert liefert LoadStandardIcon(...) ein Handle HICON
auf das geladene Icon. Um dieses Icon darzustellen wird die CDC-Methode
DrawIcon(...) aufgerufen, die als Parameter das vorhin ermittelte Handle
des Icons erhält.
Erweitern wir das Beispiel nun um die Darstellung der System-Icons.
 |
Damit die transparenten Bereiche der Icons besser ersichtlich
werden, füllen wir den Hintergrund des Fensters mit einem Farbverlauf aus. Fügen
Sie dazu der Klasse CIconsView über den Klassen-Assistenten die Nachrichten-Methode
OnEreaseBkgnd(...) hinzu. Modifizieren Sie den Code der Methode wie
folgt. Beachten Sie bitte, dass der Aufruf der Basisklassen-Methode entfernt
wurde.
BOOL CIconsView::OnEraseBkgnd(CDC*
pDC)
{
// TODO: Code für die Behandlungsroutine für Nachrichten hier
einfügen ...
// Fuelle Hintergrund aus
CRect CClientRect;
GetClientRect(&CClientRect);
// Farbverlauf initialisieren
int nDirection = 1;
COLORREF ActColor = 0x000080FF;
// Fensterhintergrund mit
Muster versehen
for (int nLoop=0; nLoop<(CClientRect.right>>2);
nLoop++)
{
pDC->FillSolidRect(0,(nLoop<<2),CClientRect.right,7,ActColor);
ActColor += 0x00001000*nDirection;
if (ActColor == 0x0000F0FF)
nDirection =
-1;
if (ActColor == 0x000080FF)
nDirection =
1;
}
return TRUE;
} |
So, und nun sind Sie wieder daran. Versuchen Sie einmal alle System-Icons
innerhalb einer Zeile darzustellen. Das Laden der Icons erfolgt sinnvollerweise
nur einmal, und zwar beim Initialisieren des Ansichtsobjekts. Fügen Sie daher
der Klasse CIconsView die virtuelle Methode OnInitialUpdate(...)
sowie die Membervariable HICON m_ahSysIcon[6] hinzu um die Icon-Handles
abzuspeichern. Geben Sie der Zeile mit den Icons die Überschrift "System-Icons".
 |
Eigentlich sollte diese Übung leicht sein. Trotzdem kann ich Ihnen auch
meine Lösung anzeigen. |
Lösung zur Darstellung der System-Icons
Zuerst werden in der OnInitialUpdate(...) Methode
die System-Icons mittels LoadStandardIcon(...) geladen.
void CIconsView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: Speziellen Code hier einfügen und/oder Basisklasse aufrufen
// Standard-Icons
laden
static const char* m_acSYSICONS[]
= {IDI_APPLICATION,IDI_INFORMATION,
IDI_WARNING,IDI_ERROR,
IDI_QUESTION,IDI_WINLOGO};
for (int iLoop=0; iLoop<sizeof(m_ahSysIcon)/sizeof(HICON); iLoop++)
m_ahSysIcon[iLoop]= AfxGetApp()->LoadStandardIcon(m_acSYSICONS[iLoop]);
} |
Haben Sie auch beachtet, dass LoadStandardIcon(...) eine Methode
von CWinApp ist? Den Zeiger auf das aktuelle CWinApp Objekt
erhalten Sie durch den Aufruf der Funktion AfxGetApp(...).
Wurden die Icons geladen, so können sie schließlich mittels DrawIcon(...)
dargestellt werden. Sie fragen sich: wo? Dort wo alle Ausgaben in der Regel
erfolgen, in der OnDraw(...) Methode natürlich.
void CIconsView::OnDraw(CDC*
pDC)
{
CIconsDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// ZU ERLEDIGEN: Hier Code zum Zeichnen der ursprünglichen Daten
hinzufügen
// Textausgabe initialisieren
pDC->SetBkMode(TRANSPARENT);
pDC->SelectStockObject(SYSTEM_FONT);
pDC->SetTextColor(RGB(0,0,0));
// System-Icons zeichnen
pDC->TextOut(10,10,"System-Icons");
for (int iLoop=0; iLoop<sizeof(m_ahSysIcon)/sizeof(HICON); iLoop++)
pDC->DrawIcon(iLoop*40+10,30,m_ahSysIcon[iLoop]);
} |
War doch nicht besonders schwierig, oder?
Ende der Lösung
|
Wenn Sie alles richtig eingegeben haben, dann sollten Sie in etwa folgende
Ausgabe erhalten:

|
So weit, so gut. Sehen wir uns nun an, wie Shell-Icons (z.B. Laufwerks- oder
Drucker-Icons) dargestellt werden. Auch diese Icons müssen zuerst geladen werden.
Leider kann hierfür nicht die Methode LoadStandardIcon(...) verwendet werden.
Um Shell-Icons zu laden muss die API-Funktion SHGetFileInfo(...)
aufgerufen werden. Da die Bedeutung der Funktionsparameter vielleicht aus der Online-Hilfe
nicht gleich ersichtlich ist, wollen wir uns hier einmal wieder das Prototyping
der Funktion ansehen:
WINSHELLAPI DWORD WINAPI SHGetFileInfo( LPCTSTR pszPath,
DWORD dwFileAttributes,
SHFILEINFO FAR *psfi, UINT cbFileInfo,
UINT uFlags ); |
Mit Hilfe dieser Funktion können Sie vielseitige Informationen über ein Shell-Objekt
(wie z.B. einem Verzeichnis oder einem Laufwerk) abfragen. Wir werden hier aber
nur den Fall betrachten, dass ein entsprechendes Shell-Icon geladen werden soll.
Dazu setzen Sie den Parameter pszPath auf einen String der den Pfad enthält,
dessen Icon geladen werden soll. Soll z.B. das Laufwerks-Icon für das Laufwerk
C: geladen werden, so ist pszPath auf "C:\\"
zu setzen. Beachten Sie bitte die doppelten Backslash im Pfad! Genauso leicht lässt
sich aber auch das Shell-Icon für ein Verzeichnisse laden. Setzen Sie dazu pszPath
einfach auf das gewünschte Verzeichnis, z.B. "C:\\WINDOWS". Der nächste
Parameter dwFileAttributes wird zum Laden von Icons nicht benötigt und
sollte mit '0UL' belegt werden. psfi ist ein Zeiger auf eine Struktur vom
Typ SHFILEINFO. Diese Struktur wird durch die Funktion mit den angeforderten Informationen
ausgefüllt und besitzt folgenden Aufbau:
typedef struct _SHFILEINFO{
HICON hIcon;
int iIcon;
DWORD dwAttributes;
char szDisplayName[MAX_PATH];
char szTypeName[80];
} SHFILEINFO; |
In unserem Fall, dem Auslesen von Shell-Icons, ist nur der Inhalt des Elements
hIcon relevant. Es enthält nach dem Aufruf der Funktion das Handle des
geladenen Shell-Icon. Der nächste Parameter der Funktion SHGetFileInfo(...),
cbFileInfo, enthält die Größe der Struktur SHFILEINFO in Bytes. Und der
letzte Parameter uFlags steuert unter anderem, welches Icon geladen werden
soll. Wie Sie bereits erfahren haben, können unter einer ID Icons mit verschiedenen
Größen abgespeichert sein. Folgende Flags können u.a. beim Laden eines Shell-Icons
für uFlags gesetzt werden:
|
Flag
|
Bedeutung
|
| SHGFI_ICON |
Laden eines Shell-Icons;
dieses Flag muss immer gesetzt sein! |
| SHGFI_LARGEICON |
Lädt das große Icon, Auflösung
32x32; Standard-Einstellung! |
| SHGFI_OPENICON |
Lädt das Icon, das einem
geöffnetem Objekt (z.B. Verzeichnis) entspricht. |
| SHGFI_SMALLICON |
Lädt das kleine Icon, Auflösung
16x16. |
| SHGFI_PIDL |
Pfadangabe pszPath enthält
einen Zeiger auf eine ITEMIDLIST
Struktur (siehe weiter unten). |
Die so erhaltenen Icons müssen nun 'nur' noch ausgegeben werden. Leider geht
dies nicht mit der vorhin aufgeführten CDC-Methode DrawIcon(...).
DrawIcon(...) ist nur in der Lage Icons mit der Standardauflösung von 32x32
darzustellen. Kleine Icons (Auflösung 16x16) werden bei der Ausgabe entsprechend
vergrößert. Sollen auch die kleinen Icons richtig dargestellt werden, so muss dazu
die API-Funktion DrawIconEx(...) verwendet werden. Für die Ausgabe von
Icons sind nur die Parameter hDC, xLeft, yTop, hIcon und diFlags
der Funktion relevant. Die Bedeutung der ersten 4 Parameter dürfte aus ihrem Namen
hervorgehen. Für den Parameter diFlags setzen Sie standardmäßig die Konstante
DI_NORMAL ein.
Wird das mittels SHGetFileInfo(...) erhaltene Icon nicht mehr benötigt,
muss es mittels DestroyIcon(...) entfernt werden.
 |
So, und nun sind Sie wieder daran. Versuchen Sie einmal folgende
Shell-Icon zu laden:
- das kleine und große Laufwerk-Icon des Laufwerks C:
- das kleine Laufwerk-Icon Ihres CD-ROM Laufwerks
- das kleine Icon und das Icon für ein geöffnetes Verzeichnis des Verzeichnisses
C:\WINDOWS
Alle Shell-Icons sind innerhalb einer Zeile darzustellen. Das Laden der Icon
erfolgt auch hier sinnvollerweise wieder in der OnInitialUpdate(...)
Methode des Ansichtsobjekts. Fügen Sie zur Klasse CIconsView die Membervariable
HICON m_ahShellIcon[12] hinzu um die Icon-Handles abzuspeichern. Geben
Sie den einzelnen Icon-Gruppen die Überschriften Laufwerk, CD-ROM
und Verzeichnisse. Denken Sie daran, dass Sie die geladenen Icons jetzt
mit Hilfe der Funktion DrawIconEx(...) darstellen und die Icons am
Ende des Programms auch wieder entfernen müssen.
 |
Eigentlich sollte diese Übung leicht sein. Trotzdem kann ich Ihnen auch
meine Lösung anzeigen. |
Lösung zur Darstellung der Shell-Icons
Zuerst werden in der OnInitialUpdate(...) Methode
die Shell-Icons geladen.
void CIconsView::OnInitialUpdate()
{
....
for (int iLoop=0; iLoop<sizeof(m_ahSysIcon)/sizeof(HICON); iLoop++)
m_ahSysIcon[iLoop]= AfxGetApp()->LoadStandardIcon(m_acSYSICONS[iLoop]);
// Shell-Icons
laden
SHFILEINFO FileInfo;
// Lesen der Laufwerks-Icon
::SHGetFileInfo("C:\\",0UL,&FileInfo,sizeof(FileInfo),SHGFI_ICON);
m_ahShellIcon[0] = FileInfo.hIcon;
::SHGetFileInfo("C:\\",0UL,&FileInfo,sizeof(FileInfo),
SHGFI_ICON|SHGFI_SMALLICON);
m_ahShellIcon[1] = FileInfo.hIcon;
// Lesen der CDROM-Icons,
Laufwerksbuchstaben eventl. anpassen!
::SHGetFileInfo("E:\\",0UL,&FileInfo,sizeof(FileInfo),SHGFI_ICON);
m_ahShellIcon[2] = FileInfo.hIcon;
::SHGetFileInfo("E:\\",0UL,&FileInfo,sizeof(FileInfo),
SHGFI_ICON|SHGFI_SMALLICON);
m_ahShellIcon[3] = FileInfo.hIcon;
// Lesen der Folder-Icons
::SHGetFileInfo("C:\\WINDOWS",0UL,&FileInfo,sizeof(FileInfo),
SHGFI_ICON|SHGFI_OPENICON);
m_ahShellIcon[4] = FileInfo.hIcon;
::SHGetFileInfo("C:\\WINDOWS",0UL,&FileInfo,sizeof(FileInfo),
SHGFI_ICON|SHGFI_SMALLICON);
m_ahShellIcon[5] = FileInfo.hIcon;
}
void CIconsView::OnDestroy()
{
CView::OnDestroy();
// TODO: Code für die Behandlungsroutine für Nachrichten hier
einfügen
// System-Icons
entfernen
for (int iIndex=0; iIndex<6;
iIndex++)
DestroyIcon(m_ahShellIcon[iIndex]);
} |
Haben Sie auch immer schön das Backslash-Zeichen innerhalb der Pfadangabe
verdoppelt?
Wurden die Icons geladen, so können sie schließlich mittels DrawIconEx(...)
dargestellt werden.
void CIconsView::OnDraw(CDC*
pDC)
{
....
// System-Icons zeichnen
....
// Laufwerk-Icons
zeichnen
pDC->TextOut(10,90,"Laufwerk");
::DrawIconEx(*pDC,10,110,m_ahShellIcon[0],0,0,0,NULL,DI_NORMAL);
::DrawIconEx(*pDC,50,110,m_ahShellIcon[1],0,0,0,NULL,DI_NORMAL);
// CDROM-Icons zeichnen
pDC->TextOut(100,90,"CD-ROM");
::DrawIconEx(*pDC,100,110,m_ahShellIcon[2],0,0,0,NULL,DI_NORMAL);
::DrawIconEx(*pDC,140,110,m_ahShellIcon[3],0,0,0,NULL,DI_NORMAL);
// Folder-Icons zeichnen
pDC->TextOut(190,90,"Verzeichnisse");
::DrawIconEx(*pDC,190,110,m_ahShellIcon[4],0,0,0,NULL,DI_NORMAL);
::DrawIconEx(*pDC,230,110,m_ahShellIcon[5],0,0,0,NULL,DI_NORMAL);
} |
War doch nicht besonders schwierig, oder?
Ende der Lösung
|
Wenn Sie alles richtig eingegeben haben, sollten Sie in etwa folgende Ausgabe
erhalten:

|
Damit sind wir nun in der Lage, Shell-Icons darzustellen die sich mit Laufwerken
und Verzeichnissen befassen. Doch das ist noch nicht alles was uns die Funktion
SHGetFileInfo(...) bietet. Mit Hilfe dieser Funktion können auch Icons
geladen werden die sich auf Systemobjekte wie z.B. dem Papierkorb (Recycle bin)
oder auf Drucker beziehen. Dazu muss jedoch zuvor die API-Funktion SHGetSpecialFolderLocation(...)
aufgerufen werden, um einen Zeiger auf das gewünschte Objekt zu erhalten. Diese
Funktion erhält u.a. einen Zeiger auf einen Zeiger auf eine Struktur (tolle Konstruktion!)
vom Typ ITEMIDLIST. In dieser Struktur befindet sich nach dem Ausführen der Funktion
die gewünschte Information über das Objekt. Der genaue Aufbau der Struktur braucht
uns hier nicht zu interessieren. Wir geben den erhaltenen Zeiger auf diese Struktur
einfach direkt weiter an die vorhin erwähnte Funktion SHGetFileInfo(...).
Beachten Sie nun bitte, dass im Parameter uFlags der Funktion SHGetFileInfo(...)
zusätzlich das Flag SHIGFI_PIDL jetzt gesetzt sein muss.
 |
Wenn Sie die Funktion SHGetSpecialFolderLocation(...) einsetzen,
müssen Sie explizit die Header-Datei shlobj.h
einbinden! |
 |
Erweitern wir das Beispiel wieder um die Ausgabe der Icons
für Drucker, den Papierkorb und das Netzwerk. Dazu muss zunächst in der Methode
OnInitialUpdate(...) das entsprechende Icon mit den erwähnten Funktionen
geladen werden. Beachten Sie bitte, dass Sie unbedingt die Header-Datei
shlobh.h explizit noch einbinden müssen (im Beispiel unten nicht dargestellt),
ansonsten erhalten Sie beim Übersetzen eine Fehlermeldung!
Korrigieren Sie ebenfalls die Schleife zum Löschen der Icons in der Methode
OnDestroy(...).
void CIconsView::OnInitialUpdate()
{
....
m_ahShellIcon[5] = FileInfo.hIcon;
// Lesen der Systemobjekt-Icons
LPITEMIDLIST ItemIdList;
// Drucker-Icon
SHGetSpecialFolderLocation(*this,CSIDL_PRINTERS,&ItemIdList);
::SHGetFileInfo((LPCSTR)ItemIdList,0UL,&FileInfo,
sizeof(FileInfo),SHGFI_ICON|SHGFI_PIDL);
m_ahShellIcon[6] = FileInfo.hIcon;
::SHGetFileInfo((LPCSTR)ItemIdList,0UL,&FileInfo, sizeof(FileInfo),
SHGFI_ICON|SHGFI_PIDL|SHGFI_SMALLICON);
m_ahShellIcon[7] = FileInfo.hIcon;
// Recycle Bin Icon, Icon
wird autom. angepasst (Bin leer/gefuellt)
SHGetSpecialFolderLocation(*this,CSIDL_BITBUCKET,&ItemIdList);
::SHGetFileInfo((LPCSTR)ItemIdList,0UL,&FileInfo, sizeof(FileInfo),
SHGFI_ICON|SHGFI_PIDL);
m_ahShellIcon[8] = FileInfo.hIcon;
::SHGetFileInfo((LPCSTR)ItemIdList,0UL,&FileInfo, sizeof(FileInfo),
SHGFI_ICON|SHGFI_PIDL|SHGFI_SMALLICON);
m_ahShellIcon[9] = FileInfo.hIcon;
// Netzwerk-Icon
SHGetSpecialFolderLocation(*this,CSIDL_NETWORK,&ItemIdList);
::SHGetFileInfo((LPCSTR)ItemIdList,0UL,&FileInfo,
sizeof(FileInfo),SHGFI_ICON|SHGFI_PIDL);
m_ahShellIcon[10] = FileInfo.hIcon;
}
void CIconsView::OnDestroy()
{
CView::OnDestroy();
// TODO: Code für die Behandlungsroutine für
Nachrichten hier einfügen
// System-Icons entfernen
for (int iIndex=0; iIndex<11;
iIndex++)
DestroyIcon(m_ahShellIcon[iIndex]);
} |
Die Darstellung der geladenen Icons erfolgt in der OnDraw(...) Methode
wiederum mittels der vorhin eingeführten API-Funktion DrawIconEx(...):
void CIconsView::OnDraw(CDC*
pDC)
{
....
// Folder-Icons zeichnen
....
// Drucker-Icons zeichnen
pDC->TextOut(10,170,"Drucker");
::DrawIconEx(*pDC,10,190,m_ahShellIcon[6],0,0,0,NULL,DI_NORMAL);
::DrawIconEx(*pDC,50,190,m_ahShellIcon[7],0,0,0,NULL,DI_NORMAL);
// CDROM-Icons zeichnen
pDC->TextOut(100,170,"Papierkorb");
::DrawIconEx(*pDC,100,190,m_ahShellIcon[8],0,0,0,NULL,DI_NORMAL);
::DrawIconEx(*pDC,140,190,m_ahShellIcon[9],0,0,0,NULL,DI_NORMAL);
// Netzwerk-Icon zeichnen
pDC->TextOut(190,170,"Netzwerk");
::DrawIconEx(*pDC,190,190,m_ahShellIcon[10],0,0,0,NULL,DI_NORMAL);
} |
Wenn Sie alles richtig eingegeben haben, so sollten Sie folgende Icons zusätzlich
erhalten:

|
Sie sehen, so einfach Icons Ihnen am Anfang vielleicht erschien sind, so vielfältig
sind sie in der Praxis.
Haben wir bisher nur vom System vorgegebene Icons dargestellt, so wird es nun
Zeit, selbst Icons zu entwerfen und auch darzustellen.
 |
Wechseln Sie dazu zunächst zur Ressourcen-Ansicht im Arbeitsbereich.
Klicken Sie dann in der Baumansicht den Ressource-Typ Icon mit der
rechten Maustaste an. Daraufhin wird ein Kontext-Menü eingeblendet. Sie können
durch Auswahl des Menüpunkts Icon einfügen nun selbst ein neues Icon
erstellen oder, wenn Sie genauso wie der Autor grafisch weniger begabt sind,
ein bestehendes Icon importieren. Wählen Sie dazu den Menüpunkt Importieren...
aus. Im Verzeichnis 99Templates befindet sich die Icon-Datei MyIcon.ico
die Sie hier z.B. importieren können. Dieses Icon wird dann im Icon-Editor mit
der Standard-Auflösung 32x32 dargestellt. Zusätzlich enthält dieses Icon auch
noch eine Darstellung für die Auflösung 16x16. Sie können sich diese Darstellung
ansehen, in dem Sie im Auswahlfeld Gerät (oberhalb des Editorfensters)
die entsprechende Auflösung auswählen.
 |
Wollen Sie ein eigenes Icon entwerfen, so wird im Icon-Editor
zunächst das Icon mit der Standard-Auflösung 32x32 dargestellt. Um auch
ein kleines Icon mit der Auflösung 16x16 zu erstellen, klicken Sie bitte
den Button neben dem Auswahlfeld Gerät an. Danach wird folgender
Dialog eingeblendet:

Wählen Sie dort unter Zielgerät den Eintrag Klein (16x16)
aus um ein kleines Icon zu erstellen.
|
Haben Sie das Icon erstellt bzw. importiert, so besitzt es standardmäßig
die ID IDI_ICONx. Um diese nicht gerade aussagekräftige ID zu ändern, klicken
Sie die ID in der Baumansicht mit der rechten Maustaste an und wählen im dann
eingeblendeten Kontext-Menü den Eintrag Eigenschaften aus. Danach wird
folgender Dialog eingeblendet:

Überschreiben Sie die (markierte) ID IDI_ICON1 mit IDI_USER um dem Icon diese
ID für das Beispiel zuzuweisen.
 |
Es hat sich als Quasi-Standard eingebürgert, IDs für Icons immer mit
IDI_xxx beginnen zu lassen |
|
Damit haben Sie Ihr erstes Icon erstellt bzw. kopiert. Später im Kurs, bei den
Tipps&Tricks, werden wir nochmals auf die Erstellung von Icons zurückkommen. Was
uns zum Schluss jetzt nur noch fehlt, ist das Laden und Anzeigen unseres Icons.
Außerdem werden wir im Beispiel noch ein Icon einer WINDOWS-Anwendung, das des NOTEPAD,
laden und anzeigen.
 |
Vervollständigen wir das Beispiel noch. Als erstes laden wir
die gewünschten Icons wiederum in der Methode OnInitialUpdate(...).
void CIconsView::OnInitialUpdate()
{
// Netzwerk-Icon
....
// Grosses Icon aus Ressource
laden
m_hUserLarge = AfxGetApp()->LoadIcon(IDI_USER);
// Kleines Icon aus Ressource
laden
// Beachten Sie die Groessenangaben beim Aufruf!
m_hUserSmall = (HICON)::LoadImage(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDI_USER),
IMAGE_ICON, 16,16, LR_DEFAULTCOLOR);
// Lesen eines Applikations-Icons
(hier NOTEPAD-Icon)
// Eventl. muessen Sie hier den Pfad noch anpassen!
::SHGetFileInfo("C:\\WINDOWS\\NOTEPAD.EXE",
0UL, &FileInfo,sizeof(FileInfo),SHGFI_ICON);
m_hAppLarge = FileInfo.hIcon;
} |
Anschließend fügen Sie der Klasse CIconsView auch noch die drei
Membervariablen m_hUserLarge, m_hUserSmall und m_hAppLarge,
alle vom Typ HICON, hinzu.
Beachten Sie im Beispiel oben bitte, dass Ressource-Icons, die von der Standard-Auflösung
32x32 abweichen, immer mit der API-Funktion LoadImage(...) geladen
werden müssen. Außerdem ist hier in der Regel die Auflösung des zu ladenden
Icons anzugeben.
Zum Schluss werden die geladenen Icons noch in der OnDraw(...) Methode
ausgegeben.
void CIconsView::OnDraw(CDC*
pDC)
{
....
// Netzwerk-Icon zeichnen
....
// Grosses Ressource-Icon
zeichnen
pDC->TextOut(10,250,"Ressourcen");
pDC->DrawIcon(10,270,m_hUserLarge);
// Kleines Ressource-Icon
zeichnen
::DrawIconEx(*pDC,50,270,m_hUserSmall,0,0,0,NULL,DI_NORMAL);
// NOTEPAD-Icon zeichen
pDC->TextOut(100,250,"NOTEPAD");
pDC->DrawIcon(100,270,m_hAppLarge);
} |
Damit sollten Sie nun folgende Icons zusätzlich angezeigt bekommen:

Und wird sind damit auch fertig. Das fertige Beispiel finden
Sie auch unter 07Ressourcen\Icons.
|
Beenden wir diese Lektion über Icon-Ressourcen und sehen uns in der nächsten
Lektion die Cursor-Ressource an.
|