X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2bda0e173844e8e0f8acf4e8ad8b5c26e5c6fe5d..f3bd1796cae0fc37a45f6b7a61b473e3ddc652ee:/src/msw/tbar95.cpp diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index ea86d42cec..3f4d814f84 100644 --- a/src/msw/tbar95.cpp +++ b/src/msw/tbar95.cpp @@ -6,7 +6,7 @@ // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -21,49 +21,70 @@ #endif #ifndef WX_PRECOMP -#include "wx.h" +#include "wx/wx.h" #endif -#if USE_BUTTONBAR && USE_TOOLBAR && defined(__WIN95__) +#if wxUSE_BUTTONBAR && wxUSE_TOOLBAR && defined(__WIN95__) -#ifndef __GNUWIN32__ +#if !defined(__GNUWIN32__) && !defined(__SALFORDC__) #include "malloc.h" #endif #include -#ifndef __GNUWIN32__ +#if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__) #include #endif +#ifndef __TWIN32__ #ifdef __GNUWIN32__ #include "wx/msw/gnuwin32/extra.h" #endif +#endif #include "wx/msw/dib.h" #include "wx/tbar95.h" #include "wx/app.h" #include "wx/msw/private.h" +// Styles +#ifndef TBSTYLE_FLAT +#define TBSTYLE_LIST 0x1000 +#define TBSTYLE_FLAT 0x0800 +#define TBSTYLE_TRANSPARENT 0x8000 +#endif + // use TBSTYLE_TRANSPARENT if you use TBSTYLE_FLAT + +// Messages +#ifndef TB_GETSTYLE +#define TB_GETSTYLE (WM_USER + 57) +#define TB_SETSTYLE (WM_USER + 56) +#endif + +/* Hint from a newsgroup for custom flatbar drawing: +Set the TBSTYLE_CUSTOMERASE style, then handle the +NM_CUSTOMDRAW message and do your custom drawing. +*/ + +#define DEFAULTBITMAPX 16 +#define DEFAULTBITMAPY 15 +#define DEFAULTBUTTONX 24 +#define DEFAULTBUTTONY 24 +#define DEFAULTBARHEIGHT 27 + #if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxToolBar95, wxToolBarBase) +#endif BEGIN_EVENT_TABLE(wxToolBar95, wxToolBarBase) - EVT_SIZE(wxToolBar95::OnSize) - EVT_PAINT(wxToolBar95::OnPaint) - EVT_KILL_FOCUS(wxToolBar95::OnKillFocus) - EVT_MOUSE_EVENTS(wxToolBar95::OnMouseEvent) + EVT_MOUSE_EVENTS(wxToolBar95::OnMouseEvent) EVT_SYS_COLOUR_CHANGED(wxToolBar95::OnSysColourChanged) END_EVENT_TABLE() -#endif -void wxMapBitmap(HBITMAP hBitmap, int width, int height); +static void wxMapBitmap(HBITMAP hBitmap, int width, int height); -wxToolBar95::wxToolBar95(void) +wxToolBar95::wxToolBar95() { - m_tilingDirection = wxVERTICAL ; - m_rowsOrColumns = 0; - m_currentRowsOrColumns = 0; m_maxWidth = -1; m_maxHeight = -1; m_hBitmap = 0; @@ -71,48 +92,41 @@ wxToolBar95::wxToolBar95(void) m_defaultHeight = DEFAULTBITMAPY; } -bool wxToolBar95::Create(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, - const long style, const int orientation, - const int RowsOrColumns, const wxString& name) +bool wxToolBar95::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) { m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)), - GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE))); + GetGValue(GetSysColor(COLOR_BTNFACE)), + GetBValue(GetSysColor(COLOR_BTNFACE))); m_foregroundColour = *wxBLACK ; - m_defaultForegroundColour = *wxBLACK ; - m_defaultBackgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)), - GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE))); + wxASSERT_MSG( (style & wxTB_VERTICAL) == 0, + "Sorry, wxToolBar95 under Windows 95 only " + "supports horizontal orientation." ); - m_tilingDirection = orientation; - if (m_tilingDirection == wxHORIZONTAL) - wxMessageBox("Sorry, wxToolBar95 under Windows 95 only supports vertical tiling.\nPass the number of rows.", "wxToolBar95 usage", wxOK); - m_rowsOrColumns = RowsOrColumns; - m_currentRowsOrColumns = 0; m_maxWidth = -1; m_maxHeight = -1; - + m_hBitmap = 0; m_defaultWidth = DEFAULTBITMAPX; m_defaultHeight = DEFAULTBITMAPY; SetName(name); + m_windowStyle = style; + + SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + SetParent(parent); + int x = pos.x; int y = pos.y; int width = size.x; int height = size.y; - m_windowStyle = style; - - SetFont(wxTheFontList->FindOrCreateFont(11, wxSWISS, wxNORMAL, wxNORMAL)); - - SetParent(parent); - - DWORD msflags = 0; - if (style & wxBORDER) - msflags |= WS_BORDER; - msflags |= WS_CHILD | WS_VISIBLE; - if (width <= 0) width = 100; if (height <= 0) @@ -123,30 +137,55 @@ bool wxToolBar95::Create(wxWindow *parent, const wxWindowID id, const wxPoint& p y = 0; m_windowId = (id < 0 ? NewControlId() : id); + DWORD msflags = 0; + if (style & wxBORDER) + msflags |= WS_BORDER; + msflags |= WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS; + + if (style & wxTB_FLAT) + { + if (wxTheApp->GetComCtl32Version() > 400) + msflags |= TBSTYLE_FLAT; + } + + bool want3D; + WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ; + + // Even with extended styles, need to combine with WS_BORDER + // for them to look right. + if ( want3D || wxStyleHasBorder(m_windowStyle) ) + msflags |= WS_BORDER; // Create the toolbar control. - HWND hWndToolbar = CreateWindowEx(0L, // No extended styles. - TOOLBARCLASSNAME, // Class name for the toolbar. - "", // No default text. - WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS, // Styles and defaults. - x, y, width, height, // Standard toolbar size and position. - (HWND) parent->GetHWND(), // Parent window of the toolbar. - (HMENU)m_windowId, // Toolbar ID. - wxGetInstance(), // Current instance. - NULL ); // No class data. + HWND hWndToolbar = CreateWindowEx + ( + exStyle, // Extended styles. + TOOLBARCLASSNAME, // Class name for the toolbar. + "", // No default text. + msflags, // Styles + x, y, width, height, // Standard toolbar size and position. + (HWND) parent->GetHWND(), // Parent window of the toolbar. + (HMENU)m_windowId, // Toolbar ID. + wxGetInstance(), // Current instance. + NULL // No class data. + ); + + wxCHECK_MSG( hWndToolbar, FALSE, "Toolbar creation failed" ); // Toolbar-specific initialisation - ::SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), (LPARAM)0); + ::SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, + (WPARAM)sizeof(TBBUTTON), (LPARAM)0); m_hWnd = (WXHWND) hWndToolbar; - if (parent) parent->AddChild(this); - - SubclassWin((WXHWND) hWndToolbar); + if (parent) + parent->AddChild(this); + + SubclassWin((WXHWND)hWndToolbar); return TRUE; } -wxToolBar95::~wxToolBar95(void) +wxToolBar95::~wxToolBar95() { UnsubclassWin(); @@ -157,13 +196,13 @@ wxToolBar95::~wxToolBar95(void) } } -bool wxToolBar95::CreateTools(void) +bool wxToolBar95::CreateTools() { if (m_tools.Number() == 0) return FALSE; HBITMAP oldToolBarBitmap = (HBITMAP) m_hBitmap; - + int totalBitmapWidth = (int)(m_defaultWidth * m_tools.Number()); int totalBitmapHeight = (int)m_defaultHeight; @@ -171,10 +210,10 @@ bool wxToolBar95::CreateTools(void) HDC dc = ::GetDC(NULL); m_hBitmap = (WXHBITMAP) ::CreateCompatibleBitmap(dc, totalBitmapWidth, totalBitmapHeight); ::ReleaseDC(NULL, dc); - + // Now blit all the tools onto this bitmap HDC memoryDC = ::CreateCompatibleDC(NULL); - HBITMAP oldBitmap = ::SelectObject(memoryDC, (HBITMAP) m_hBitmap); + HBITMAP oldBitmap = (HBITMAP) ::SelectObject(memoryDC, (HBITMAP) m_hBitmap); HDC memoryDC2 = ::CreateCompatibleDC(NULL); int x = 0; @@ -187,9 +226,9 @@ bool wxToolBar95::CreateTools(void) { // wxPalette *palette = tool->m_bitmap1->GetPalette(); - HBITMAP oldBitmap2 = ::SelectObject(memoryDC2, (HBITMAP) tool->m_bitmap1.GetHBITMAP()); + HBITMAP oldBitmap2 = (HBITMAP) ::SelectObject(memoryDC2, (HBITMAP) tool->m_bitmap1.GetHBITMAP()); /* int bltResult = */ - BitBlt(memoryDC, x, 0, (int) m_defaultWidth, (int) m_defaultHeight, memoryDC2, + BitBlt(memoryDC, x, 0, (int) m_defaultWidth, (int) m_defaultHeight, memoryDC2, 0, 0, SRCCOPY); ::SelectObject(memoryDC2, oldBitmap2); x += (int)m_defaultWidth; @@ -213,7 +252,7 @@ bool wxToolBar95::CreateTools(void) replaceBitmap.nIDNew = (UINT) (HBITMAP) m_hBitmap; replaceBitmap.nButtons = noButtons; if (::SendMessage((HWND) GetHWND(), TB_REPLACEBITMAP, (WPARAM) 0, (LPARAM) &replaceBitmap) == -1) - wxMessageBox("Could not add bitmap to toolbar"); + wxFAIL_MSG("Could not add bitmap to toolbar"); ::DeleteObject((HBITMAP) oldToolBarBitmap); @@ -232,7 +271,7 @@ bool wxToolBar95::CreateTools(void) addBitmap.hInst = 0; addBitmap.nID = (UINT)m_hBitmap; if (::SendMessage((HWND) GetHWND(), TB_ADDBITMAP, (WPARAM) noButtons, (LPARAM) &addBitmap) == -1) - wxMessageBox("Could not add bitmap to toolbar"); + wxFAIL_MSG("Could not add bitmap to toolbar"); } // Now add the buttons. @@ -270,23 +309,23 @@ bool wxToolBar95::CreateTools(void) bitmapId ++; } - + i ++; node = node->Next(); } - int ans = (int)::SendMessage((HWND) GetHWND(), TB_ADDBUTTONS, (WPARAM)i, (LPARAM)& buttons); - ans = (int)::SendMessage((HWND) GetHWND(), TB_AUTOSIZE, (WPARAM)0, (LPARAM) 0); + long rc = ::SendMessage((HWND) GetHWND(), TB_ADDBUTTONS, (WPARAM)i, (LPARAM)& buttons); - RECT rect; - ::SendMessage((HWND) GetHWND(), TB_SETROWS, MAKEWPARAM(m_rowsOrColumns, TRUE), (LPARAM) & rect); - m_maxWidth = (rect.right - rect.left + 2); - m_maxHeight = (rect.bottom - rect.top + 2); + wxCHECK_MSG( rc, FALSE, "failed to add buttons to the toolbar" ); + + (void)::SendMessage((HWND) GetHWND(), TB_AUTOSIZE, (WPARAM)0, (LPARAM) 0); + + SetRows(m_maxRows); return TRUE; } -bool wxToolBar95::MSWCommand(const WXUINT cmd, const WXWORD id) +bool wxToolBar95::MSWCommand(WXUINT cmd, WXWORD id) { wxNode *node = m_tools.Find((long)id); if (!node) @@ -304,51 +343,81 @@ bool wxToolBar95::MSWCommand(const WXUINT cmd, const WXWORD id) return TRUE; } -bool wxToolBar95::MSWNotify(const WXWPARAM WXUNUSED(wParam), const WXLPARAM lParam) +bool wxToolBar95::MSWOnNotify(int WXUNUSED(idCtrl), + WXLPARAM lParam, + WXLPARAM *result) { - // First check if this applies to us + // First check if this applies to us NMHDR *hdr = (NMHDR *)lParam; - if (hdr->code != TTN_NEEDTEXT) - return FALSE; - HWND toolTipWnd = (HWND) ::SendMessage((HWND) GetHWND(), TB_GETTOOLTIPS, 0, 0); - if ( toolTipWnd != hdr->hwndFrom ) - return FALSE; + // the tooltips control created by the toolbar is sometimes Unicode, even in + // an ANSI application + if ( (hdr->code != TTN_NEEDTEXTA) && (hdr->code != TTN_NEEDTEXTW) ) + return FALSE; - LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT) lParam; - int id = (int)ttText->hdr.idFrom; - wxNode *node = m_tools.Find((long)id); - if (!node) - return FALSE; - - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); + HWND toolTipWnd = (HWND)::SendMessage((HWND)GetHWND(), TB_GETTOOLTIPS, 0, 0); + if ( toolTipWnd != hdr->hwndFrom ) + return FALSE; - switch (ttText->hdr.code) - { - case TTN_NEEDTEXT: - { - if (tool->m_shortHelpString != "") - ttText->lpszText = (char *) (const char *)tool->m_shortHelpString; + LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam; + int id = (int)ttText->hdr.idFrom; + wxNode *node = m_tools.Find((long)id); + if (!node) + return FALSE; + + wxToolBarTool *tool = (wxToolBarTool *)node->Data(); + + const wxString& help = tool->m_shortHelpString; - // For backward compatibility... - OnMouseEnter(tool->m_index); - break; + if ( !help.IsEmpty() ) + { + if ( hdr->code == TTN_NEEDTEXTA ) + { + ttText->lpszText = (char *)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 + + size_t lenAnsi = help.Len(); + #ifdef __MWERKS__ + // MetroWerks doesn't like calling mbstowcs with NULL argument + size_t lenUnicode = 2*lenAnsi; + #else + size_t lenUnicode = mbstowcs(NULL, help, lenAnsi); + #endif + + // using the pointer of right type avoids us doing all sorts of + // pointer arithmetics ourselves + wchar_t *dst = (wchar_t *)ttText->szText, + *pwz = new wchar_t[lenUnicode + 1]; + mbstowcs(pwz, help, lenAnsi + 1); + memcpy(dst, pwz, lenUnicode*sizeof(wchar_t)); + + // put the terminating _wide_ NUL + dst[lenUnicode] = 0; + + delete [] pwz; + } +#endif // _WIN32_IE >= 0x0300 } - default: - return FALSE; - break; - } - - return TRUE; + + // For backward compatibility... + OnMouseEnter(tool->m_index); + + return TRUE; } -void wxToolBar95::SetDefaultSize(const wxSize& size) +void wxToolBar95::SetToolBitmapSize(const wxSize& size) { - m_defaultWidth = size.x; m_defaultHeight = size.y; + m_defaultWidth = size.x; + m_defaultHeight = size.y; ::SendMessage((HWND) GetHWND(), TB_SETBITMAPSIZE, 0, (LPARAM) MAKELONG ((int)size.x, (int)size.y)); } -void wxToolBar95::SetRows(const int nRows) +void wxToolBar95::SetRows(int nRows) { RECT rect; ::SendMessage((HWND) GetHWND(), TB_SETROWS, MAKEWPARAM(nRows, TRUE), (LPARAM) & rect); @@ -356,12 +425,12 @@ void wxToolBar95::SetRows(const int nRows) m_maxHeight = (rect.bottom - rect.top + 2); } -wxSize wxToolBar95::GetMaxSize(void) const +wxSize wxToolBar95::GetMaxSize() const { - if (m_maxWidth == -1 | m_maxHeight == -1) + if ((m_maxWidth == -1) || (m_maxHeight == -1)) { RECT rect; - ::SendMessage((HWND) GetHWND(), TB_SETROWS, MAKEWPARAM(m_rowsOrColumns, TRUE), (LPARAM) & rect); + ::SendMessage((HWND) GetHWND(), TB_SETROWS, MAKEWPARAM(m_maxRows, TRUE), (LPARAM) & rect); ((wxToolBar95 *)this)->m_maxWidth = (rect.right - rect.left + 2); // ??? ((wxToolBar95 *)this)->m_maxHeight = (rect.bottom - rect.top + 2); // ??? } @@ -373,16 +442,17 @@ void wxToolBar95::GetSize(int *w, int *h) const wxWindow::GetSize(w, h); // For some reason, the returned height is several pixels bigger than that // displayed! - *h -= 2; + // Taking this fudge factor out now, it seems fine without it. +// *h -= 2; } // The button size is bigger than the bitmap size -wxSize wxToolBar95::GetDefaultButtonSize(void) const +wxSize wxToolBar95::GetToolSize() const { return wxSize(m_defaultWidth + 8, m_defaultHeight + 7); } -void wxToolBar95::EnableTool(const int toolIndex, const bool enable) +void wxToolBar95::EnableTool(int toolIndex, bool enable) { wxNode *node = m_tools.Find((long)toolIndex); if (node) @@ -393,7 +463,7 @@ void wxToolBar95::EnableTool(const int toolIndex, const bool enable) } } -void wxToolBar95::ToggleTool(const int toolIndex, const bool toggle) +void wxToolBar95::ToggleTool(int toolIndex, bool toggle) { wxNode *node = m_tools.Find((long)toolIndex); if (node) @@ -407,7 +477,12 @@ void wxToolBar95::ToggleTool(const int toolIndex, const bool toggle) } } -void wxToolBar95::ClearTools(void) +bool wxToolBar95::GetToolState(int toolIndex) const +{ + return (::SendMessage((HWND) GetHWND(), TB_ISBUTTONCHECKED, (WPARAM)toolIndex, (LPARAM)0) != 0); +} + +void wxToolBar95::ClearTools() { // TODO: Don't know how to reset the toolbar bitmap, as yet. // But adding tools and calling CreateTools should probably @@ -418,10 +493,10 @@ void wxToolBar95::ClearTools(void) // If pushedBitmap is NULL, a reversed version of bitmap is // created and used as the pushed/toggled image. // If toggle is TRUE, the button toggles between the two states. -wxToolBarTool *wxToolBar95::AddTool(const int index, const wxBitmap& bitmap, const wxBitmap& pushedBitmap, - const bool toggle, const long xPos, const long yPos, wxObject *clientData, const wxString& helpString1, const wxString& helpString2) +wxToolBarTool *wxToolBar95::AddTool(int index, const wxBitmap& bitmap, const wxBitmap& pushedBitmap, + bool toggle, long xPos, long yPos, wxObject *clientData, const wxString& helpString1, const wxString& helpString2) { - wxToolBarTool *tool = new wxToolBarTool(index, bitmap, (wxBitmap *)NULL, toggle, xPos, yPos, helpString1, helpString2); + wxToolBarTool *tool = new wxToolBarTool(index, bitmap, wxNullBitmap, toggle, xPos, yPos, helpString1, helpString2); tool->m_clientData = clientData; if (xPos > -1) @@ -434,7 +509,7 @@ wxToolBarTool *wxToolBar95::AddTool(const int index, const wxBitmap& bitmap, con else tool->m_y = m_yMargin; - tool->SetSize(GetDefaultButtonWidth(), GetDefaultButtonHeight()); + tool->SetSize(GetToolSize().x, GetToolSize().y); m_tools.Append((long)index, tool); return tool; @@ -444,21 +519,31 @@ wxToolBarTool *wxToolBar95::AddTool(const int index, const wxBitmap& bitmap, con void wxToolBar95::OnSysColourChanged(wxSysColourChangedEvent& event) { m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)), - GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE))); - m_defaultBackgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)), - GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE))); + GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE))); // Remap the buttons CreateTools(); - Default(); - Refresh(); // Propagate the event to the non-top-level children wxWindow::OnSysColourChanged(event); } +void wxToolBar95::OnMouseEvent(wxMouseEvent& event) +{ + if (event.RightDown()) + { + // For now, we don't have an id. Later we could + // try finding the tool. + OnRightClick((int)-1, event.GetX(), event.GetY()); + } + else + { + event.Skip(); + } +} + // These are the default colors used to map the bitmap colors // to the current system colors @@ -492,7 +577,7 @@ void wxMapBitmap(HBITMAP hBitmap, int width, int height) if (hdcMem) { - hbmOld = SelectObject(hdcMem, hBitmap); + hbmOld = (HBITMAP) SelectObject(hdcMem, hBitmap); int i, j, k; for ( i = 0; i < width; i++)