Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Поместить значок в трей....


Автор: Doc_d0s 3.8.2006, 00:00
Вопрос собственно отмечен в заголовке темы, желательно тексты программ)

Автор: 586 3.8.2006, 01:33
Код
#include <windows.h>

NOTIFYICONDATA nid;
BYTE hidden=0;
BYTE ic=0;    // присутствие иконки

int __stdcall MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, long lParam)
{
    switch(uMsg)
    {
    case WM_CLOSE:
        EndDialog(hWnd, 0);
        break;
    case WM_COMMAND:
        switch(LOWORD(wParam))
        {
        case 1000:    // кнопка "создать значок"
            if(ic) break;
            nid.cbSize=sizeof(NOTIFYICONDATA);        // размер структуры
            nid.hIcon=LoadIcon(0, IDI_EXCLAMATION);    // значок
            nid.hWnd=hWnd;                            // хендл скрываемого окна
            strcpy(nid.szTip,"Hello world");        // подсказка к значку
            nid.uCallbackMessage=WM_USER+1;            // сообщение uMsg
            nid.uID=0;                                // идентификатор иконки
            nid.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;  // флаги
            Shell_NotifyIcon(NIM_ADD, &nid);
            ic=1;
            break;
        case 1001:    // кнопка "скрыть окно"
            if(ic)
            {
                ShowWindow(hWnd, 0);
                hidden=1;
            } else MessageBeep(0);
            break;
        case 1002:    // кнопка "удалить значок"
            if(!ic) break;
            Shell_NotifyIcon(NIM_DELETE, &nid);    // удаление
            ic=0;
            break;                
        }
        break;
    case WM_USER+1:    // сообщения значка
        switch(lParam)
        {
        case WM_LBUTTONDOWN:
            if(hidden)
                ShowWindow(hWnd, 5);    // показать
            else
                ShowWindow(hWnd, 0);    // скрыть
            hidden^=1;
            break;
        }
        break;
    }
    return 0;
}

int __stdcall WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, INT)
{
    DialogBoxParam(hinst, (char*)1000, 0, MainWndProc, 0);
    return 0;
}

Автор: MoZy 4.8.2006, 19:43
Вот, сам давно пользуюсь (кстати нашеля я это в МАПИ):
Код

#define WM_TRAYCLICK    17

....

BOOL DelTaskIcon(HWND hwnd, UINT uID)
{ 
    BOOL res; 
    NOTIFYICONDATA tnid; 
 
    tnid.cbSize = sizeof(NOTIFYICONDATA); 
    tnid.hWnd = hwnd; 
    tnid.uID = uID; 
         
    res = Shell_NotifyIcon(NIM_DELETE, &tnid); 

    return res;

}

BOOL AddTaskIcon(HWND hwnd, UINT uID, HICON hicon, LPSTR lpszTip) 
{
    BOOL res;
    NOTIFYICONDATA tnid;
    
    tnid.cbSize = sizeof(NOTIFYICONDATA); 
    tnid.hWnd = hwnd; 
    tnid.uID = uID; 

    tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; 
    tnid.uCallbackMessage = WM_TRAYCLICK;
    tnid.hIcon = hicon;
    if (lpszTip)
        lstrcpyn(tnid.szTip, lpszTip, sizeof(tnid.szTip)); 
    else 
        tnid.szTip[0] = '\0'; 
 
    res = Shell_NotifyIcon(NIM_ADD, &tnid); 
 
    if (hicon) 
        DestroyIcon(hicon); 

    return res; 
}

BOOL ChangeTaskIcon(HWND hwnd, UINT uID, HICON hicon, LPSTR lpszTip) 
{ 
    BOOL res; 
    NOTIFYICONDATA tnid;
    
    tnid.cbSize = sizeof(NOTIFYICONDATA); 
    tnid.hWnd = hwnd; 
    tnid.uID = uID; 

    tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; 
    tnid.uCallbackMessage = WM_TRAYCLICK; 
    tnid.hIcon = hicon; 
    if (lpszTip) 
        lstrcpyn(tnid.szTip, lpszTip, sizeof(tnid.szTip)); 
    else 
        tnid.szTip[0] = '\0'; 
 
    res = Shell_NotifyIcon(NIM_MODIFY, &tnid); 
 
    if (hicon) 
        DestroyIcon(hicon); 
 
    return res; 
}

//А это вставь в процедуру
case WM_TRAYCLICK:

     if(lParam == WM_LBUTTONDBLCLK)
     { 
         if(ShowWindow (hwndMain,0)==0)
         {
            ShowWindow (hwndMain,SW_SHOW);
            SetForegroundWindow(hwndMain);
        }
        else ShowWindow (hwndMain,SW_HIDE);

         break;
     }
     
     if( lParam == WM_LBUTTONDOWN)
     {
         SetForegroundWindow(hwndMain);
         break;
     }

     if( lParam == WM_RBUTTONUP)//Как раз как правильно попапы отображать
     {
         SetForegroundWindow(hwndMain);
         GetCursorPos(&pt);
         TrackPopupMenu(cMenu, TPM_RIGHTALIGN|TPM_RIGHTBUTTON,pt.x, pt.y, 0, hwndMain, NULL);
         break;
     }
return 0;

Автор: jonie 11.8.2006, 23:02
Код

     if( lParam == WM_RBUTTONUP)//Как раз как правильно попапы отображать
     {
         SetForegroundWindow(hwndMain);
         GetCursorPos(&pt);
         TrackPopupMenu(cMenu, TPM_RIGHTALIGN|TPM_RIGHTBUTTON,pt.x, pt.y, 0, hwndMain, NULL);
         break;
     }


надобно сделать так
Код

     if( lParam == WM_RBUTTONUP)//Как раз как правильно попапы отображать
     {
         GetCursorPos(&pt);
         SetForegroundWindow(hwndMain);
         TrackPopupMenu(cMenu, TPM_RIGHTALIGN|TPM_RIGHTBUTTON,pt.x, pt.y, 0, hwndMain, NULL);
   PostMessage(hwndMain,WM_NULL,0,0);
         break;
     }

цитата из сборика Iczelion`a :
Цитата

Внимание: остерегайтесь следующих проблем, часто возникающих при pаботе со всплывающими меню. 

Когда меню отображено на экране, щелчок вне меню не приводит к его немедленному исчезновению. Это происходит потому, что окно, которое будет получать уведомления от меню, ДОЛЖНО быть на переднем плане. Просто вызовите SetForegroundWindow, чтобы исправить эту проблему. 

После вызова SetForegroundWindow вы обнаружите, что в первый раз всплывающее меню сработает нормально, но при последующем появлении оно будет отображаться, а затем тут же исчезать. Как написано в MSDN, это сделано "намеренно". Необходимо переключить задачу на программу, являющуюся владельцем иконки в system tray. Этого можно добиться, отправив любое сообщение окну вашей программы. Но только используйте PostMessage, а не SendMessage! 

Автор: AquilA 27.5.2007, 18:22
Люди, столкнулся с такой проблемой.
Добавляю иконку в трей
Код

void AddStatusIcon(HWND m_hWnd)
{
    HICON hIcon;
    hIcon = AfxGetApp()->LoadIconA(IDR_MAINFRAME);
    nf.hWnd = m_hWnd;
    nf.uID = NULL;
    nf.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
    nf.uCallbackMessage = WM_MYICONNOTIFY;
    nf.hIcon = hIcon;
    lstrcpyn(nf.szTip, "подсказка", sizeof(nf.szTip));
    Shell_NotifyIconA(NIM_ADD, &nf);
}

Потом навожу на нее мышкой и она исчезает вообще! 
как решить проблему?

Автор: Tectoder 27.5.2007, 18:35
AquilA, не sizeof а strlen.
Когда люди начнут читать учебники по C++? Ниужто никогда?

Автор: AquilA 27.5.2007, 18:44
Tectoder
в смысле strlen(nf.szTip)? в примерах везде sizeof!
Но это сути дела не поменяло. все равно исчезает иконка!

Автор: Tectoder 27.5.2007, 20:33
Цитата(AquilA @  27.5.2007,  18:44 Найти цитируемый пост)
в примерах везде sizeof!
Все такие примеры надо выкинуть
Вообще,
1) nf.cbsize надо то же устанавливать
2) m_hWnd точно правильный hwnd, который все время существует?

Автор: AquilA 28.5.2007, 08:08
m_hWnd  все таки не передается!!! :( не могу вкурить.
Можно в MESSAGE_MAP прописать загрузку данной функции? или как?

Автор: webgraf 6.7.2007, 16:37
Столкунулся с проблемой. Код аналогичный приведенному выше, но меню создавал в ресурсах. В итоге при вызове попап оно неправильно прорисовывается - без содержания, однако при выборе подменю(а его можно выбрать если прицелиться) подменю отображается коректно.
Собственно вот так вот:
user posted image

А если навести курсор на примерное место пункта - появляется нормальное submenu:
user posted image

Меню создавал так:
Код

             if( lParam == WM_RBUTTONUP)             {
                 POINT  pt;
                 GetCursorPos(&pt);
                 SetForegroundWindow(hWnd);
                 TrackPopupMenu(LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU1)), TPM_RIGHTALIGN|TPM_RIGHTBUTTON,pt.x, pt.y, 0, hWnd, NULL);
                 PostMessage(hWnd,WM_NULL,0,0);
                 break;
             }


Само меню содержит всего два пункта, один из них содержит два подпункта.
Кому-нибудь знакома такая ситуация?

Автор: 586 6.7.2007, 17:43
http://forum.vingrad.ru/forum/topic-112151.html

Автор: webgraf 6.7.2007, 18:26
Спасибо!  smile 

Получается в данном случае нужно обязательно  применять submenu.
Код

TrackPopupMenu(GetSubMenu(LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU1)),0), TPM_RIGHTALIGN|TPM_RIGHTBUTTON,pt.x, pt.y, 0, hWnd, NULL);

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)