MFC CToolBar更新机制错误?

时间:2016-05-24 17:15:08

标签: c++ mfc updatecommand

在Visual Studio中,MFC CToolBar按钮由ON_UPDATE_COMMAND_UI更新,该按钮在空闲状态下发送。如果我在ON_UPDATE_COMMAND_UI处理程序中更改按钮的启用/禁用状态,我想这个机制是错误的。

具体来说:

假设按钮现在处于启用状态。在某个时间,代码“想要”按钮被禁用(并且当然不应该被用户点击),但是在下一个空闲时段按钮将被禁用,如下图所示:

enter image description here

在图中的红色区域中,我认为代码状态不稳定,开发人员必须通过手动检查按钮状态来处理此不稳定状态。我不知道我是否遗漏了某些东西或对这种机制有误解?

PS:菜单的步骤正常。它始终调用ON_UPDATE_COMMAND_UI处理程序并检查ON_COMMAND处理程序之前的按钮状态。

我的问题是如何在ON_UPDATE_COMMAND_UI处理程序之前调用ON_COMMAND处理程序,就像菜单一样?

2 个答案:

答案 0 :(得分:0)

经过调试和追踪,我终于找到了一个可能的解决方案。此处列出了关键代码,以帮助其他人遇到同样的问题。覆盖OnCommand如下:

BOOL CMainDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
    // Disable WM_COMMAND reflection for ToolBar control
    // makes the ON_UPDATE_COMMAND_UI handler be called 
    // right before ON_COMMAND handler.

    if ((HWND)lParam == m_wndToolBar.GetSafeHwnd())
        lParam = NULL;

    return CDialog::OnCommand(wParam, lParam);
}

副作用是ToolBar禁用WM_COMMAND反射,但在大多数情况下都可以。

答案 1 :(得分:0)

因为我刚刚碰到这个,所以我想我会添加我的解决方案。我有一个按钮将记录粘贴到数据库中,因此对于客户端来说很明显,如果剪贴板上有有效数据,我只想启用该按钮。这是它的样子:

enter image description here

我的应用程序在后面和记事本++前面选择了记录。当我按下C'记事本中的文字++'我'即使我的应用程序处于空闲状态,我的工具栏也会变为活动我的应用程序是剪贴板链的一部分,并得到通知。这是WM_DRAWCLIPBOARD处理程序。

p

从那里我发布到我的应用程序不会妨碍WM_DRAWCLIPBOARD消息,并在那里:

LRESULT CMainFrame::OnDrawClipboard(  WPARAM wparam, LPARAM lparam  )
{
    if( hWndClipboardChain )
        ::SendMessage( hWndClipboardChain, WM_DRAWCLIPBOARD, wparam, lparam );

    if( wparam )
        PostMessage( ID_CLIPBOARD_HASCHANGED, 0, 0 );

    return TRUE;
}

我的应用程序的主要线程被消息唤醒,而且我的#3;将打开和关闭,而不会使应用程序成为活动窗口。它只是在没有任何额外代码的情况下发生。