System Tray

  • Автор темы solova
  • Дата начала
S

solova

#1
Делаю в MFC
собсна нужно заменить иконку в трее
с IDI_ICON1 на IDI_ICON2
вот как всё происходит
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Mydlg.h</div></div><div class="sp-body"><div class="sp-content">
C++:
class CMyDlg : public CDialog
{
public:
NOTIFYICONDATA nf;//чтоб по сто раз не объявлять
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">MyDlg.cpp</div></div><div class="sp-body"><div class="sp-content">
C++:
#define WM_MYICONNOTIFY	(WM_USER+1)
BEGIN_MESSAGE_MAP(CTest2Dlg, CDialog)
ON_WM_SYSCOMMAND()
ON_MESSAGE(WM_MYICONNOTIFY,&CMyDlg::DelIcon)
END_MESSAGE_MAP()
BOOL CMyDlg::OnInitDialog()
{
nf.cbSize = sizeof(&nf);
nf.hWnd = m_hWnd;
nf.uCallbackMessage = WM_MYICONNOTIFY;
return TRUE;
}
void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0)==SC_CLOSE)		//при нажатие на крестик
{
wchar_t textup[]=L"Программа работает";
nf.uID = NULL;					///!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
nf.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;

wcscpy_s(nf.szTip,sizeof(nf.szTip),textup);

HICON hIcon;
hIcon=AfxGetApp()->LoadIcon(IDI_ICON1);
nf.hIcon = hIcon;
Shell_NotifyIcon(NIM_ADD,&nf);
ShowWindow(SW_HIDE);
//OnClose();
}
//CDialog::OnSysCommand(nID, lParam);
}
LRESULT CMyDlg::DelIcon(WPARAM wParam, LPARAM lParam)
{
if (lParam==WM_LBUTTONDBLCLK)
{
Shell_NotifyIcon(NIM_DELETE,&nf);
ShowWindow(SW_RESTORE);
}
return 0;
}
//вот кнопка каторая должна поменять иконку и надпись
void CMyDlg::OnBnClickedButton1()
{
wchar_t texticon[]=L"Иконка заменена";
nf.uFlags = NIF_ICON | NIF_TIP;
wcscpy_s(nf.szTip,sizeof(nf.szTip),textup);
//а зачем вообще nf.uID				///!!!!!!!!!!!!!!!!!!!!!!!!!!!
//и иконку просто заново загрузить или как то nf.uID можно использовать?
// и я понимаю что вторую иконку всё равно надо загружать в проект,
//но может как то с помощью uID можно менять(а то зачем он нужен)
"HICON hIcon;"
"hIcon=AfxGetApp()->LoadIcon(IDI_ICON2);"
"nf.hIcon = hIcon;"
Shell_NotifyIcon(NIM_MODIFY,&nf);
}
ну вот собсна uID мне покоя не даёт
 

lazybiz

Well-known member
03.11.2010
1 339
0
#2
Перенеси nf.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; в BOOL CMyDlg::OnInitDialog()
Из void CMyDlg::OnBnClickedButton1() удали nf.uFlags = NIF_ICON | NIF_TIP;

uID

Type: UINT

The application-defined identifier of the taskbar icon. The Shell uses either (hWnd plus uID) or guidItem to identify which icon to operate on when Shell_NotifyIcon is invoked. You can have multiple icons associated with a single hWnd by assigning each a different uID. If guidItem is specified, uID is ignored.
uID - это произвольный идентификатор иконки. Нужен в том случае если иконок в трее должно быть более чем одна.
Т.е., для указания иконки служат hWnd + uID или guidItem. guidItem ты не используешь но используешь окно, значит параметр uID тебе необходим. Если у тебя в трее должна быть только одна иконка можешь выставить uID = 0;

А так все должно работать на первый взгляд.
 
S

solova

#3
Нужен в том случае если иконок в трее должно быть более чем одна.
ну во, а я думал это надо если несколько иконок используется для одного окна в трее. спасибо
да и что то я NIF_MESSAGE упустил в баттоне (без него же калбак не будет учитываться)
 

lazybiz

Well-known member
03.11.2010
1 339
0
#4
Вот для понимания простой рабочий пример:
C++:
#define	WINVER			0x0600
#define	_WIN32_IE		0x0800
#define	NTDDI_VERSION	0x06000000

#include <windows.h>

#define		W				320
#define		H				240

char			g_szWindowName[]	= "test";
char			g_szWindowClass[]	= "test32";
HWND		g_hWnd;

#define		WM_TBAR_NOTIFY	(WM_USER + 0x1234)
#define		ICON_ID			0x1234

void tray_init()
{
NOTIFYICONDATA	nid;
ZeroMemory( &nid, NOTIFYICONDATA_V2_SIZE );
nid.cbSize				= NOTIFYICONDATA_V2_SIZE;
nid.hWnd				= g_hWnd;
nid.uID				= ICON_ID;
nid.uFlags				= NIF_ICON | NIF_MESSAGE | NIF_INFO | NIF_TIP;
nid.uCallbackMessage		= WM_TBAR_NOTIFY;
nid.hIcon				= LoadIcon( NULL, IDI_EXCLAMATION );

strcpy( nid.szTip, "Tip #1\nTip #2\nTip #3" );
strcpy( nid.szInfo, "Test" );
strcpy( nid.szInfoTitle, "Test Title" );

nid.uTimeout			= 5000;
nid.dwInfoFlags			= NIIF_USER;
nid.hBalloonIcon			= LoadIcon( NULL, IDI_WINLOGO );
Shell_NotifyIcon( NIM_ADD, &nid ); // добавляю первую иконку

nid.uID				= ICON_ID + 1;
nid.hIcon				= LoadIcon( NULL, IDI_HAND );
Shell_NotifyIcon( NIM_ADD, &nid ); // добавляю вторую иконку
}

void tray_destroy()
{
NOTIFYICONDATA	nid;
ZeroMemory( &nid, NOTIFYICONDATA_V2_SIZE );
nid.cbSize				= NOTIFYICONDATA_V2_SIZE;
nid.hWnd				= g_hWnd;
nid.uID				= ICON_ID;
Shell_NotifyIcon( NIM_DELETE, &nid ); // удаляю первую иконку

nid.uID				= ICON_ID + 1;
Shell_NotifyIcon( NIM_DELETE, &nid ); // удаляю вторую иконку
}

static LRESULT CALLBACK wnd_proc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch ( uMsg ) {
case WM_KEYDOWN: if ( (int)wParam != VK_ESCAPE ) break;
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}

int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
MSG			msg;
WNDCLASS	wc;

memset( &wc, 0, sizeof( WNDCLASS ) );
wc.style			= CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc		= wnd_proc;
wc.hInstance		= hInst;
wc.lpszClassName	= g_szWindowClass;
wc.hCursor		= LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground	= (HBRUSH)GetStockObject( WHITE_BRUSH );
RegisterClass( &wc );

g_hWnd = CreateWindow(
g_szWindowClass, g_szWindowName, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
(GetSystemMetrics( SM_CXSCREEN ) >> 1) - (W >> 1),
(GetSystemMetrics( SM_CYSCREEN ) >> 1) - (H >> 1),
W, H, NULL, NULL, hInst, NULL );

tray_init();

while ( GetMessage( &msg, NULL, 0, 0 ) ) {
TranslateMessage( &msg );
DispatchMessage( &msg );
}

tray_destroy();

DestroyWindow( g_hWnd );
UnregisterClass( g_szWindowClass, hInst );
return 0;
}
 

Вложения

  • 12.1 КБ Просмотры: 6
S

solova

#5
ну если я ранее всё понял то в этом примере будет две иконки в трее (теперь уж точно ясно).
и в моём случае(нужна одна) nid.uID можно и не менять, а только nid.hIcon.
а вот
C++:
(GetSystemMetrics( SM_CXSCREEN ) >> 1) - (X >> 1),
GetSystemMetrics() берёт размер экрана , а что дальше означают эти ">>" и что вообще эти строки делают(типа окно по центру ставят?)
 

lazybiz

Well-known member
03.11.2010
1 339
0
#6
Да, чтобы по центру было.
Беру размер экрана, делю его на два и отнимаю пол окна.