FAQ:WinAPI VCPP:иконка в области уведомлений (системном трее) — различия между версиями

Материал из Весельчак У
Перейти к: навигация, поиск
м (одно документное --пропущен пробел.)
 
(не показана 1 промежуточная версия 1 участника)
Строка 4: Строка 4:
 
Например, сделаем так, чтобы, по нажатию кнопки меню, окно программы сворачивалось в
 
Например, сделаем так, чтобы, по нажатию кнопки меню, окно программы сворачивалось в
 
трей (иконка сначала недолго поморгает), а при щелчке левой кнопкой мыши по иконке -
 
трей (иконка сначала недолго поморгает), а при щелчке левой кнопкой мыши по иконке -
разворачивалось к предыдущему состоянию. В примере использовано однодокументное
+
разворачивалось к предыдущему состоянию. В примере использовано одно документное
 
приложение (MDI), поэтому "всё происходит" в классе CMainFrame. Переписать для CDialog
 
приложение (MDI), поэтому "всё происходит" в классе CMainFrame. Переписать для CDialog
 
и вообще для любого случая - несложно.
 
и вообще для любого случая - несложно.
Строка 12: Строка 12:
 
class CMainFrame : public CFrameWnd
 
class CMainFrame : public CFrameWnd
 
{
 
{
//переменная для сохранения состояния окна до сворачивания.
+
// переменная для сохранения состояния окна до сворачивания.
//"Запоминаем" сюда значения SW_MAXIMIZE или SW_RESTORE
+
// "Запоминаем" сюда значения SW_MAXIMIZE или SW_RESTORE
 
DWORD m_dwdTrayShowCMD;
 
DWORD m_dwdTrayShowCMD;
 
 
//определяем константы
+
// определяем константы
 
enum
 
enum
 
{
 
{
//идентификатор иконки приложения в трее.
+
// идентификатор иконки приложения в трее.
//не путать с ID ресурса иконки!!!
+
// не путать с ID ресурса иконки!!!
e_tray_ID=1000,
+
e_tray_ID = 1000,
e_tray_ID_1=1001, //(ID второй иконки для анимации)
+
e_tray_ID_1 = 1001, //(ID второй иконки для анимации)
e_tray_MSG=WM_COMMAND,//сообщение, посылаемое из трея
+
e_tray_MSG = WM_COMMAND, //сообщение, посылаемое из трея
 
};
 
};
...
+
 
...
+
// это добавит визард ->
//это добавит визард ->
+
 
 
 
// Overrides
 
// Overrides
 
// ClassWizard generated virtual function overrides
 
// ClassWizard generated virtual function overrides
 
//{{AFX_VIRTUAL(CMainFrame)
 
//{{AFX_VIRTUAL(CMainFrame)
...
+
 
...
+
 
protected:
 
protected:
 
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
 
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
Строка 42: Строка 40:
 
CMainFrame::CMainFrame()
 
CMainFrame::CMainFrame()
 
{
 
{
m_dwdTrayShowCMD=SW_MAXIMIZE;
+
m_dwdTrayShowCMD = SW_MAXIMIZE;
 
}
 
}
</pre>
+
</syntaxhighlight>
<pre>
+
<syntaxhighlight lang="cpp">
//обработчик кнопки меню "свернуть в трей" (ID_PUTTOTRAY)
+
// обработчик кнопки меню "свернуть в трей" (ID_PUTTOTRAY)
 
void CMainFrame::OnPuttotray()
 
void CMainFrame::OnPuttotray()
 
{
 
{
//"запоминаем", какой командой потом разворачивать окно
+
// "запоминаем", какой командой потом разворачивать окно
m_dwdTrayShowCMD=((GetStyle()&WS_MAXIMIZE)?SW_MAXIMIZE:SW_RESTORE);
+
m_dwdTrayShowCMD = ((GetStyle() & WS_MAXIMIZE) ? SW_MAXIMIZE : SW_RESTORE);
 
 
//заполняем структуру NOTIFYICONDATA для иконки
+
// заполняем структуру NOTIFYICONDATA для иконки
NOTIFYICONDATA ndata=
+
NOTIFYICONDATA ndata =
 
{
 
{
//размер структуры
+
sizeof(NOTIFYICONDATA), // размер структуры
sizeof(NOTIFYICONDATA),
+
m_hWnd, // хендл этого окна
//хендл этого окна
+
e_tray_ID, // идентификатор иконки трея в приложении
m_hWnd,
+
NIF_ICON | NIF_MESSAGE | NIF_TIP, // опции: есть иконка, есть сообщение, есть надпись
//идентификатор иконки трея в приложении
+
e_tray_MSG, // сообщение, посылаемое иконкой из трея (сейчас == WM_COMMAND)
e_tray_ID,
+
::AfxGetApp()->LoadIcon(IDR_MAINFRAME), // иконка из ресурсов
//опции: есть иконка, есть сообщение, есть надпись
+
"Значок моей программы" // всплывающая надпись
NIF_ICON|NIF_MESSAGE|NIF_TIP,
+
//сообщение, посылаемое иконкой из трея (сейчас == WM_COMMAND)
+
e_tray_MSG,
+
//иконка из ресурсов
+
::AfxGetApp()->LoadIcon(IDR_MAINFRAME),
+
//всплывающая надпись
+
"Значок моей программы"
+
 
};
 
};
 
 
//заполняем структуру NOTIFYICONDATA для "пустой" иконки
+
// заполняем структуру NOTIFYICONDATA для "пустой" иконки
NOTIFYICONDATA ndata1=ndata;
+
NOTIFYICONDATA ndata1 = ndata;
ndata1.hIcon=0;
+
ndata1.hIcon = 0;
 
 
//скрываем окно программы
+
// скрываем окно программы
 
ShowWindow(SW_HIDE);
 
ShowWindow(SW_HIDE);
 
 
//добавляем значок e_tray_ID в трей
+
// добавляем значок e_tray_ID в трей
Shell_NotifyIcon(NIM_ADD,&ndata);
+
Shell_NotifyIcon(NIM_ADD, &ndata);
 
 
//"моргаем" 4 раза
+
// "моргаем" 4 раза
for(int i=0;i<4;i++)
+
for (int i = 0; i < 4; i++)
 
{
 
{
//заменяем значок в трее пустым
+
// заменяем значок в трее пустым
Shell_NotifyIcon(NIM_MODIFY,&ndata1);
+
Shell_NotifyIcon(NIM_MODIFY, &ndata1);
 
Sleep(70);
 
Sleep(70);
 
 
//возвращаем обратно иконку
+
// возвращаем обратно иконку
Shell_NotifyIcon(NIM_MODIFY,&ndata);
+
Shell_NotifyIcon(NIM_MODIFY, &ndata);
 
Sleep(70);
 
Sleep(70);
 
}
 
}
Строка 97: Строка 88:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Добавим обработчик для команды e_tray_MSG (==WM_COMMAND) - переопределим виртуальную функцию
+
Добавим обработчик для команды e_tray_MSG (WM_COMMAND) - переопределим виртуальную функцию
  
 
BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)
 
BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)
Строка 104: Строка 95:
 
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)  
 
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)  
 
{
 
{
//определяем, что сообщение от иконки e_tray_ID
+
// определяем, что сообщение от иконки e_tray_ID
if(wParam==e_tray_ID)
+
if (wParam == e_tray_ID)
 
{
 
{
//определяем, какое действие мышью произвели
+
// определяем, какое действие мышью произвели
switch(lParam)
+
switch (lParam)
 
{
 
{
 
case WM_LBUTTONDOWN:
 
case WM_LBUTTONDOWN:
 
{
 
{
//показываем окно ("запомненной" командой)
+
// показываем окно ("запомненной" командой)
 
ShowWindow(m_dwdTrayShowCMD);
 
ShowWindow(m_dwdTrayShowCMD);
 
 
//заполняем структуру для удаления иконки
+
// заполняем структуру для удаления иконки
NOTIFYICONDATA ndata=
+
NOTIFYICONDATA ndata =
 
{
 
{
 
sizeof(NOTIFYICONDATA),
 
sizeof(NOTIFYICONDATA),
Строка 123: Строка 114:
 
};
 
};
 
 
//удаляем иконку
+
// удаляем иконку
Shell_NotifyIcon(NIM_DELETE,&ndata);
+
Shell_NotifyIcon(NIM_DELETE, &ndata);
 
}
 
}
 
break;
 
break;
Строка 130: Строка 121:
 
case WM_MOUSEMOVE:
 
case WM_MOUSEMOVE:
 
{
 
{
//по иконке двигался курсор
+
// по иконке двигался курсор
 
}
 
}
 
break;
 
break;
 
 
case WM_LBUTTONUP:{}break;
+
case WM_LBUTTONUP: {} break;
case WM_LBUTTONDBLCLK:{}break;
+
case WM_LBUTTONDBLCLK: {} break;
case WM_RBUTTONDOWN:{}break;
+
case WM_RBUTTONDOWN: {} break;
case WM_RBUTTONUP:{}break;
+
case WM_RBUTTONUP: {} break;
case WM_RBUTTONDBLCLK:{}break;
+
case WM_RBUTTONDBLCLK: {} break;
case WM_MBUTTONDOWN:{}break;
+
case WM_MBUTTONDOWN: {} break;
case WM_MBUTTONUP:{}break;
+
case WM_MBUTTONUP: {} break;
case WM_MBUTTONDBLCLK:{}break;
+
case WM_MBUTTONDBLCLK: {} break;
 
}
 
}
 
 
//сообщение обработано
+
// сообщение обработано
 
return 1;
 
return 1;
 
}
 
}

Текущая версия на 11:11, 7 августа 2008

Как создать иконку в области уведомлений (системном трее)? Как определить, какие действия производит с иконкой пользователь? Как сделать анимацию иконки в трее? Как удалить иконку?

Для всего этого - использовать процедуру API Shell_NotifyIcon(). Например, сделаем так, чтобы, по нажатию кнопки меню, окно программы сворачивалось в трей (иконка сначала недолго поморгает), а при щелчке левой кнопкой мыши по иконке - разворачивалось к предыдущему состоянию. В примере использовано одно документное приложение (MDI), поэтому "всё происходит" в классе CMainFrame. Переписать для CDialog и вообще для любого случая - несложно.

//определение класса CMainFrame
class CMainFrame : public CFrameWnd
{
	// переменная для сохранения состояния окна до сворачивания.
	// "Запоминаем" сюда значения SW_MAXIMIZE или SW_RESTORE
	DWORD m_dwdTrayShowCMD;
 
	// определяем константы
	enum
	{
		// идентификатор иконки приложения в трее.
		// не путать с ID ресурса иконки!!!
		e_tray_ID = 1000,	
		e_tray_ID_1 = 1001,	 //(ID второй иконки для анимации)
		e_tray_MSG = WM_COMMAND, //сообщение, посылаемое из трея
	};
 
	// это добавит визард ->
 
// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CMainFrame)
 
	protected:
	virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
	//}}AFX_VIRTUAL
};
 
//конструктор
CMainFrame::CMainFrame()
{
	m_dwdTrayShowCMD = SW_MAXIMIZE;
}
// обработчик кнопки меню "свернуть в трей" (ID_PUTTOTRAY)
void CMainFrame::OnPuttotray()
{
	// "запоминаем", какой командой потом разворачивать окно
	m_dwdTrayShowCMD = ((GetStyle() & WS_MAXIMIZE) ? SW_MAXIMIZE : SW_RESTORE);
 
	// заполняем структуру NOTIFYICONDATA для иконки
	NOTIFYICONDATA ndata =
	{
		sizeof(NOTIFYICONDATA), // размер структуры
		m_hWnd, // хендл этого окна
		e_tray_ID, // идентификатор иконки трея в приложении
		NIF_ICON | NIF_MESSAGE | NIF_TIP, // опции: есть иконка, есть сообщение, есть надпись
		e_tray_MSG, // сообщение, посылаемое иконкой из трея (сейчас == WM_COMMAND)
		::AfxGetApp()->LoadIcon(IDR_MAINFRAME), // иконка из ресурсов
		"Значок моей программы" // всплывающая надпись
	};
 
	// заполняем структуру NOTIFYICONDATA для "пустой" иконки
	NOTIFYICONDATA ndata1 = ndata;
	ndata1.hIcon = 0;
 
	// скрываем окно программы
	ShowWindow(SW_HIDE);
 
	// добавляем значок e_tray_ID в трей
	Shell_NotifyIcon(NIM_ADD, &ndata);
 
	// "моргаем" 4 раза
	for (int i = 0; i < 4; i++)
	{
		// заменяем значок в трее пустым
		Shell_NotifyIcon(NIM_MODIFY, &ndata1);
		Sleep(70);
 
		// возвращаем обратно иконку
		Shell_NotifyIcon(NIM_MODIFY, &ndata);
		Sleep(70);
	}
 
	return;
}

Добавим обработчик для команды e_tray_MSG (WM_COMMAND) - переопределим виртуальную функцию

BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)

BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) 
{
	// определяем, что сообщение от иконки e_tray_ID
	if (wParam == e_tray_ID)
	{
		// определяем, какое действие мышью произвели
		switch (lParam)
		{
			case WM_LBUTTONDOWN:
			{
				// показываем окно ("запомненной" командой)
				ShowWindow(m_dwdTrayShowCMD);
 
				// заполняем структуру для удаления иконки
				NOTIFYICONDATA ndata =
				{
					sizeof(NOTIFYICONDATA),
					m_hWnd,
					e_tray_ID
				};
 
				// удаляем иконку
				Shell_NotifyIcon(NIM_DELETE, &ndata);
			}
			break;
 
			case WM_MOUSEMOVE:
			{
				// по иконке двигался курсор
			}
			break;
 
			case WM_LBUTTONUP: {} break;
			case WM_LBUTTONDBLCLK: {} break;
			case WM_RBUTTONDOWN: {} break;
			case WM_RBUTTONUP: {} break;
			case WM_RBUTTONDBLCLK: {} break;
			case WM_MBUTTONDOWN: {} break;
			case WM_MBUTTONUP: {} break;
			case WM_MBUTTONDBLCLK: {} break;
		}
 
		// сообщение обработано
		return 1;
	}
 
	return CFrameWnd::OnCommand(wParam, lParam);
}