[英]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.