void CShellAnimDlg:: InstallAnimatedIcon (
DWORD dwMsgType,
UINT nIndexOfIcon,
CString strToolTip)
Im ersten Schritt lädt die Methode das erforderliche Symbol aus dem Array.
{
HICON hIconAtIndex = AfxGetApp()->LoadIcon(
iconResourceArray[nIndexOfIcon]);
Als nächstes ist die NOTIFYICONDATA-Struktur zu initialisieren. Zu setzen sind in hWnd das Fensterhandle und in uID der Identifier des Symbols. In uFlags werden drei Standardflags zugewiesen, die neben dem Symbol und dem Tooltip auch die benutzerdefinierte Nachricht anzeigen, deren Wert in uCallbackMessage steht. Das Handle des Symbols steht schließlich in hIcon.
NOTIFYICONDATA iconData;
iconData.cbSize = sizeof(NOTIFYICONDATA);
iconData.hWnd = GetSafeHwnd();
iconData.uID = 100 ;
iconData.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
iconData.uCallbackMessage = MYMSG_NOTIFYICON;
iconData.hIcon = hIconAtIndex;
Der Tooltip wird wie folgt behandelt:
LPCTSTR lpszToolTip = strToolTip.GetBuffer(
strToolTip.GetLength());
lstrcpyn(iconData.szTip,lpszToolTip,strlen(lpszToolTip)+1);
Die letzte zu übernehmende Information legt fest, was der Aufruf von Shell_NotifyIcon() bewirken soll, und wird in dwMsgType übergeben.
Shell_NotifyIcon(dwMsgType, &iconData);
Abschließend sind noch die Ressourcen wieder freizugeben.
if (hIconAtIndex)
DestroyIcon(hIconAtIndex);
}
Schritt 3: Animation des Symbols
Der Beginn der Animation erfolgt sinnvollerweise in der Methode OnInitDialog() mit dem ersten Symbol des Arrays, das durch NIM_ADD hinzugefügt wird, während nachfolgende Aufrufe dann über NIM_MODIFY das Symbol ändern.
BOOL CShellAnimDlg::OnInitDialog()
{
CDialog::OnInitDialog();
int nIndexFirstIcon = 0;
InstallAnimatedIcon(NIM_ADD, nIndexFirstIcon,
strToolTipArray[nIndexFirstIcon]);
Ebenfalls in OnInitDialog() wird ein Timer gesetzt, dessen Ereignis dann zum Animieren des Symbols verwendet werden kann.
SetTimer(1,1000,NULL);
return TRUE;
}
Den aktuellen Index in das Array der Symbole verwaltet das Static-Member nCounter, das zunächst mit 0 vorbelegt und anschließend mit jedem Aufruf der Methode OnTimer() hochgezählt wird, bis NUM_ICONS_IN_ANIMATION erreicht ist und wieder bei Symbol 0 angefangen wird.
void CShellAnimDlg::OnTimer(UINT nIDEvent)
{
static int nCounter = 0;
InstallAnimatedIcon(NIM_MODIFY, nCounter,
strToolTipArray[nCounter]);
m_nCounter = nCounter;
nCounter++;
nCounter = nCounter%( NUM_ICONS_IN_ANIMATION);
CDialog::OnTimer(nIDEvent);
}
Es bleibt anzumerken, daß es notwendig sein kann, das letzte Symbol selbst zu löschen, wenn die Anwendung schließt. Es sollte daher sichergestellt werden, daß beim Schließen der Anwendung die folgenden Zeilen Code ausgeführt werden:
KillTimer(1);
InstallAnimatedIcon(NIM_DELETE,m_nCounter,"")
Schritt 4: Behandlung der Benachrichtigungen
Als letzter Schritt ist das Handling der Benachrichtigungen auf Mausereignisse zu implementieren. Dazu wurde die benutzerdefinierte Nachricht MYMSG_NOTIFYICON installiert, die für Callback-Benachrichtigungen verwendet wird. Für jede Aktion, die der Anwender auf dem Symbol ausführt, sendet die Shell eine Nachricht. Da hier nur Mausnachrichten interessieren, brauchen die übrigen nicht behandelt zu werden. Zunächst ist also ein Message-Handler zu erzeugen ...
afx_msg void OnHandleIconNotify(UINT wParam, LONG lParam);
... sowie zusätzlich das Mapping der Nachricht auf die entsprechende Funktion.
ON_MESSAGE(MYMSG_NOTIFYICON, OnHandleIconNotify)
Die Methode OnHandleIconNotify() besitzt dann folgenden Aufbau:
|