2

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

具体来说:

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

在此处输入图像描述

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

PS:Menu的程序是OK的。它总是调用ON_UPDATE_COMMAND_UI处理程序并在处理程序之前检查按钮状态ON_COMMAND

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

4

2 回答 2

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

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

于 2016-05-25T08:35:13.110 回答
0

当我遇到这个问题时,我想我会添加我的解决方案。我有一个按钮可以将记录粘贴到数据库中,因此客户端很清楚,我只希望在剪贴板上有有效数据时启用该按钮。这是它的样子:

在此处输入图像描述

后面是我的应用程序,前面是记事本++,并选择了记录。当我'ctrl C' 记事本++ 中的文本时,即使我的应用程序处于空闲状态,我的工具栏上的'I' 也会变为活动状态。我的应用程序是剪贴板链的一部分并得到通知。这是 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;
}

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

于 2016-06-18T21:02:04.813 回答