X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a2327a9f80fa3240ab652da8f95a66b5c25576de..c13cace12594b37706e9520a6fbd602c949f8127:/src/msw/tbar95.cpp diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index e101ced821..589df6cf67 100644 --- a/src/msw/tbar95.cpp +++ b/src/msw/tbar95.cpp @@ -35,6 +35,7 @@ #include "wx/dynarray.h" #include "wx/settings.h" #include "wx/bitmap.h" + #include "wx/dcmemory.h" #endif #if wxUSE_TOOLBAR && defined(__WIN95__) && wxUSE_TOOLBAR_NATIVE @@ -60,6 +61,18 @@ #include "wx/msw/dib.h" #include "wx/app.h" // for GetComCtl32Version +// ---------------------------------------------------------------------------- +// conditional compilation +// ---------------------------------------------------------------------------- + +// wxWindows previously always considered that toolbar buttons have light grey +// (0xc0c0c0) background and so ignored any bitmap masks - however, this +// doesn't work with XPMs which then appear to have black background. To make +// this work, we must respect the bitmap masks - which we do now. This should +// be ok in any case, but to restore 100% compatible with the old version +// behaviour, you can set this to 0. +#define USE_BITMAP_MASKS 1 + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -95,13 +108,14 @@ // private function prototypes // ---------------------------------------------------------------------------- +// adjust toolbar bitmap colours static void wxMapBitmap(HBITMAP hBitmap, int width, int height); // ---------------------------------------------------------------------------- // wxWin macros // ---------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl) +IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase) BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent) @@ -245,7 +259,18 @@ bool wxToolBar::Create(wxWindow *parent, wxToolBar::~wxToolBar() { - if (m_hBitmap) + // we must refresh the frame size when the toolbar is deleted but the frame + // is not - otherwise toolbar leaves a hole in the place it used to occupy + // + // NB: a frame is being deleted only if it is not any longer in + // wxTopLevelWindows list + wxFrame *frame = wxDynamicCast(GetParent(), wxFrame); + if ( frame && wxTopLevelWindows.Find(frame) ) + { + frame->SendSizeEvent(); + } + + if ( m_hBitmap ) { ::DeleteObject((HBITMAP) m_hBitmap); } @@ -267,8 +292,32 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool) { - // normally, we only delete one button, but we use several separators to - // cover the space used by one control sometimes (with old comctl32.dll) + // the main difficulty we have here is with the controls in the toolbars: + // as we (sometimes) use several separators to cover up the space used by + // them, the indices are not the same for us and the toolbar + + // first determine the position of the first button to delete: it may be + // different from pos if we use several separators to cover the space used + // by a control + wxToolBarToolsList::Node *node; + for ( node = m_tools.GetFirst(); node; node = node->GetNext() ) + { + wxToolBarToolBase *tool2 = node->GetData(); + if ( tool2 == tool ) + { + // let node point to the next node in the list + node = node->GetNext(); + + break; + } + + if ( tool2->IsControl() ) + { + pos += ((wxToolBarTool *)tool2)->GetSeparatorsCount(); + } + } + + // now determine the number of buttons to delete and the area taken by them size_t nButtonsToDelete = 1; // get the size of the button we're going to delete @@ -287,11 +336,13 @@ bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool) width *= nButtonsToDelete; } + // do delete all buttons + m_nButtons -= nButtonsToDelete; while ( nButtonsToDelete-- > 0 ) { if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, pos, 0) ) { - wxLogLastError("TB_DELETEBUTTON"); + wxLogLastError(wxT("TB_DELETEBUTTON")); return FALSE; } @@ -299,11 +350,9 @@ bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool) tool->Detach(); - m_nButtons -= nButtonsToDelete; - - // reposition all the controls after this button - wxToolBarToolsList::Node *node = m_tools.Item(pos); - for ( node = node->GetNext(); node; node = node->GetNext() ) + // and finally reposition all the controls after this button (the toolbar + // takes care of all normal items) + for ( /* node -> first after deleted */ ; node; node = node->GetNext() ) { wxToolBarToolBase *tool2 = node->GetData(); if ( tool2->IsControl() ) @@ -339,7 +388,17 @@ bool wxToolBar::Realize() int totalBitmapWidth = (int)(m_defaultWidth * nTools); int totalBitmapHeight = (int)m_defaultHeight; - // Create a bitmap for all the tool bitmaps + // Create a bitmap and copy all the tool bitmaps to it +#if USE_BITMAP_MASKS + wxMemoryDC dcAllButtons; + wxBitmap bitmap(totalBitmapWidth, totalBitmapHeight); + dcAllButtons.SelectObject(bitmap); + dcAllButtons.SetBackground(*wxLIGHT_GREY_BRUSH); + dcAllButtons.Clear(); + + m_hBitmap = bitmap.GetHBITMAP(); + HBITMAP hBitmap = (HBITMAP)m_hBitmap; +#else // !USE_BITMAP_MASKS HBITMAP hBitmap = ::CreateCompatibleBitmap(ScreenHDC(), totalBitmapWidth, totalBitmapHeight); @@ -352,11 +411,11 @@ bool wxToolBar::Realize() m_hBitmap = (WXHBITMAP)hBitmap; - // Now blit all the tools onto this bitmap HDC memoryDC = ::CreateCompatibleDC(NULL); HBITMAP oldBitmap = (HBITMAP) ::SelectObject(memoryDC, hBitmap); HDC memoryDC2 = ::CreateCompatibleDC(NULL); +#endif // USE_BITMAP_MASKS/!USE_BITMAP_MASKS // the button position wxCoord x = 0; @@ -370,17 +429,23 @@ bool wxToolBar::Realize() wxToolBarToolBase *tool = node->GetData(); if ( tool->IsButton() ) { - HBITMAP hbmp = GetHbitmapOf(tool->GetBitmap1()); - if ( hbmp ) + const wxBitmap& bmp = tool->GetBitmap1(); + if ( bmp.Ok() ) { +#if USE_BITMAP_MASKS + // notice the last parameter: do use mask + dcAllButtons.DrawBitmap(tool->GetBitmap1(), x, 0, TRUE); +#else // !USE_BITMAP_MASKS + HBITMAP hbmp = GetHbitmapOf(bmp); HBITMAP oldBitmap2 = (HBITMAP)::SelectObject(memoryDC2, hbmp); if ( !BitBlt(memoryDC, x, 0, m_defaultWidth, m_defaultHeight, memoryDC2, 0, 0, SRCCOPY) ) { - wxLogLastError("BitBlt"); + wxLogLastError(wxT("BitBlt")); } ::SelectObject(memoryDC2, oldBitmap2); +#endif // USE_BITMAP_MASKS/!USE_BITMAP_MASKS } else { @@ -397,9 +462,16 @@ bool wxToolBar::Realize() node = node->GetNext(); } +#if USE_BITMAP_MASKS + dcAllButtons.SelectObject(wxNullBitmap); + + // don't delete this HBITMAP! + bitmap.SetHBITMAP(0); +#else // !USE_BITMAP_MASKS ::SelectObject(memoryDC, oldBitmap); ::DeleteDC(memoryDC); ::DeleteDC(memoryDC2); +#endif // USE_BITMAP_MASKS/!USE_BITMAP_MASKS // Map to system colours wxMapBitmap(hBitmap, totalBitmapWidth, totalBitmapHeight); @@ -446,7 +518,7 @@ bool wxToolBar::Realize() { if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, 0, 0) ) { - wxLogLastError("TB_DELETEBUTTON"); + wxLogLastError(wxT("TB_DELETEBUTTON")); } } @@ -518,7 +590,7 @@ bool wxToolBar::Realize() if ( !::SendMessage(GetHwnd(), TB_ADDBUTTONS, (WPARAM)i, (LPARAM)buttons) ) { - wxLogLastError("TB_ADDBUTTONS"); + wxLogLastError(wxT("TB_ADDBUTTONS")); } delete [] buttons; @@ -547,7 +619,7 @@ bool wxToolBar::Realize() if ( !SendMessage(GetHwnd(), TB_GETITEMRECT, index, (LPARAM)(LPRECT)&r) ) { - wxLogLastError("TB_GETITEMRECT"); + wxLogLastError(wxT("TB_GETITEMRECT")); } // TB_SETBUTTONINFO message is only supported by comctl32.dll 4.71+ @@ -566,7 +638,7 @@ bool wxToolBar::Realize() tool->GetId(), (LPARAM)&tbbi) ) { // the id is probably invalid? - wxLogLastError("TB_SETBUTTONINFO"); + wxLogLastError(wxT("TB_SETBUTTONINFO")); } } else @@ -580,7 +652,7 @@ bool wxToolBar::Realize() TBBUTTON tbb; wxZeroMemory(tbb); tbb.idCommand = 0; - tbb.fsState = TBSTATE_ENABLED | TBSTATE_HIDDEN; + tbb.fsState = TBSTATE_ENABLED; tbb.fsStyle = TBSTYLE_SEP; size_t nSeparators = size.x / widthSep; @@ -589,7 +661,7 @@ bool wxToolBar::Realize() if ( !SendMessage(GetHwnd(), TB_INSERTBUTTON, index, (LPARAM)&tbb) ) { - wxLogLastError("TB_INSERTBUTTON"); + wxLogLastError(wxT("TB_INSERTBUTTON")); } index++; @@ -705,11 +777,17 @@ bool wxToolBar::MSWOnNotify(int WXUNUSED(idCtrl), { ttText->lpszText = (wxChar *)help.c_str(); } -#if (_WIN32_IE >= 0x0300) else { - // FIXME this is a temp hack only until I understand better what - // must be done in both ANSI and Unicode builds +#if wxUSE_UNICODE + ttText->lpszText = (wxChar *)help.c_str(); +#else + // VZ: I don't know why it happens, but the versions of + // comctl32.dll starting from 4.70 sometimes send TTN_NEEDTEXTW + // even to ANSI programs (normally, this message is supposed + // to be sent to Unicode programs only) - hence we need to + // handle it as well, otherwise no tooltips will be shown in + // this case size_t lenAnsi = help.Len(); #ifdef __MWERKS__ @@ -730,8 +808,8 @@ bool wxToolBar::MSWOnNotify(int WXUNUSED(idCtrl), dst[lenUnicode] = 0; delete [] pwz; +#endif } -#endif // _WIN32_IE >= 0x0300 } // For backward compatibility... @@ -814,15 +892,7 @@ void wxToolBar::UpdateSize() wxFrame *frame = wxDynamicCast(GetParent(), wxFrame); if ( frame ) { - // don't change the size, we just need to generate a WM_SIZE - RECT r; - if ( !GetWindowRect(GetHwndOf(frame), &r) ) - { - wxLogLastError(_T("GetWindowRect")); - } - - (void)::SendMessage(GetHwndOf(frame), WM_SIZE, SIZE_RESTORED, - MAKELPARAM(r.right - r.left, r.bottom - r.top)); + frame->SendSizeEvent(); } }