+ // this array will hold the indices of all controls in the toolbar
+ wxArrayInt controlIds;
+
+ int i = 0;
+ for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
+ {
+ wxToolBarToolBase *tool = node->GetData();
+
+ // don't add separators to the vertical toolbar - looks ugly
+ if ( isVertical && tool->IsSeparator() )
+ continue;
+
+ TBBUTTON& button = buttons[i];
+
+ wxZeroMemory(button);
+
+ switch ( tool->GetStyle() )
+ {
+ case wxTOOL_STYLE_CONTROL:
+ button.idCommand = tool->GetId();
+ // fall through: create just a separator too
+
+ case wxTOOL_STYLE_SEPARATOR:
+ button.fsState = TBSTATE_ENABLED;
+ button.fsStyle = TBSTYLE_SEP;
+ break;
+
+ case wxTOOL_STYLE_BUTTON:
+ button.iBitmap = bitmapId;
+ button.idCommand = tool->GetId();
+
+ if ( tool->IsEnabled() )
+ button.fsState |= TBSTATE_ENABLED;
+ if ( tool->IsToggled() )
+ button.fsState |= TBSTATE_CHECKED;
+
+ button.fsStyle = tool->CanBeToggled() ? TBSTYLE_CHECK
+ : TBSTYLE_BUTTON;
+
+ bitmapId++;
+ break;
+ }
+
+ i++;
+ }
+
+ if ( !::SendMessage(GetHwnd(), TB_ADDBUTTONS,
+ (WPARAM)i, (LPARAM)buttons) )
+ {
+ wxLogLastError("TB_ADDBUTTONS");
+ }
+
+ delete [] buttons;
+
+ // Deal with the controls finally
+ // ------------------------------
+
+ // adjust the controls size to fit nicely in the toolbar
+ size_t index = 0;
+ for ( node = m_tools.GetFirst(); node; node = node->GetNext(), index++ )
+ {
+ wxToolBarToolBase *tool = node->GetData();
+ if ( !tool->IsControl() )
+ continue;
+
+ wxControl *control = tool->GetControl();
+
+ wxSize size = control->GetSize();
+
+ // the position of the leftmost controls corner
+ int left = -1;
+
+ // note that we use TB_GETITEMRECT and not TB_GETRECT because the
+ // latter only appeared in v4.70 of comctl32.dll
+ RECT r;
+ if ( !SendMessage(GetHwnd(), TB_GETITEMRECT,
+ index, (LPARAM)(LPRECT)&r) )
+ {
+ wxLogLastError("TB_GETITEMRECT");
+ }
+
+ // TB_SETBUTTONINFO message is only supported by comctl32.dll 4.71+
+ #if defined(_WIN32_IE) && (_WIN32_IE >= 0x400 )
+ // available in headers, now check whether it is available now
+ // (during run-time)
+ if ( wxTheApp->GetComCtl32Version() >= 471 )
+ {
+ // set the (underlying) separators width to be that of the
+ // control
+ TBBUTTONINFO tbbi;
+ tbbi.cbSize = sizeof(tbbi);
+ tbbi.dwMask = TBIF_SIZE;
+ tbbi.cx = size.x;
+ if ( !SendMessage(GetHwnd(), TB_SETBUTTONINFO,
+ tool->GetId(), (LPARAM)&tbbi) )
+ {
+ // the id is probably invalid?
+ wxLogLastError("TB_SETBUTTONINFO");
+ }
+ }
+ else
+ #endif // comctl32.dll 4.71
+ // TB_SETBUTTONINFO unavailable
+ {
+ // try adding several separators to fit the controls width
+ int widthSep = r.right - r.left;
+ left = r.left;
+
+ TBBUTTON tbb;
+ wxZeroMemory(tbb);
+ tbb.idCommand = 0;
+ tbb.fsState = TBSTATE_ENABLED | TBSTATE_HIDDEN;
+ tbb.fsStyle = TBSTYLE_SEP;
+
+ size_t nSeparators = size.x / widthSep;
+ for ( size_t nSep = 0; nSep < nSeparators; nSep++ )
+ {
+ if ( !SendMessage(GetHwnd(), TB_INSERTBUTTON,
+ index, (LPARAM)&tbb) )
+ {
+ wxLogLastError("TB_INSERTBUTTON");
+ }
+
+ index++;
+ }
+
+ // remember the number of separators we used - we'd have to
+ // delete all of them later
+ ((wxToolBarTool *)tool)->SetSeparatorsCount(nSeparators);
+
+ // adjust the controls width to exactly cover the separators
+ control->SetSize((nSeparators + 1)*widthSep, -1);
+ }
+
+ // and position the control itself correctly vertically
+ int height = r.bottom - r.top;
+ int diff = height - size.y;
+ if ( diff < 0 )
+ {
+ // the control is too high, resize to fit
+ control->SetSize(-1, height - 2);
+
+ diff = 2;
+ }
+
+ control->Move(left == -1 ? r.left : left, r.top + (diff + 1) / 2);
+ }
+
+ // the max index is the "real" number of buttons - i.e. counting even the
+ // separators which we added just for aligning the controls
+ m_nButtons = index;
+
+ if ( !isVertical )
+ {
+ if ( m_maxRows == 0 )
+ {
+ // if not set yet, only one row
+ SetRows(1);
+ }
+ }
+ else if ( m_nButtons > 0 ) // vertical non empty toolbar
+ {
+ if ( m_maxRows == 0 )
+ {
+ // if not set yet, have one column
+ SetRows(m_nButtons);
+ }
+ }
+
+ return TRUE;