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.