새소식

DEV/C++

[MFC]Dialog UPDATE_COMMAND_UI 안먹는 문제

  • -
728x90

Dialog 에 UPDATE_COMMAND_UI 가 적용 안되는 증상

아래는 토글flag에 따라 메뉴UI 활성/비활성 화 하기 위한 소스인데,

 

1.초기 버튼토글 위한 전역 변수생성, 초기화.

_bstart = TRUE;

 

2. 버튼 컨트롤의 COMMAND, UPDATE_COMMAND_UI 만들어서 함수내용 작성한다.

//ID_STRAT버튼의 COMMAND 이벤트함수
void CMenuTestDlg::OnStrat()   
{
    _bstart = !_bstart;  //토글
}

//ID_STRAT버튼의 UPDATE_COMMAND_UI
void CMenuTestDlg::OnUpdateStrat(CCmdUI* pCmdUI) 
{
    if (_bstart == TRUE)
        pCmdUI->Enable(FALSE); //메뉴 비활성화
    else
        pCmdUI->Enable(TRUE); //활성화
}

뭐 원랜 여기까지만 해도 적용 되야하지만.. 적용이 안되는 이슈가 있다

해당 이슈는 마이크로소프트 페이지에 공개 되어 있다(http://support.microsoft.com/kb/242577 )

다이얼로그에 UPDATE_COMMAND_UI를 사용하면 미적용 된다는 이슈..

하여 동작위해선 매세지맵에 ON_WM_INITMENUPOPUP 이걸 추가 하여야 한다.

 

3. 메세지 맵에 ON_WM_INITMENUPOPUP 추가 그리고 함수작성

void CMenuTestDlg::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
    CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);

    ASSERT(pPopupMenu != NULL);

    CCmdUI state;
    state.m_pMenu = pPopupMenu;
    ASSERT(state.m_pOther == NULL);
    ASSERT(state.m_pParentMenu == NULL);

    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;
        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) {
                    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;
    }
}
728x90
Contents

Copied the posting URL.

Please sympathize with me if this article was helpful.