Выход нашёлся, не знаю насколько прямой, оцените его прямость/кривость.
На Исходниках.Ру нашёлся класс CToolBarEx который позволяет в тулбар пихать комбо и любые другие элементы. Там во внутренностях наткнулся на следующие private функции (глюки уже исправил - там нехватало пару условий для нормальной работы):
void CToolBarEx::_GetButton(int nIndex, TBBUTTON* pButton) const
{
CToolBarEx* pBar = (CToolBarEx*)this;
VERIFY(pBar->DefWindowProc(TB_GETBUTTON, nIndex, (LPARAM)pButton));
// TBSTATE_ENABLED == TBBS_DISABLED so invert it
if ((pButton->fsState & TBSTATE_ENABLED)==0) // was TBBS_DISABLED без этого условия всё работает довольно таки криво
pButton->fsState^=TBBS_DISABLED;
}
void CToolBarEx::_SetButton(int nIndex, TBBUTTON* pButton)
{
// get original button state
TBBUTTON button;
VERIFY(DefWindowProc(TB_GETBUTTON, nIndex, (LPARAM)&button));
// prepare for old/new button comparsion
button.bReserved[0] = 0;
button.bReserved[1] = 0;
// TBSTATE_ENABLED == TBBS_DISABLED so invert it
if ((pButton->fsState & TBSTATE_ENABLED)==1) // was TBSTATE_ENABLED без этого условия всё работает довольно таки криво
pButton->fsState ^= TBSTATE_ENABLED;
pButton->bReserved[0] = 0;
pButton->bReserved[1] = 0;
// nothing to do if they are the same
if (memcmp(pButton, &button, sizeof(TBBUTTON)) != 0)
{
// don't redraw everything while setting the button
DWORD dwStyle = GetStyle();
ModifyStyle(WS_VISIBLE, 0);
VERIFY(DefWindowProc(TB_DELETEBUTTON, nIndex, 0));
VERIFY(DefWindowProc(TB_INSERTBUTTON, nIndex, (LPARAM)pButton));
ModifyStyle(0, dwStyle & WS_VISIBLE);
// invalidate appropriate parts
if (((pButton->fsStyle ^ button.fsStyle) & TBSTYLE_SEP) ||
((pButton->fsStyle & TBSTYLE_SEP) && pButton->iBitmap != button.iBitmap))
{
// changing a separator
Invalidate();
}
else
{
// invalidate just the button
CRect rect;
if (DefWindowProc(TB_GETITEMRECT, nIndex, (LPARAM)&rect))
InvalidateRect(rect);
}
}
теперь обращаюсь к этим функциям. (где-то в классе объявил TBBUTTON pConnectBtn, pStartBtn, pPauseBtn, pStopBtn;)
1. При инициализации
pConnectBtn.fsState=TBSTATE_ENABLED;
pStartBtn.fsState=TBSTATE_ENABLED;
pPauseBtn.fsState=TBSTATE_HIDDEN;
m_wndToolBar._SetButton(2,&pConnectBtn);
m_wndToolBar._SetButton(6,&pStartBtn);
m_wndToolBar._SetButton(7,&pPauseBtn);
m_wndToolBar._SetButton(8,&pStopBtn);
если не хотим скрывать кнопки, а только блокировать, то пишем pPauseBtn.fsState=0; (вместо TBSTATE_HIDDEN)
2. При нажатии на кнопку PLAY:
pStartBtn.fsState=TBSTATE_HIDDEN;
pPauseBtn.fsState=TBSTATE_ENABLED;
m_wndToolBar._SetButton(6,&pStartBtn); // 6 - позиция кнопки Start на тулбаре
m_wndToolBar._SetButton(7,&pPauseBtn); // 7 - позиция кнопки Pause на тулбаре
3. При нажатии на кнопку PAUSE и STOP:
pPauseBtn.fsState=TBSTATE_HIDDEN;
pStartBtn.fsState=TBSTATE_ENABLED;
m_wndToolBar._SetButton(6,&pStartBtn);
m_wndToolBar._SetButton(7,&pPauseBtn);
Прошу прокомментировать кривость данного подхода (в особенности какое влияние на устойчивость системы может, например, оказать).