// TrayIcon.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#define NUM_ICON_FOR_ANIMATION 8
#define MAX_LOADSTRING 100
#define MYMSG_NOTIFYICON (WM_APP + 100)
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
HWND hWindowHandle;
// Global Vraibles
// Keep track of the last displayed icon
int nCounter;
// List of Icon that is created and to be animated
static int IconResourceArray[NUM_ICON_FOR_ANIMATION] = {IDI_ICON8, IDI_ICON7, IDI_ICON6, IDI_ICON5, IDI_ICON4, IDI_ICON3, IDI_ICON2, IDI_ICON1};
// Current icon displayed index values.
static m_nCounter = 0;
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
VOID AnimateIcon(HINSTANCE hInstance, HWND hWnd, DWORD dwMsgType,UINT nIndexOfIcon);
VOID TimerAnimationIcon(HINSTANCE hInst, HWND hWnd);
LONG OnTrayNotification(HINSTANCE hInstance, HWND hWnd, WPARAM wParam, LPARAM lParam);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TRAYICON, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TRAYICON);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TRAYICON);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_TRAYICON;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_TRAYICON);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Add icon on system tray during initialzation
AnimateIcon(hInstance, hWnd, NIM_ADD, 0);
// Set a timer functionality to animate the icon in a certain interval
SetTimer(hWnd, 1, 500, NULL);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_EXIT:
case ID_FILE_KILLPROCESS:
DestroyWindow(hWnd);
break;
case ID_TRAYICON_MINIMISE:
ShowWindow(hWnd, SW_MINIMIZE);
break;
case ID_TRAYICON_HIDEWINDOW:
ShowWindow(hWnd, SW_HIDE);
break;
case ID_TRAYICON_MAXIMIZEWINDOW:
ShowWindow(hWnd, SW_MAXIMIZE);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_CLOSE:
case WM_DESTROY:
case WM_QUIT:
KillTimer(hWnd, 1);
AnimateIcon(hInst, hWnd, NIM_DELETE, m_nCounter);
PostQuitMessage(0);
break;
case WM_TIMER:
TimerAnimationIcon(hInst, hWnd);
case MYMSG_NOTIFYICON:
// System Tray Icon notification will be executed..
OnTrayNotification(hInst, hWnd, wParam, lParam);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
/* Function Name : TimerAnimationIcon
Description : Function which will keep track of the current displayed icons, based on that
this will select the next icon to be displayed by sending a modify message type
to the system tray icon.
Function Called : AnimateIcon
Global Variable : m_nCounter - Keep track of the icon which is currently dispalyed
nCounter - Incremented one by one to select the next icon from the icon list.
*/
VOID TimerAnimationIcon(HINSTANCE hInst, HWND hWnd)
{
AnimateIcon(hInst, hWnd, NIM_MODIFY, nCounter);
m_nCounter = nCounter; //Store it here to keep track of the last displayed icon
nCounter++;
nCounter = nCounter%(NUM_ICON_FOR_ANIMATION);
}
/* Function Name : AnimateIcon
Description : Function which will act based on the message type that is received as parameter
like ADD, MODIFY, DELETE icon in the system tray. Also send a message to display
the icon in title bar as well as in the task bar application.
Function Called : Shell_NotifyIcon - API which will Add, Modify, Delete icon in tray.
SendMessage - Send a message to windows
Variable : NOTIFYICONDATA - Structure which will have the details of the tray icons
*/
void AnimateIcon(HINSTANCE hInstance, HWND hWnd, DWORD dwMsgType,UINT nIndexOfIcon)
{
HICON hIconAtIndex = LoadIcon(hInstance, (LPCTSTR) MAKEINTRESOURCE(IconResourceArray[nIndexOfIcon]));
NOTIFYICONDATA IconData;
IconData.cbSize = sizeof(NOTIFYICONDATA);
IconData.hIcon = hIconAtIndex;
IconData.hWnd = hWnd;
lstrcpyn(IconData.szTip,"Animated System Tray Icons", (int) strlen("Animated System Tray Icons")+1);
IconData.uCallbackMessage = MYMSG_NOTIFYICON;
IconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
Shell_NotifyIcon(dwMsgType, &IconData);
SendMessage(hWnd, WM_SETICON, NULL, (long) hIconAtIndex);
if(hIconAtIndex)
DestroyIcon(hIconAtIndex);
}
/* Function Name : OnTrayNotification
Description : CALLBACK routine which will be get executed when a notification is identified on the
system tray.
Function Called : LoadMenu - Load the menu into the application
*/
LONG OnTrayNotification(HINSTANCE hInstance, HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HMENU hMenu;
switch(lParam)
{
case WM_RBUTTONDOWN:
{
/** Load and verify the menu**/
if(hMenu = LoadMenu(hInstance, (LPCTSTR) MAKEINTRESOURCE(IDC_TRAYICON)))
{
hMenu = GetSubMenu(hMenu, 0);
if(hMenu != NULL)
{
POINT pt;
GetCursorPos(&pt);
SetForegroundWindow(hWnd);
TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hWnd, NULL);
}
}
break ;
}
}
return 0;
}