CMFCToolBar button
От: Alex_st Россия  
Дата: 27.11.14 14:01
Оценка:
день добрый всем!
Возникла необходимость заменить в приложении CToolBar на CMFCToolBar вроде все более менее понятно кроме одного: подскажите как дезаблить / енаблить кнопки на этом тулбаре не используя ON_UPDATE_COMAND_UI перепробовал уже кучу танцев с разными бубнами, пока ничего не получается
Re: CMFCToolBar button
От: AlexGin Беларусь  
Дата: 28.11.14 16:28
Оценка:
Здравствуйте, Alex_st, Вы писали:

A_>день добрый всем!

A_>Возникла необходимость заменить в приложении CToolBar на CMFCToolBar вроде все более менее понятно кроме одного: подскажите как дезаблить / енаблить кнопки на этом тулбаре не используя ON_UPDATE_COMAND_UI перепробовал уже кучу танцев с разными бубнами, пока ничего не получается

1) В чем проблема применения ON_UPDATE_COMMAND_UI(..., ...)?
2) Что мешает вызвать CMFCToolBar::GetAllButtons(); — этот вызов заполнит коллекцию кнопок CObList — а в ней уже находить нужную кнопку (объект типа CMFCToolBarButton) и для нее вызывать EnableWindow(FALSE/TRUE)?
3) Возможно, есть еще какие-либо варианты решения данного вопроса.

P.S. Я нашел рекомендацию:
https://social.msdn.microsoft.com/Forums/en-US/a1eae56a-0c57-4011-b799-8dd57e6be99d/how-do-i-disablereenable-a-cmfctoolbarbutton-in-a-cmfctoolbar?forum=vcmfcatl — может она чем то поможет.

Вопрос — тулбар применяется как основной (в окне наследнике CFrameWndEx/CMDIFrameWndEx) или же в dockable-окне?

Если это основной тулбар, то, возможно, поможет вот такое решение:
http://www.codeproject.com/Questions/205114/disable-buttons-in-CMFCToolbar
Отредактировано 28.11.2014 16:40 AlexGin . Предыдущая версия . Еще …
Отредактировано 28.11.2014 16:35 AlexGin . Предыдущая версия .
Re[2]: CMFCToolBar button
От: Alex_st Россия  
Дата: 01.12.14 09:53
Оценка:
Здравствуйте, AlexGin, Вы писали:


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`е
Re[3]: CMFCToolBar button
От: AlexGin Беларусь  
Дата: 01.12.14 12:05
Оценка:
Здравствуйте, 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) тут не пройдет

http://msdn.microsoft.com/en-us/library/bb983678.aspx

Поэтому — приходится извращаться...
Отредактировано 01.12.2014 12:09 AlexGin . Предыдущая версия . Еще …
Отредактировано 01.12.2014 12:06 AlexGin . Предыдущая версия .
Re[4]: CMFCToolBar button
От: Alex_st Россия  
Дата: 01.12.14 12:41
Оценка:
Здравствуйте, AlexGin, Вы писали:

AG>Дело в том, что объект CMFCToolBarButton — это наследник CObject, а не CWnd.

AG>То есть — вызов EnableWindow(FALSE/TRUE) тут не пройдет

AG>Поэтому — приходится извращаться...

вот сделали жа гемороя.
подмена картинок кнопки все-равно оставит ее активной, она будет нажиматься, будет меняться про наведении мыши.
пробовал даже стили менять
    int idx = pToolBar->CommandToIndex (nID);
    if (idx == -1) 
        return;
    UINT iStyle = pToolBar->GetButtonStyle (idx);
    if (bStatus) 
    {
        pToolBar->SetButtonStyle (idx, iStyle & !TBSTATE_ENABLED);
    }
    else 
    {
        pToolBar->SetButtonStyle (idx, iStyle | TBSTATE_ENABLED);
    }
    pToolBar->InvalidateButton(idx);

не помогает
Re[5]: CMFCToolBar button
От: AlexGin Беларусь  
Дата: 01.12.14 13:47
Оценка:
Здравствуйте, 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)...
...вместо того, чтобы сделать картинку за-дисабленной...
Re: CMFCToolBar button
От: AlexGin Беларусь  
Дата: 01.12.14 14:01
Оценка:
Здравствуйте, Alex_st, Вы писали:

A_>день добрый всем!

A_>Возникла необходимость заменить в приложении CToolBar на CMFCToolBar вроде все более менее понятно кроме одного: подскажите как дезаблить / енаблить кнопки на этом тулбаре не используя ON_UPDATE_COMAND_UI перепробовал уже кучу танцев с разными бубнами, пока ничего не получается

В общем похоже, что самый верный вариант — именно использование ON_UPDATE_COMAND_UI
Хотя, конечно, это немного связывает руки при разработке...
Re[2]: CMFCToolBar button
От: Alex_st Россия  
Дата: 02.12.14 09:19
Оценка:
Здравствуйте, AlexGin, Вы писали:

AG>Здравствуйте, Alex_st, Вы писали:


A_>>день добрый всем!

A_>>Возникла необходимость заменить в приложении CToolBar на CMFCToolBar вроде все более менее понятно кроме одного: подскажите как дезаблить / енаблить кнопки на этом тулбаре не используя ON_UPDATE_COMAND_UI перепробовал уже кучу танцев с разными бубнами, пока ничего не получается

AG>В общем похоже, что самый верный вариант — именно использование ON_UPDATE_COMAND_UI

AG>Хотя, конечно, это немного связывает руки при разработке...
мда, т.е. самая главная проблемма: получается я не могу создать CMFCToolBar динамически, добавив на него нужные мне кнопки, все новые тулбары должны быть в ресурсах
Re[3]: CMFCToolBar button
От: SаNNy Россия  
Дата: 02.12.14 10:03
Оценка:
Здравствуйте, Alex_st, Вы писали:

A_>мда, т.е. самая главная проблемма: получается я не могу создать CMFCToolBar динамически, добавив на него нужные мне кнопки, все новые тулбары должны быть в ресурсах


Кнопки можно добавлять и убирать динамически на уже существующем тулбаре
Re[4]: CMFCToolBar button
От: Alex_st Россия  
Дата: 02.12.14 11:02
Оценка:
Здравствуйте, SаNNy, Вы писали:

SNN>Кнопки можно добавлять и убирать динамически на уже существующем тулбаре

насколько я понял, даже на существующий тулбар новую кнопку, т.е. такую. которой не было в ресурсе. нормально не добавишь. а убирать существующие, и потом ставить их обратно можно
Re[5]: CMFCToolBar button
От: SаNNy Россия  
Дата: 02.12.14 11:50
Оценка:
Здравствуйте, Alex_st, Вы писали:

A_>Здравствуйте, SаNNy, Вы писали:


SNN>>Кнопки можно добавлять и убирать динамически на уже существующем тулбаре

A_>насколько я понял, даже на существующий тулбар новую кнопку, т.е. такую. которой не было в ресурсе. нормально не добавишь. а убирать существующие, и потом ставить их обратно можно

В библиотеке от BCGSoft (а MFCToolbar это тоже самое, т.к. Microsoft купил у них лицензию) это делается так:
m_wndToolBar.RemoveButton(m_wndToolBar.CommandToIndex(ID_APP_DATEFROM)); // удаление кнопки

m_wndToolBar.InsertButton(CToolbarLabel(ID_LABEL_TO, L"по:"), nLabelViewIndx + 3); // добавление кнопки
m_wndToolBar.InsertSeparator(nLabelViewIndx + 6); // добавление сепаратора
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.