Ei saa muuta menüükäsu olek: selle käsu kasutajaliidese ohjur, kui menüü on lisatud dialoogiboksi Visual c++

Märkus Microsoft Visual C++ .NET 2002 ja Microsoft Visual C++ .NET 2003 tugi nii hallatav kood mudelit, mis on esitatud Microsoft .NET Frameworki ja haldamata native Microsoft Windowsi koodi näidis. Selles artiklis olev teave kehtib ainult halduseta Visual C++ kood. Microsoft Visual C++ 2005 toetab hallatav kood mudel, mis on saadaval Microsoft .NET Frameworki ja haldamata native Microsoft Windowsi kood mudel.

Sümptomid

Selle käsu kasutajaliidese (UI) ohjuri menüükäsu oleku (lubada või keelata, sisse/Eemalda, Muuda teksti) üleminek ei tööta õigesti kui menüü on seotud dialoogiboks:

void CTestDlg::OnUpdateFileExit(CCmdUI* pCmdUI) {    pCmdUI->Enable(FALSE); //Not calling the command handler, but does not show as disabled.    pCmdUI->SetCheck(TRUE); // Does not show check mark before the text.    pCmdUI->SetRadio(TRUE); // Does not show dot before the text.    pCmdUI->SetText("Close"); //Does not change the text.}

Põhjus

Rippmenüüst menüü kuvamisel WM_INITMENUPOPUP sõnum saadetakse enne menüükäskude kuvamine. MFC CFrameWnd::OnInitMenuPopup funktsiooni itereerib läbi menüükäskude ja kutsub värskenduse käsu UI ohjuri üksuse, kui see on olemas. Iga menüükäsu ilme värskendatakse kajastamiseks olek (lubatud või keelatud, kontrollitud/kontrollimata). Update UI mehhanism ei tööta dialoogiboksi väljale-põhine rakendus kasutab CWndvaikimisi handler, ei sea värskenduse käsu UI ohjurid käsud, sest CDialog on OnInitMenuPopup ohjurit pole.

Lahendus

Kasutage selle probleemi lahendamiseks toimige järgmiselt.

  1. ON_WM_INITMENUPOPUP kirje lisamine kaarti teade:

    BEGIN_MESSAGE_MAP(CTestDlg, CDialog)//}}AFX_MSG_MAPON_WM_INITMENUPOPUP()END_MESSAGE_MAP()
  2. OnInitMenuPopup liikme funktsiooni lisamiseks dialoogiboksi väljale klassi ja kopeerige järgmine kood (Pange tähele, et seda koodi on võetud suurel määral CFrameWnd::OnInitMenuPopup WinFrm.cpp):

    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;    }}

Olek

Selline käitumine on ette nähtud.

Lisateave

Värskenduse käsu UI ohjuri nimetatakse ka CWnd::OnCommand veenduge, et käsk ei saanud keelatud enne marsruudi. See on põhjuseks, miks käsk ohjuri nimetatakse keelatud menüükäsu isegi juhul, kui see on hall (pole saadaval). Käsud on juhtida olekuks sel juhul kajastada. See on seotud Wincore.cpp failist:

   // Make sure command has not become disabled before routing.   CTestCmdUI state;   state.m_nID = nID;   OnCmdMsg(nID, CN_UPDATE_COMMAND_UI, &state, NULL);   if (!state.m_bEnabled)   {      TRACE1("Warning: not executing disabled command %d\n", nID);      return TRUE;   }

Sellise käitumise taasesilekutsumise juhised

Visual C++ .NET-is sellise käitumise taasesilekutsumise tehke järgmist

  1. AppWizard abil luua MFC dialoogiboksi põhise rakenduse.

  2. Looge uus menüü ressurss ja faili ja Faili/Exit käsud lisada.

  3. Saate selle menüü lahtrisse Properties dialoogiaken dialoogiboksis menüü. Selleks avage dialoogiboksi ressursi dialoogiboksi redaktori. Klõpsake aknas atribuudid valige menüü. Atribuut redaktori rippmenüü loendis kuvatakse uue menüü ressursi ID-d.

  4. Lisage UPDATE_COMMAND_UI ohjuri Faili/Exit menüükäsu. Selleks paremklõpsake Faili/Exit menüü editor ja seejärel Lisage sündmuseohjuri. Viisardi sündmuseohjuri lisamiseks projekti CDialog tuletatud klass UPDATE_COMMAND_UI ohjuri. Klõpsake lisamine ja muutmine luua ohjuri ja lisage üks neist väidetest loodud käitleja meetod:

    pCmdUI->Enable(FALSE); //Not calling the handler, but does not show as disabledpCmdUI->SetCheck(TRUE); // Does not show check mark before the text.pCmdUI->SetRadio(TRUE); // Does not show dot before the text.pCmdUI->SetText("Close"); //Does not change the text.
  5. Luua ja käivitada rakendus.

Viited

Lisateabe saamiseks klõpsake Microsofti teabebaasi artikli kuvamiseks järgmist artiklinumbrit:

lisamine kontrolli olekuriba MFC dialoogiboksid

Kas vajate veel abi?

Täiendage oma oskusi
Tutvuge koolitusmaterjalidega
Kasutage uusi funktsioone enne teisi
Liitu Microsofti Insideri programmis osalejad

Kas sellest teabest oli abi?

Täname tagasiside eest!

Täname tagasiside eest! Tundub, et võiksime teid kokku viia ühega meie Office'i tugiagentidest, kes aitab teil probleemi lahendada.

×