X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bb6290e3514a84a7b50860d1c75d4623696ff601..5ad998f2808122841875cd3b91abbbccbe54922d:/src/msw/tbar95.cpp diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index 63a64b9f57..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,30 +21,33 @@ #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 @@ -52,25 +55,36 @@ #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; @@ -78,48 +92,41 @@ wxToolBar95::wxToolBar95(void) m_defaultHeight = DEFAULTBITMAPY; } -bool wxToolBar95::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, - long style, int orientation, - 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); - int x = pos.x; - int y = pos.y; - int width = size.x; - int height = size.y; - m_windowStyle = style; SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); - SetParent(parent); - DWORD msflags = 0; - if (style & wxBORDER) - msflags |= WS_BORDER; - msflags |= WS_CHILD | WS_VISIBLE; - + int x = pos.x; + int y = pos.y; + int width = size.x; + int height = size.y; + if (width <= 0) width = 100; if (height <= 0) @@ -130,37 +137,55 @@ bool wxToolBar95::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, co y = 0; m_windowId = (id < 0 ? NewControlId() : id); - DWORD msStyle = WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS; + DWORD msflags = 0; + if (style & wxBORDER) + msflags |= WS_BORDER; + msflags |= WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS; if (style & wxTB_FLAT) { if (wxTheApp->GetComCtl32Version() > 400) - msStyle |= TBSTYLE_FLAT; + 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. - msStyle, // 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(); @@ -171,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; @@ -185,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; @@ -201,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; @@ -227,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); @@ -246,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. @@ -284,18 +309,18 @@ 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; } @@ -318,47 +343,77 @@ bool wxToolBar95::MSWCommand(WXUINT cmd, WXWORD id) return TRUE; } -bool wxToolBar95::MSWNotify(WXWPARAM WXUNUSED(wParam), 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; - // For backward compatibility... - OnMouseEnter(tool->m_index); - break; + wxToolBarTool *tool = (wxToolBarTool *)node->Data(); + + const wxString& help = tool->m_shortHelpString; + + 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)); } @@ -370,12 +425,12 @@ void wxToolBar95::SetRows(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); // ??? } @@ -387,11 +442,12 @@ 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); } @@ -421,7 +477,12 @@ void wxToolBar95::ToggleTool(int toolIndex, 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 @@ -435,7 +496,7 @@ void wxToolBar95::ClearTools(void) 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) @@ -448,7 +509,7 @@ wxToolBarTool *wxToolBar95::AddTool(int index, const wxBitmap& bitmap, const wxB else tool->m_y = m_yMargin; - tool->SetSize(GetDefaultButtonWidth(), GetDefaultButtonHeight()); + tool->SetSize(GetToolSize().x, GetToolSize().y); m_tools.Append((long)index, tool); return tool; @@ -458,21 +519,31 @@ wxToolBarTool *wxToolBar95::AddTool(int index, const wxBitmap& bitmap, const wxB 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 @@ -506,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++)