Menu modifizieren



  • Hi,
    ich plage mich schon seit einiger Zeit mit einem Popup-Menu herum. Aufgerufen
    wird es durch einen Rechtsklick auf ein TrayIcon (benutze die Klasse
    "CSystemTray" von Chris Maunder, weiß nicht ob's wichtig ist).

    Es will mir aber nicht gelingen, das Menu nachträglich zu manipulieren. Im
    unten stehenden Code manipuliere ich erst das System-Menu (funktioniert) und
    anschließend mein eigenes Tray-Menu (funktioniert nicht). Benutzen kann man
    es jedoch ohne Probleme. Ich kann es nur nicht ändern.

    Woran könnte das liegen?

    CMenu Menu, *pMenu = GetSystemMenu(FALSE);
    
    // Das System-Menu modifizieren
    if(pMenu != NULL){
        pMenu->AppendMenu(MF_SEPARATOR);
        pMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, "Hallo System-Menu");
    }
    
    // Das Popup-Menu modifizieren
    if(!Menu.LoadMenu(IDR_MENU_SYSTRAY) || !(pMenu = Menu.GetSubMenu(0))){
        MessageBox("Konnte Menu nicht laden!");
        return;
    } else {
        pMenu->AppendMenu(MF_SEPARATOR);
        pMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, "Hallo System-Tray-Menu");
    }
    


  • Wann zeigst du denn dein PopupMenu an?



  • Wenn der Benutzer mit der rechten Maustaste auf das TrayIcon klickt.

    Aufgerufen wird es durch einen Rechtsklick auf das TrayIcon. Die Nachricht wird
    in der Klasse CSystemTray behandelt (unter "OnTrayNotification"), die übrigens von CWnd erbt. Die wichtigsten Codeauschnitte habe ich unten mal aufgeführt.

    In der Dialogklasse:

    ...
    m_clsSystemTray.Create( this,
                PM_NOTIFY_TRAY_ICON,
                "Backy konfigurieren",
                m_hIcon,
                IDR_MENU_SYSTRAY);
    ...
    

    Klasse CSystemTray:

    ...
    BOOL CSystemTray::Create(CWnd* pParent, UINT uCallbackMessage, LPCTSTR szToolTip, 
                             HICON icon, UINT uID)
    {
        // this is only for Windows 95 (or higher)
        m_bEnabled = (GetVersion() & 0xff) >= 4;
        if (!m_bEnabled) 
        {
            ASSERT(FALSE);
            return FALSE;
        }
    
        m_nMaxTooltipLength = _countof(m_tnd.szTip);
    
        // Make sure we avoid conflict with other messages
        ASSERT(uCallbackMessage >= WM_APP);
    
        // Tray only supports tooltip text up to m_nMaxTooltipLength) characters
        ASSERT(AfxIsValidString(szToolTip));
        ASSERT(_tcslen(szToolTip) <= m_nMaxTooltipLength);
    
        // Create an invisible window
        CWnd::CreateEx(0, AfxRegisterWndClass(0), _T(""), WS_POPUP, 0,0,0,0, NULL, 0);
    
        // load up the NOTIFYICONDATA structure
        m_tnd.cbSize = sizeof(NOTIFYICONDATA);
        m_tnd.hWnd   = pParent->GetSafeHwnd()? pParent->GetSafeHwnd() : m_hWnd;
        m_tnd.uID    = uID;
        m_tnd.hIcon  = icon;
        m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
        m_tnd.uCallbackMessage = uCallbackMessage;
        _tcsncpy(m_tnd.szTip, szToolTip, m_nMaxTooltipLength-1);
    
        m_uCreationFlags = m_tnd.uFlags;    // Store in case we need to recreate in OnTaskBarCreate
    
        return (Shell_NotifyIcon(NIM_ADD, &m_tnd) != 0);
    }
    
    LRESULT CSystemTray::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
    {
        if (message == m_tnd.uCallbackMessage)
            return OnTrayNotification(wParam, lParam);
    
        return CWnd::WindowProc(message, wParam, lParam);
    }
    
    LRESULT CSystemTray::OnTrayNotification(UINT wParam, LONG lParam) 
    {
        //Return quickly if its not for this tray icon
        if (wParam != m_tnd.uID)
            return 0L;
    
        CMenu menu, *pSubMenu;
        CWnd *pTargetWnd = GetTargetWnd();
        if (!pTargetWnd)
            return 0L;
    
        // Clicking with right button brings up a context menu
        if (LOWORD(lParam) == WM_RBUTTONUP)
        {    
            if (!menu.LoadMenu(m_tnd.uID))
                return 0;
    
            pSubMenu = menu.GetSubMenu(0);
            if (!pSubMenu)
                return 0;
    
            // Make chosen menu item the default (bold font)
            ::SetMenuDefaultItem(pSubMenu->m_hMenu, m_DefaultMenuItemID, m_DefaultMenuItemByPos);
    
            // Display and track the popup menu
            CPoint pos;
            GetCursorPos(&pos);
    
            pTargetWnd->SetForegroundWindow(); 
    
            ::TrackPopupMenu(pSubMenu->m_hMenu, 0, pos.x, pos.y, 0, 
                             pTargetWnd->GetSafeHwnd(), NULL);
    
            // BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly"
            pTargetWnd->PostMessage(WM_NULL, 0, 0);
    
            menu.DestroyMenu();
        } 
        else if (LOWORD(lParam) == WM_LBUTTONDBLCLK) 
        {
            // double click received, the default action is to execute default menu item
            pTargetWnd->SetForegroundWindow();  
    
            UINT uItem;
            if (m_DefaultMenuItemByPos)
            {
                if (!menu.LoadMenu(m_tnd.uID))
                    return 0;
    
                pSubMenu = menu.GetSubMenu(0);
                if (!pSubMenu)
                    return 0;
    
                uItem = pSubMenu->GetMenuItemID(m_DefaultMenuItemID);
    
                menu.DestroyMenu();
            }
            else
                uItem = m_DefaultMenuItemID;
    
            pTargetWnd->SendMessage(WM_COMMAND, uItem, 0);
        }
    
        return 1;
    }
    


  • Du musst es in CSystemTray::OnTrayNotification modifizieren ...



  • Tatsächlich, es klappt. Aber warum kann ich es von der Dialogklasse aus
    nicht modifizieren? Denn auf die Resourcen habe ich ja von überall aus
    Zugriff.



  • Du kannst die Resourcen zur Laufzeit nicht modifizieren. Immer nur laden und dann modifizieren.


Anmelden zum Antworten