查遍了msdn。用过CToolBarCtrl::EnableButton
CToolBarCtrl::SetState都不起作用
CToolBarCtrl::SetState都不起作用
解决方案 »
- 如何在线程函数中调用SetDlgItemText
- 我是的FTP(自己用socket实现的协议)客户端程序与Server U通信,程序是正常的,也关闭了所有的socket,
- 如何限制窗口缩放尺寸
- 我能够通过GetIRichEditOle()->GetObject(...)来得到已经插入richedit的object的位子???
- 刚刚建好一个对话框,大家看看这个错误是什么东西?解决即结贴
- 请问这是什么错误?
- VB中有指针吗
- 在VC中如何使用windows 媒体播放器这个控件?
- 请问学习vc++有浅到深的顺序,例如c++->MFC->ATL->com->.NET?说明理由。
- 用vc++怎么做一个建立ftp服务器端?
- 在线等待
- COM中使用SOCKET
用SetButtonInfo把要禁止按钮的ID改成无效
CMainFrame * pMainFrame=(CMainFrame *)AfxGetMainWnd(); if(pMainFrame->m_wndToolBar.GetToolBarCtrl().IsButtonEnabled(ID_GETDATESOURCE))
{
MessageBox("test");
pMainFrame->m_wndToolBar.GetToolBarCtrl().SetState(ID_,TBSTATE_HIDDEN);
}
if(pMainFrame->m_wndToolBar.GetToolBarCtrl().IsButtonHidden(ID_))
{
MessageBox("test1");
pMainFrame->m_wndToolBar.GetToolBarCtrl().SetState(ID_,TBSTATE_ENABLED); }
{
// TODO: Add your specialized code here and/or call the base class
m_wndToolBar.GetToolBarCtrl().EnableButton( ID_FILE_NEW, FALSE );
return CFrameWnd::PreTranslateMessage(pMsg);
}
pToolBarCtrl->SetCmdID(nIndex, 1);
看看mfc的源代码
所有的界面更新操作mfc都有自己的一套机制。通过对idle消息的处理发送WM_COMMAND消息(code=CN_COMMAND_UI),因为WM_COMMAND消息在mfc里面有自己定义好的流动方式,所以对界面的更新操作每时每刻都在进行。尽管你用CToolBarCtrl::EnableButton或者CToolBarCtrl::SetState改变按钮的状态,mfc在线程没有消息的时候也会干涉的。
它的干涉方式如下:
void CControlBar::OnInitialUpdate()
{
// update the indicators before becoming visible
OnIdleUpdateCmdUI(TRUE, 0L);//这里调用下一个函数
}
LRESULT CControlBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM)
{
// handle delay hide/show
BOOL bVis = GetStyle() & WS_VISIBLE;
UINT swpFlags = 0;
if ((m_nStateFlags & delayHide) && bVis)
swpFlags = SWP_HIDEWINDOW;
else if ((m_nStateFlags & delayShow) && !bVis)
swpFlags = SWP_SHOWWINDOW;
m_nStateFlags &= ~(delayShow|delayHide);
if (swpFlags != 0)
{
SetWindowPos(NULL, 0, 0, 0, 0, swpFlags|
SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
} // the style must be visible and if it is docked
// the dockbar style must also be visible
if ((GetStyle() & WS_VISIBLE) &&
(m_pDockBar == NULL || (m_pDockBar->GetStyle() & WS_VISIBLE)))
{
CFrameWnd* pTarget = (CFrameWnd*)GetOwner();
if (pTarget == NULL || !pTarget->IsFrameWnd())
pTarget = GetParentFrame();
if (pTarget != NULL)
OnUpdateCmdUI(pTarget, (BOOL)wParam); //这里调用CToolBar的下一个成员函数
}
return 0L;
}void CToolBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
CToolCmdUI state;
state.m_pOther = this; state.m_nIndexMax = (UINT)DefWindowProc(TB_BUTTONCOUNT, 0, 0);
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; state.m_nIndex++)
{
// get buttons state
TBBUTTON button;
_GetButton(state.m_nIndex, &button);
state.m_nID = button.idCommand; // ignore separators
if (!(button.fsStyle & TBSTYLE_SEP))
{
// allow reflections
if (CWnd::OnCmdMsg(0,
MAKELONG((int)CN_UPDATE_COMMAND_UI, WM_COMMAND+WM_REFLECT_BASE),
&state, NULL))
continue; // allow the toolbar itself to have update handlers
if (CWnd::OnCmdMsg(state.m_nID, CN_UPDATE_COMMAND_UI, &state, NULL))
continue; // allow the owner to process the update
state.DoUpdate(pTarget, bDisableIfNoHndler);
}
} // update the dialog controls added to the toolbar
UpdateDialogControls(pTarget, bDisableIfNoHndler);
}
//主要的操作就在这里面
BOOL CCmdUI::DoUpdate(CCmdTarget* pTarget, BOOL bDisableIfNoHndler)
{
ASSERT_VALID(pTarget); if (m_nID == 0 || LOWORD(m_nID) == 0xFFFF)
return TRUE; // ignore invalid IDs m_bEnableChanged = FALSE;
//这里调用我们自己写的OnCmdUI()如果没有写bResult返回FALSE;
//m_bEnableChanged是CCmdUI的成员变量通过pCmdUI->Enable来改变他
BOOL bResult = pTarget->OnCmdMsg(m_nID, CN_UPDATE_COMMAND_UI, this, NULL);
if (!bResult)
ASSERT(!m_bEnableChanged); // not routed//bDisableIfNoHandle 就是前面OnInitialUpdate里面的TRUE;
//如果bDisableIfNoHndler(对应的命令没有处理函数就禁止该选项)为true而且
//m_bEnableChanged为为False(默认)执行下面的代码 if (bDisableIfNoHndler && !m_bEnableChanged)
{
AFX_CMDHANDLERINFO info;
info.pTarget = NULL;
//注意bHandle的返回值为TRUE表示消息处理链中有这样的函数
BOOL bHandler = pTarget->OnCmdMsg(m_nID, CN_COMMAND, this, &info);#ifdef _DEBUG
if ((afxTraceFlags & traceCmdRouting) && !bHandler)
TRACE1("No handler for command ID 0x%04X, disabling it.\n", m_nID);
#endif
// Enable or Disable based on whether there is a handler there
//这是一行关键的代码禁止和允许都在这里面
//如果不想要mfc自动改变状态就在前面想办法吧 ^&^
Enable(bHandler);
}
return bResult;
}
好累阿
我想经过上面的分析你应该知道怎么做了吧
我想如果你用CToolBar除非做钩子和挂接,否则很难实现,我是这样想的.
{
if(m_spMedia) // 接口指针有效
{
m_spMedia->UpdateUICommand(); //调用组件中的更新
}
}// 组件中
STDMETHODIMP CMedia::UpdateUICommand()
{
if( m_bUpdate )
{
CMenu* pMenu = m_pMainMenu->GetSubMenu(1);
pMenu->EnableMenuItem(iId,MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
m_pToolBar->GetToolBarCtrl().EnableButton(iId,FALSE);
}
return S_OK;
}
CFrameWnd::有个公有成员变量来控制是否使用cmdui来更新菜单如果m_bAutoMenuEnable
你只要赋值为FALSE就可以了;