день добрый всем!
Возникла необходимость заменить в приложении CToolBar на CMFCToolBar вроде все более менее понятно кроме одного: подскажите как дезаблить / енаблить кнопки на этом тулбаре не используя ON_UPDATE_COMAND_UI перепробовал уже кучу танцев с разными бубнами, пока ничего не получается
Здравствуйте, Alex_st, Вы писали:
A_>день добрый всем! A_>Возникла необходимость заменить в приложении CToolBar на CMFCToolBar вроде все более менее понятно кроме одного: подскажите как дезаблить / енаблить кнопки на этом тулбаре не используя ON_UPDATE_COMAND_UI перепробовал уже кучу танцев с разными бубнами, пока ничего не получается
1) В чем проблема применения ON_UPDATE_COMMAND_UI(..., ...)?
2) Что мешает вызвать CMFCToolBar::GetAllButtons(); — этот вызов заполнит коллекцию кнопок CObList — а в ней уже находить нужную кнопку (объект типа CMFCToolBarButton) и для нее вызывать EnableWindow(FALSE/TRUE)?
3) Возможно, есть еще какие-либо варианты решения данного вопроса.
AG>1) В чем проблема применения ON_UPDATE_COMMAND_UI(..., ...)?
в том, что мне нужно апдейтить кнопки по моим событиям, а не тогда когда решит винда, что можно это сделать. к тому же переписывать кучу лигики приложения на ON_UPDATE_COMMAND_UI слишком затратно
AG>2) Что мешает вызвать CMFCToolBar::GetAllButtons(); — этот вызов заполнит коллекцию кнопок CObList — а в ней уже находить нужную кнопку (объект типа CMFCToolBarButton) и для нее вызывать EnableWindow(FALSE/TRUE)?
то, что это не работает
AG>P.S. Я нашел рекомендацию: AG>https://social.msdn.microsoft.com/Forums/en-US/a1eae56a-0c57-4011-b799-8dd57e6be99d/how-do-i-disablereenable-a-cmfctoolbarbutton-in-a-cmfctoolbar?forum=vcmfcatl — может она чем то поможет.
спасибо. но тут как раз через ON_UPDATE_COMMAND_UI
AG>Вопрос — тулбар применяется как основной (в окне наследнике CFrameWndEx/CMDIFrameWndEx) или же в dockable-окне?
тулбар не основной, он не один и висит на отдельно стоящем диалоге, фактически на AppBar`е
Здравствуйте, Alex_st, Вы писали:
A_>Здравствуйте, AlexGin, Вы писали:
AG>>1) В чем проблема применения ON_UPDATE_COMMAND_UI(..., ...)? A_>в том, что мне нужно апдейтить кнопки по моим событиям, а не тогда когда решит винда, что можно это сделать. к тому же переписывать кучу лигики приложения на ON_UPDATE_COMMAND_UI слишком затратно
Винда работает достаточно точно и оперативно , посему проблемы в этом не должно быть.
AG>>2) Что мешает вызвать CMFCToolBar::GetAllButtons(); — этот вызов заполнит коллекцию кнопок CObList — а в ней уже находить нужную кнопку (объект типа CMFCToolBarButton) и для нее вызывать EnableWindow(FALSE/TRUE)? A_>то, что это не работает
Может попробовать так:
POSITION pos;
const CObList& list = m_wndToolBar.GetAllButtons();
int i = 0;
for(pos = list.GetHeadPosition(); pos != NULL; i++)
{
CMFCToolBarButton* pBtn = DYNAMIC_DOWNCAST(CMFCToolBarButton, list.GetNext(pos));
if (pBtn)
{
pBtn->Show(TRUE);
pBtn->SetImage(i); // Set image (or disabled image)
}
}
m_wndToolBar.Invalidate();
Дело в том, что объект CMFCToolBarButton — это наследник CObject, а не CWnd.
То есть — вызов EnableWindow(FALSE/TRUE) тут не пройдет
Здравствуйте, AlexGin, Вы писали:
AG>Дело в том, что объект CMFCToolBarButton — это наследник CObject, а не CWnd. AG>То есть — вызов EnableWindow(FALSE/TRUE) тут не пройдет
AG>Поэтому — приходится извращаться...
вот сделали жа гемороя.
подмена картинок кнопки все-равно оставит ее активной, она будет нажиматься, будет меняться про наведении мыши.
пробовал даже стили менять
Здравствуйте, Alex_st, Вы писали:
A_>вот сделали жа гемороя.
А вот если попробовать таким образом:
сделаем класс-наследник от CMFCToolBar:
class CMyToolBar : public CMFCToolBar
{
public:
void EnableButton (int iCmd, BOOL bStatus);
virtual BOOL OnBeforeFloat(CRect& rectFloat, AFX_DOCK_METHOD dockMethod)
{
return FALSE; // пусть будет строго фиксированным
};
};
вот его метод EnableButton:
void CMyToolBar::EnableButton (int iCmd, BOOL bStatus)
{
// iCmd is not the index, but the command ID - this way the
// buttons can be re-arranged and this routine still works
int idx = CommandToIndex (iCmd);
if (idx == -1)
return; // not in this toolbar
UINT iStyle = GetButtonStyle (idx);
CMFCToolBarButton *Button = GetButton (idx);
if (bStatus)
{ // enable
SetButtonStyle (idx, iStyle & !TBBS_DISABLED);
}
else
{
SetButtonStyle (idx, iStyle | TBBS_DISABLED); // Предотвращает переход в состояние TBBS_PRESSED
}
Button->Show(bStatus); // При bStatus==FALSE картинка пропадает (странное поведение контрола)
}
там, где надо заблокировать — например кнопку:
m_wndToolBar.EnableButton(ID_FILE_OPEN, FALSE);
разблокируем — эту же самую кнопку:
m_wndToolBar.EnableButton(ID_FILE_OPEN, TRUE);
Проверял на основном тулбаре приложения — работает. Однако, соглашусь, что работает весьма странно!
Так как вызов Button->Show(FALSE) приведет к полному убиранию картинки с кнопки тулбара(image)...
...вместо того, чтобы сделать картинку за-дисабленной...
Здравствуйте, Alex_st, Вы писали:
A_>день добрый всем! A_>Возникла необходимость заменить в приложении CToolBar на CMFCToolBar вроде все более менее понятно кроме одного: подскажите как дезаблить / енаблить кнопки на этом тулбаре не используя ON_UPDATE_COMAND_UI перепробовал уже кучу танцев с разными бубнами, пока ничего не получается
В общем похоже, что самый верный вариант — именно использование ON_UPDATE_COMAND_UI
Хотя, конечно, это немного связывает руки при разработке...
Здравствуйте, AlexGin, Вы писали:
AG>Здравствуйте, Alex_st, Вы писали:
A_>>день добрый всем! A_>>Возникла необходимость заменить в приложении CToolBar на CMFCToolBar вроде все более менее понятно кроме одного: подскажите как дезаблить / енаблить кнопки на этом тулбаре не используя ON_UPDATE_COMAND_UI перепробовал уже кучу танцев с разными бубнами, пока ничего не получается
AG>В общем похоже, что самый верный вариант — именно использование ON_UPDATE_COMAND_UI AG>Хотя, конечно, это немного связывает руки при разработке...
мда, т.е. самая главная проблемма: получается я не могу создать CMFCToolBar динамически, добавив на него нужные мне кнопки, все новые тулбары должны быть в ресурсах
Здравствуйте, Alex_st, Вы писали:
A_>мда, т.е. самая главная проблемма: получается я не могу создать CMFCToolBar динамически, добавив на него нужные мне кнопки, все новые тулбары должны быть в ресурсах
Кнопки можно добавлять и убирать динамически на уже существующем тулбаре
Здравствуйте, SаNNy, Вы писали:
SNN>Кнопки можно добавлять и убирать динамически на уже существующем тулбаре
насколько я понял, даже на существующий тулбар новую кнопку, т.е. такую. которой не было в ресурсе. нормально не добавишь. а убирать существующие, и потом ставить их обратно можно
Здравствуйте, Alex_st, Вы писали:
A_>Здравствуйте, SаNNy, Вы писали:
SNN>>Кнопки можно добавлять и убирать динамически на уже существующем тулбаре A_>насколько я понял, даже на существующий тулбар новую кнопку, т.е. такую. которой не было в ресурсе. нормально не добавишь. а убирать существующие, и потом ставить их обратно можно
В библиотеке от BCGSoft (а MFCToolbar это тоже самое, т.к. Microsoft купил у них лицензию) это делается так: