繁体   English   中英

MFC CToolBar更新机制错误?

[英]MFC CToolBar update mechanism bug?

在Visual Studio中,MFC CToolBar按钮由在空闲状态期间发送的ON_UPDATE_COMMAND_UI更新。 我想如果我在ON_UPDATE_COMMAND_UI处理程序中更改按钮的启用/禁用状态,则该机制存在问题。

特别:

假设按钮现在处于启用状态。 在某个时间,代码“希望”禁用按钮(当然用户也不应单击该按钮),但是在下一个空闲时间该按钮实际上将被禁用,如下图所示:

在此处输入图片说明

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

PS:“菜单”的步骤确定。 它总是调用ON_UPDATE_COMMAND_UI处理程序,并在ON_COMMAND处理程序之前检查按钮状态。

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

经过调试和跟踪,我终于找到了可能的解决方案。 此处列出了关键代码,以帮助其他人解决相同的问题。 覆盖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);
}

副作用是为工具栏禁用了WM_COMMAND反射,但是在大多数情况下可以。

当我刚遇到这个问题时,我想我应该添加解决方案。 我有一个将记录粘贴到数据库中的按钮,因此对于客户端来说很明显,我只想在剪贴板上有有效数据的情况下启用该按钮。 看起来像这样:

在此处输入图片说明

我的应用程序位于背面,记事本++位于前面,并已选择记录。 当我“ Ctrl C”时,即使我的应用程序处于空闲状态,记事本++中的文本也仍然处于活动状态。 我的应用程序是剪贴板链的一部分,并得到通知。 这是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;
}

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

LRESULT CMainFrame::OnCheckClipboard(  WPARAM wparam, LPARAM lparam  )
{
    std::string data( GetClipboardStr( ) );
    std::string::size_type end_cnt= data.find( "\r\n" );
    if( end_cnt == std::string::npos )
        bClipboardHasValidRecords= false;
    else
    {
        auto header_end= data.begin( ) + end_cnt;
        csv_vect_t header;
        split( header, str_it_range_t( data.begin( ), header_end ), boost::is_any_of("\t") );

        bClipboardHasValidRecords= header.size( ) == RARECORD_SIZE;
    }
    return TRUE;
}

消息将唤醒我的应用程序的主线程,并且“ I”将打开和关闭,而不会使应用程序成为活动窗口。 它只是发生而无需任何额外的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM