Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > tray icon


Автор: decembrist 6.10.2005, 16:50
кто знает, как подключить popup меню к tray icon на событие RMB?
в MainFrame::OnInitDialog создаю иконку

Код

// Load a small icon
HICON hIconSmall = (HICON)::LoadImage(_Module.GetResourceInstance(), 
                                      MAKEINTRESOURCE(IDR_MAINFRAME),
                                      IMAGE_ICON, 
                                      ::GetSystemMetrics(SM_CXSMICON), 
                                      ::GetSystemMetrics(SM_CYSMICON), 
                                      LR_DEFAULTCOLOR);


а дальше как?

Автор: chaos 7.10.2005, 06:51
вот тебе не большой пример
Код

#define WM_TRAYNOTIFY WM_USER+1
...
NOTIFYICONDATA nf;
nf.hWnd = m_hWnd;
nf.uID = NULL;

nf.uFlags = NIF_ICON | NIF_MESSAGE;
nf.uCallbackMessage = WM_MYICONNOTIFY;

HICON hIcon;
hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
nf.hIcon = hIcon;
Shell_NotifyIcon(NIM_ADD,&nf);
....


и потом обрабатываешь сообщение WM_MYICONNOTIFY
Код

BEGIN_MESSAGE_MAP(YouProgram, ParentYouProgram)
    //{{AFX_MSG_MAP(CTrayDlg)
    ON_MESSAGE(WM_SHELLNOTIFY,OnTray)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()


void YouProgram::OnTray(WPARAM wp, LPARAM lp)
{
...    
}

Автор: decembrist 7.10.2005, 11:35
Да, у меня есть функция которая вызывается в HWND MainFrame::Create(HWND hWndParent)

Код

bool MainFrame::AddTrayIcon(void)
{
    try
    {
        m_nf.cbSize = sizeof(NOTIFYICONDATA);
        m_nf.hWnd = GetHWND();
        m_nf.uID = N_TRAY;
        m_nf.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
        m_nf.uCallbackMessage = UWM_SYSTRAY; // message sent to nid.hWnd
        strcpy(m_nf.szTip,"PowerCAST");
        m_nf.hIcon=::LoadIcon(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MAINFRAME));
    }
    catch (...) 
    {
    }
    return Shell_NotifyIcon(NIM_ADD,&m_nf) ? true : false;
}


и иконка у меня есть.
Мне нужно создать поп ап меню, которое реагировало бы на нажатие RMB по этой иконке

Автор: chaos 7.10.2005, 12:05
ну вот, у тебя есть
Код

m_nf.uCallbackMessage = UWM_SYSTRAY;

тебе надо обрабатывать сообщение UWM_SYSTRAY
вот тебе пример
Код

void CTrayDlg::OnTray(WPARAM wp, LPARAM lp)
{
    if (WM_RBUTTONDOWN == lp)    
    {
        CMenu oMenu;
        oMenu.CreatePopupMenu();
        POINT pt;
        GetCursorPos(&pt);
        oMenu.AppendMenu(MF_STRING, 0, "str1");
        oMenu.AppendMenu(MF_STRING, 1, "str2");
        oMenu.AppendMenu(MF_STRING, 2, "str3");
        oMenu.TrackPopupMenu(TPM_RIGHTALIGN, pt.x, pt.y, this);
    }
}

Добавлено @ 12:09
соответственно тебе надо в карте сообщений связать функцию обработки события с сообщением!!

Автор: decembrist 7.10.2005, 12:29
chaos Компилятир на WM_SHELLNOTIFY ругается smile

Автор: chaos 7.10.2005, 12:32
Цитата(decembrist @ 7.10.2005, 12:29)
chaos Компилятир на WM_SHELLNOTIFY ругается smile

и правельно делает smile
это еще надо
Код

#define WM_SHELLNOTIFY WM_USER+1 

Автор: decembrist 7.10.2005, 12:33
ага, сейчас попробую с UWM_SYSTRAY, спасибо chaos smile

Автор: decembrist 7.10.2005, 12:52
обрабатываю сообщение UWM_SYSTRAY:
Код

if (lParam ==  WM_RBUTTONUP)  
        {
            switch (wParam) 
            { 
            case N_TRAY: 
                DisplayContextMenu();
                break; 
            default: 
                break; 
            }
        }

в функции DisplayContextMenu() создаю меню:
Код

LRESULT MainFrame::DisplayContextMenu()
{
     CMenu m_ContextMenu;
     m_ContextMenu.LoadMenu(IDR_SYSTRAY_MENU);
     POINT pt;
     ::GetCursorPos(&pt);
     CMenuHandle menuTrackContext = m_ContextMenu.GetSubMenu(0);
     if (!m_ContextMenu.m_hMenu)
     {
         ATLTRACE(_T("Failed to get context menu child\n"));
         m_ContextMenu.DestroyMenu();
         m_ContextMenu.m_hMenu = NULL;
         return 0; 
     }
}

и никакого поп ап меню не появляется!

Автор: chaos 7.10.2005, 12:54
ты в DisplayContextMenu() вообще попадаешь?

Автор: decembrist 7.10.2005, 12:56
сорри там еще
Код

m_ContextMenu.TrackPopupMenu(TPM_RIGHTALIGN, pt.x, pt.y, this);

Автор: chaos 7.10.2005, 13:02
вот у меня все работает
Код

void CTrayDlg::OnTray(WPARAM wp, LPARAM lp)
{
    if (lp == WM_RBUTTONDOWN)    
    {
        POINT pt;
        GetCursorPos(&pt);

        CMenu oMenu;
        oMenu.LoadMenu(IDR_MENU1);
        oMenu.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTALIGN, pt.x, pt.y, this);
    }
}

Автор: decembrist 7.10.2005, 13:10
да попадаю.
но на строчке
Код

m_ContextMenu.TrackPopupMenu(TPM_RIGHTALIGN, pt.x, pt.y, this); 


комп ругается:
WTL::CMenuT<t_bManaged>::TrackPopupMenu cannot convert parameter 4 from "MainFrame *const' to "HWND"

Автор: chaos 7.10.2005, 13:18
хм WTL
попробуй так
Код

 m_ContextMenu.TrackPopupMenu(TPM_RIGHTALIGN, pt.x, pt.y, m_hWnd); 

Автор: decembrist 7.10.2005, 13:21
у меня функция с 5 параметрами:

Код

TrackPopupMenu(UINT nFlags, int x, int y, CWnd *pWnd, LPCRECT lpRect = 0);

Автор: chaos 7.10.2005, 13:23
короче!!!
чето мы тут првратили простетскую задачу в ...(сам не знаю что)
сделай так
Код

m_ContextMenu.TrackPopupMenu(TPM_RIGHTALIGN, pt.x, pt.y, AfxGetMainWnd( )); 



Автор: decembrist 7.10.2005, 16:10
chaos попробовал так как ты написал с параметром m_hWnd.
Вроде заработало. Спасибо smile

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