Wie lasse ich den Mainframe das Kontextmenü eines CListCtrl behandeln?



  • Hallo!

    Ich habe in mein ListCtrl ein Contextmenü eingebaut. Einige Funktionen sollen aber die selben sein wie die aus dem Hauptmenü und deshalb vom MainFrame behandelt werden.

    Mit den WM_COMMAND hab ich das schon geschafft:

    void CSortListCtrl::OnBearbeitenAendern() 
    {
    	AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_BEARBEITEN_AENDERN);
    }
    

    Aber was mache ich für die Updateterei? Was für eine Nachricht kann ich da schicken?

    Das hier geht jedenfalls nicht. 😞

    void CSortListCtrl::OnUpdateBearbeitenAendern(CCmdUI* pCmdUI) 
    {
    	AfxGetMainWnd()->SendMessage(UPDATE_COMMAND_UI, ID_BEARBEITEN_AENDERN);
    }
    

    So, nun bau ich das erstmal auf CommandRange um. Hoffentlich hat hier jemand inzwischen eine Idee. 🙂



  • Zusatzfrage:

    Warum reagiert das Listcontrol nicht auf das Menü?
    Also: Das Menü erscheint, aber die Menünachrichten gehen irgendwo verloren. 😕



  • Bitte Leute, ich find echt nix zum Thema. 😞

    Das muss doch möglich sein, für controls ein Contextmenü anzulegen und dessen Nachrichten zu behandeln.



  • So etwas habe ich gefunden und zwar in der MSDN:
    In Dialogen (und wie es scheint auch FormViews) wird WM_INITMENUPOPUP nicht behandelt. Daher funktionieren auch die OnUpdateCommandUi Handler nicht. Deswegen muss man einen Handler schreiben mit folgendem Quelltext:

    void CTestDlg::OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex,BOOL bSysMenu)
    {
        ASSERT(pPopupMenu != NULL);
        // Check the enabled state of various menu items.
    
        CCmdUI state;
        state.m_pMenu = pPopupMenu;
        ASSERT(state.m_pOther == NULL);
        ASSERT(state.m_pParentMenu == NULL);
    
        // Determine if menu is popup in top-level menu and set m_pOther to
        // it if so (m_pParentMenu == NULL indicates that it is secondary popup).
        HMENU hParentMenu;
        if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu)
            state.m_pParentMenu = pPopupMenu;    // Parent == child for tracking popup.
        else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL)
        {
            CWnd* pParent = this;
    		// Child windows don't have menus--need to go to the top!
            if (pParent != NULL &&
    			(hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
            {
    			int nIndexMax = ::GetMenuItemCount(hParentMenu);
    			for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
    			{
    				if (::GetSubMenu(hParentMenu, nIndex) == pPopupMenu->m_hMenu)
    				{
    					// When popup is found, m_pParentMenu is containing menu.
    					state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
    					break;
    				}
    			}
            }
        }
    
        state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
        for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
    	state.m_nIndex++)
        {
            state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
            if (state.m_nID == 0)
    			continue; // Menu separator or invalid cmd - ignore it.
    
            ASSERT(state.m_pOther == NULL);
            ASSERT(state.m_pMenu != NULL);
            if (state.m_nID == (UINT)-1)
            {
    			// Possibly a popup menu, route to first item of that popup.
    			state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);
    			if (state.m_pSubMenu == NULL ||
    				(state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
    				state.m_nID == (UINT)-1)
    			{
    				continue;       // First item of popup can't be routed to.
    			}
    			state.DoUpdate(this, TRUE);   // Popups are never auto disabled.
            }
            else
            {
    			// Normal menu item.
    			// Auto enable/disable if frame window has m_bAutoMenuEnable
    			// set and command is _not_ a system command.
    			state.m_pSubMenu = NULL;
    			state.DoUpdate(this, FALSE);
            }
    
            // Adjust for menu deletions and additions.
            UINT nCount = pPopupMenu->GetMenuItemCount();
            if (nCount < state.m_nIndexMax)
            {
    			state.m_nIndex -= (state.m_nIndexMax - nCount);
    			while (state.m_nIndex < nCount &&
    				pPopupMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
    			{
    				state.m_nIndex++;
    			}
            }
            state.m_nIndexMax = nCount;
        }
    }
    

    Ich habe zwar keinen Dialog, aber für Controls scheint das auch zuzutreffen. Jedenfalls wird das jetzt alles brav de-/aktiviert.

    Das mit dem Schicken an den Mainframe geht allerdings immer noch nicht. 😞


Anmelden zum Antworten