From a9102b3671a45d116d781b0c8e90d2e9a84fbdcb Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Wed, 16 Mar 2005 17:51:41 +0000 Subject: [PATCH] Implemented PocketPC menubar/toolbar as wxToolMenuBar derived from wxToolBar, solving the problem of how normal toolbars can co-exist with combined ones. Tidied up WinCE toolbar code. Implemented wxToolBar as 'dummy' toolbar under Smartphone. Dialogs now show an empty menubar to hide inactive one underneath. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@32853 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- demos/life/dialogs.cpp | 4 +- demos/life/life.cpp | 2 +- docs/latex/wx/frame.tex | 5 + docs/latex/wx/toolbar.tex | 15 +- docs/latex/wx/wxmsw.tex | 43 ++- include/wx/msw/toplevel.h | 5 + include/wx/msw/wince/tbarwce.h | 112 ++++--- src/common/framecmn.cpp | 6 + src/msw/frame.cpp | 2 +- src/msw/menu.cpp | 8 +- src/msw/tbar95.cpp | 2 +- src/msw/toplevel.cpp | 34 +++ src/msw/wince/tbarwce.cpp | 513 +++++---------------------------- 13 files changed, 251 insertions(+), 500 deletions(-) diff --git a/demos/life/dialogs.cpp b/demos/life/dialogs.cpp index c55fc7989d..27c74fa918 100644 --- a/demos/life/dialogs.cpp +++ b/demos/life/dialogs.cpp @@ -186,14 +186,14 @@ XLife is (c) 1989 by Jon Bennett et al.")), sizer->Add( new wxStaticLine(this, wxID_ANY), 0, wxGROW | wxLEFT | wxRIGHT, 5 ); #endif // wxUSE_STATLINE -#ifndef __WXWINCE__ +#if ! (defined(__SMARTPHONE__) || defined(__POCKETPC__)) sizer->Add( CreateButtonSizer(wxOK), 0, wxCENTRE | wxALL, 10 ); #endif // activate SetSizer(sizer); -#ifndef __WXWINCE__ +#if ! (defined(__SMARTPHONE__) || defined(__POCKETPC__)) sizer->SetSizeHints(this); sizer->Fit(this); Centre(wxBOTH | wxCENTRE_ON_SCREEN); diff --git a/demos/life/life.cpp b/demos/life/life.cpp index 2ff4a9e43a..5dc05609ee 100644 --- a/demos/life/life.cpp +++ b/demos/life/life.cpp @@ -199,7 +199,7 @@ LifeFrame::LifeFrame() : menuFile->Append(wxID_NEW, wxGetStockLabel(wxID_NEW), _("Start a new game")); menuFile->Append(wxID_OPEN, wxGetStockLabel(wxID_OPEN), _("Open an existing Life pattern")); menuFile->Append(ID_SAMPLES, _("&Sample game..."), _("Select a sample configuration")); -#ifndef __WXWINCE__ +#if ! (defined(__SMARTPHONE__) || defined(__POCKETPC__)) menuFile->AppendSeparator(); menuFile->Append(wxID_EXIT, wxGetStockLabel(wxID_EXIT, true, _T("Alt-X")), _("Quit this program")); diff --git a/docs/latex/wx/frame.tex b/docs/latex/wx/frame.tex index b16d7b3a1d..3f3bd4fa10 100644 --- a/docs/latex/wx/frame.tex +++ b/docs/latex/wx/frame.tex @@ -241,6 +241,11 @@ with \helpref{wxFrame::SetToolBar}{wxframesettoolbar}, the frame will manage the position and adjust the return value from \helpref{wxWindow::GetClientSize}{wxwindowgetclientsize} to reflect the available space for application windows. +Under Pocket PC, you should {\it always} use this function for creating the toolbar +to be managed by the frame, so that wxWidgets can use a combined +menubar and toolbar. Where you manage your own toolbars, create a wxToolBar +as usual. + \wxheading{See also} \helpref{wxFrame::CreateStatusBar}{wxframecreatestatusbar},\rtfsp diff --git a/docs/latex/wx/toolbar.tex b/docs/latex/wx/toolbar.tex index ea7abe14f8..c6d63f58ff 100644 --- a/docs/latex/wx/toolbar.tex +++ b/docs/latex/wx/toolbar.tex @@ -23,19 +23,18 @@ wxToolBarBase\\ \wxheading{Include files} (to allow wxWidgets to select an appropriate toolbar class)\\ - (the base class)\\ - (the non-Windows 95 Windows toolbar class)\\ - (the Windows 95/98 toolbar class)\\ + (the base class) \wxheading{Remarks} You may also create a toolbar that is managed by the frame, by -calling \helpref{wxFrame::CreateToolBar}{wxframecreatetoolbar}. +calling \helpref{wxFrame::CreateToolBar}{wxframecreatetoolbar}. Under Pocket PC, +you should {\it always} use this function for creating the toolbar +to be managed by the frame, so that wxWidgets can use a combined +menubar and toolbar. Where you manage your own toolbars, create a wxToolBar +as usual. -Due to the use of native toolbars on the various platforms, certain adaptions will -often have to be made in order to get optimal look on all platforms as some platforms -ignore the values for explicit placement and use their own layout and the meaning -of a "separator" is a vertical line under Windows95 vs. simple space under GTK etc. +The meaning of a "separator" is a vertical line under Windows and simple space under GTK+. {\bf wxToolBar95:} Note that this toolbar paints tools to reflect system-wide colours. If you use more than 16 colours in your tool bitmaps, you may wish to suppress diff --git a/docs/latex/wx/wxmsw.tex b/docs/latex/wx/wxmsw.tex index 637a048123..59937fee83 100644 --- a/docs/latex/wx/wxmsw.tex +++ b/docs/latex/wx/wxmsw.tex @@ -136,16 +136,38 @@ provided, to show settings in the correct style on PocketPC and on other platfor Notifications (bubble HTML text with optional buttons and links) will also be implemented in the future for PocketPC. +Modeless dialogs probably don't make sense for PocketPC and Smartphone, since +frames and dialogs are normally full-screen, and a modeless dialog is normally +intended to co-exist with the main application frame. + \subsubsection{Menubars and toolbars in wxWinCE} -Menubars and toolbars can only be implemented using a combined control, -but you can use the same syntax as before; wxWidgets will combine the menubar -and toolbar. +\wxheading{Menubars and toolbars in PocketPC} On PocketPC, a frame must always have a menubar, even if it's empty. +An empty menubar is automatically provided for dialogs, to hide +any existing menubar for the duration of the dialog. + +Menubars and toolbars are implemented using a combined control, +but you can use essentially the usual wxWidgets API; wxWidgets will combine the menubar +and toolbar. However, there are some restrictions: + +\itemsep=0pt +\begin{itemize} +\item You must create the frame's primary toolbar with wxFrame::CreateToolBar, +because this uses the special wxToolMenuBar class (derived from wxToolBar) +to implement the combined toolbar and menubar. Otherwise, you can create and manage toolbars +using the wxToolBar class as usual, for example to implement an optional +formatting toolbar above the menubar as Pocket Word does. But don't assign +a wxToolBar to a frame using SetToolBar - you should always use CreateToolBar +for the main frame toolbar. +\item Deleting and adding tools to wxToolMenuBar is not supported. +\end{itemize} + +\wxheading{Menubars and toolbars in Smartphone} On Smartphone, there are only two menu buttons, so a menubar is simulated -using a nested menu on the right menu button. Toolbars are simply ignored on +using a nested menu on the right menu button. Any toolbars are simply ignored on Smartphone. \subsubsection{Closing windows in wxWinCE} @@ -160,9 +182,15 @@ wxID\_EXIT, it will do the right thing. \subsubsection{Control differences on wxWinCE} -This section is to be written. +These controls are missing from wxWinCE: + +\itemsep=0pt +\begin{itemize} +\item {\bf wxCheckListBox} This can be implemented using a wxListCtrl in report mode +with checked/unchecked images. +\end{itemize} -Can someone remind us why wxChoice was rewritten for Smartphone? +This section is currently incomplete. \subsubsection{Online help in wxWinCE} @@ -197,6 +225,9 @@ Win32. the correct size on the emulator, but too small on a VGA Pocket Loox device. \item {\bf wxStaticLine.} Lines don't show up, and the documentation suggests that missing styles are implemented with WM\_PAINT. +\item {\bf wxCheckListBox.} This class needs to be implemented in terms of a wxListCtrl +in report mode, using icons for checkbox states. This is necessary because owner-draw listboxes +are not supported on Windows CE. \item {\bf OK button.} We should allow the OK button on a dialog to be optional, perhaps by using wxCLOSE\_BOX to indicate when the OK button should be displayed. \item {\bf Dynamic adaptation.} We should probably be using run-time tests more diff --git a/include/wx/msw/toplevel.h b/include/wx/msw/toplevel.h index 2033fb0d4e..377a446cce 100644 --- a/include/wx/msw/toplevel.h +++ b/include/wx/msw/toplevel.h @@ -165,6 +165,11 @@ protected: void ReloadAllButtons(); #endif // __SMARTPHONE__ && __WXWINCE__ + // Empty menubar for dialogs +#ifdef __POCKETPC__ + WXHWND m_menuBarHWND; +#endif + DECLARE_EVENT_TABLE() DECLARE_NO_COPY_CLASS(wxTopLevelWindowMSW) }; diff --git a/include/wx/msw/wince/tbarwce.h b/include/wx/msw/wince/tbarwce.h index 153973126a..bcf66439ca 100644 --- a/include/wx/msw/wince/tbarwce.h +++ b/include/wx/msw/wince/tbarwce.h @@ -20,13 +20,74 @@ #include "wx/dynarray.h" +// Smartphones don't have toolbars, so use a dummy class +#ifdef __SMARTPHONE__ + class WXDLLEXPORT wxToolBar : public wxToolBarBase { public: // ctors and dtor - wxToolBar() { Init(); } + wxToolBar() { } wxToolBar(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxNO_BORDER | wxTB_HORIZONTAL, + const wxString& name = wxToolBarNameStr) + { + Create(parent, id, pos, size, style, name); + } + + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxNO_BORDER | wxTB_HORIZONTAL, + const wxString& name = wxToolBarNameStr); + + // override/implement base class virtuals + virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, wxCoord y) const; + virtual bool Realize() { return true; } + +protected: + // implement base class pure virtuals + virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool); + virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool); + + virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable); + virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle); + virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle); + + virtual wxToolBarToolBase *CreateTool(int id, + const wxString& label, + const wxBitmap& bmpNormal, + const wxBitmap& bmpDisabled, + wxItemKind kind, + wxObject *clientData, + const wxString& shortHelp, + const wxString& longHelp); + virtual wxToolBarToolBase *CreateTool(wxControl *control); + +private: + DECLARE_EVENT_TABLE() + DECLARE_DYNAMIC_CLASS(wxToolBar) + DECLARE_NO_COPY_CLASS(wxToolBar) +}; + +#else + +// For __POCKETPC__ + +#include "wx/msw/tbar95.h" + +class WXDLLEXPORT wxToolMenuBar : public wxToolBar +{ +public: + // ctors and dtor + wxToolMenuBar() { Init(); } + + wxToolMenuBar(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, @@ -47,32 +108,15 @@ public: const wxString& name = wxToolBarNameStr, wxMenuBar* menuBar = NULL); - virtual ~wxToolBar(); + virtual ~wxToolMenuBar(); // override/implement base class virtuals - virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, wxCoord y) const; - virtual bool Realize(); - virtual void SetToolBitmapSize(const wxSize& size); - virtual wxSize GetToolSize() const; - - virtual void SetRows(int nRows); - // implementation only from now on // ------------------------------- - virtual void SetWindowStyleFlag(long style); - virtual bool MSWCommand(WXUINT param, WXWORD id); - virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); - - void OnMouseEvent(wxMouseEvent& event); - void OnSysColourChanged(wxSysColourChangedEvent& event); - - void SetFocus() {} - - static WXHBITMAP MapBitmap(WXHBITMAP bitmap, int width, int height); // Return HMENU for the menu associated with the commandbar WXHMENU GetHMenu(); @@ -97,10 +141,6 @@ protected: virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool); virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool); - virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable); - virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle); - virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle); - virtual wxToolBarToolBase *CreateTool(int id, const wxString& label, const wxBitmap& bmpNormal, @@ -111,34 +151,18 @@ protected: const wxString& longHelp); virtual wxToolBarToolBase *CreateTool(wxControl *control); - // override WndProc mainly to process WM_SIZE - virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); - - // return the appropriate size and flags for the toolbar control - virtual wxSize DoGetBestSize() const; - virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const; - - // handlers for various events - void HandleMouseMove(WXWPARAM wParam, WXLPARAM lParam); - - // should be called whenever the toolbar size changes - void UpdateSize(); - - // the total number of toolbar elements - size_t m_nButtons; - - // the tool the cursor is in - wxToolBarToolBase *m_pInTool; - // The menubar associated with this toolbar wxMenuBar* m_menuBar; private: DECLARE_EVENT_TABLE() - DECLARE_DYNAMIC_CLASS(wxToolBar) - DECLARE_NO_COPY_CLASS(wxToolBar) + DECLARE_DYNAMIC_CLASS(wxToolMenuBar) + DECLARE_NO_COPY_CLASS(wxToolMenuBar) }; +#endif + // __SMARTPHONE__ + #endif // wxUSE_TOOLBAR #endif diff --git a/src/common/framecmn.cpp b/src/common/framecmn.cpp index 995bf80b19..6127486170 100644 --- a/src/common/framecmn.cpp +++ b/src/common/framecmn.cpp @@ -489,9 +489,15 @@ wxToolBar* wxFrameBase::OnCreateToolBar(long style, wxWindowID id, const wxString& name) { +#if defined(__WXWINCE__) && defined(__POCKETPC__) + return new wxToolMenuBar(this, id, + wxDefaultPosition, wxDefaultSize, + style, name); +#else return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name); +#endif } void wxFrameBase::SetToolBar(wxToolBar *toolbar) diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index 1ec081f3f4..22bebcacc6 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -357,7 +357,7 @@ void wxFrame::AttachMenuBar(wxMenuBar *menubar) #elif defined(WINCE_WITHOUT_COMMANDBAR) if (!GetToolBar()) { - wxToolBar* toolBar = new wxToolBar(this, wxID_ANY, + wxToolMenuBar* toolBar = new wxToolMenuBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxTB_HORIZONTAL, wxToolBarNameStr, menubar); diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index 3b1499ce24..3f6cb15334 100644 --- a/src/msw/menu.cpp +++ b/src/msw/menu.cpp @@ -716,9 +716,13 @@ wxMenuBar::~wxMenuBar() { // In Windows CE (not .NET), the menubar is always associated // with a toolbar, which destroys the menu implicitly. -#if defined(WINCE_WITHOUT_COMMANDBAR) +#if defined(WINCE_WITHOUT_COMMANDBAR) && defined(__POCKETPC__) if (GetToolBar()) - GetToolBar()->SetMenuBar(NULL); + { + wxToolMenuBar* toolMenuBar = wxDynamicCast(GetToolBar(), wxToolMenuBar); + if (toolMenuBar) + toolMenuBar->SetMenuBar(NULL); + } #else // we should free Windows resources only if Windows doesn't do it for us // which happens if we're attached to a frame diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index 6636f4cebd..5890b3ec97 100644 --- a/src/msw/tbar95.cpp +++ b/src/msw/tbar95.cpp @@ -39,7 +39,7 @@ #include "wx/control.h" #endif -#if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE && (!defined(_WIN32_WCE) || (_WIN32_WCE >= 400 && !defined(__POCKETPC__) && !defined(__SMARTPHONE__))) +#if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE && !defined(__SMARTPHONE__) #include "wx/toolbar.h" #include "wx/sysopt.h" diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index f5ae3f72e8..09e60871b1 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -148,6 +148,10 @@ void wxTopLevelWindowMSW::Init() #if defined(__SMARTPHONE__) && defined(__WXWINCE__) m_MenuBarHWND = 0; #endif +#ifdef __POCKETPC__ + // A dummy menubar for dialogs + m_menuBarHWND = 0; +#endif } WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const @@ -415,6 +419,27 @@ bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate, ::SetWindowText(GetHwnd(), title); } +#ifdef __POCKETPC__ + // Create an empty menubar so that we don't see the menubar underneath + SHMENUBARINFO mbi; + + memset (&mbi, 0, sizeof (SHMENUBARINFO)); + mbi.cbSize = sizeof (SHMENUBARINFO); + mbi.hwndParent = (HWND) GetParent()->GetHWND(); + mbi.nToolBarId = 5000; + mbi.nBmpId = 0; + mbi.cBmpImages = 0; + mbi.dwFlags = 0 ; // SHCMBF_EMPTYBAR; + mbi.hInstRes = wxGetInstance(); + + if (!SHCreateMenuBar(&mbi)) + { + wxFAIL_MSG( _T("SHCreateMenuBar failed") ); + } + + m_menuBarHWND = (WXHWND) mbi.hwndMB; +#endif + SubclassWin(m_hWnd); #ifdef __SMARTPHONE__ @@ -563,6 +588,15 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent, wxTopLevelWindowMSW::~wxTopLevelWindowMSW() { +#ifdef __POCKETPC__ + // Destroy the dummy menubar for dialogs + if (m_menuBarHWND) + { + ::DestroyWindow((HWND) m_menuBarHWND); + m_menuBarHWND = 0; + } +#endif + // after destroying an owned window, Windows activates the next top level // window in Z order but it may be different from our owner (to reproduce // this simply Alt-TAB to another application and back before closing the diff --git a/src/msw/wince/tbarwce.cpp b/src/msw/wince/tbarwce.cpp index 90f4f1fc51..c2d6df75b0 100644 --- a/src/msw/wince/tbarwce.cpp +++ b/src/msw/wince/tbarwce.cpp @@ -63,73 +63,28 @@ #include "wx/msw/winundef.h" -#if defined(__MWERKS__) && defined(__WXMSW__) -// including for max definition doesn't seem -// to work using CodeWarrior 6 Windows. So we define it -// here. (Otherwise we get a undefined identifier 'max' -// later on in this file.) (Added by dimitri@shortcut.nl) -# ifndef max -# define max(a,b) (((a) > (b)) ? (a) : (b)) -# endif - -#endif - -// ---------------------------------------------------------------------------- -// constants -// ---------------------------------------------------------------------------- - -// these standard constants are not always defined in compilers headers - -// Styles -#ifndef TBSTYLE_FLAT - #define TBSTYLE_LIST 0x1000 - #define TBSTYLE_FLAT 0x0800 -#endif - -#ifndef TBSTYLE_TRANSPARENT - #define TBSTYLE_TRANSPARENT 0x8000 -#endif - -#ifndef TBSTYLE_TOOLTIPS - #define TBSTYLE_TOOLTIPS 0x0100 -#endif - -// Messages -#ifndef TB_GETSTYLE - #define TB_SETSTYLE (WM_USER + 56) - #define TB_GETSTYLE (WM_USER + 57) -#endif - -#ifndef TB_HITTEST - #define TB_HITTEST (WM_USER + 69) -#endif +#if !defined(__SMARTPHONE__) -// these values correspond to those used by comctl32.dll -#define DEFAULTBITMAPX 16 -#define DEFAULTBITMAPY 15 -#define DEFAULTBUTTONX 24 -#define DEFAULTBUTTONY 24 -#define DEFAULTBARHEIGHT 27 +///////////// This implementation is for PocketPC. +///////////// See later for the Smartphone dummy toolbar class. // ---------------------------------------------------------------------------- -// wxWin macros +// Event table // ---------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl) +IMPLEMENT_DYNAMIC_CLASS(wxToolMenuBar, wxToolBar) -BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) - EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent) - EVT_SYS_COLOUR_CHANGED(wxToolBar::OnSysColourChanged) +BEGIN_EVENT_TABLE(wxToolMenuBar, wxToolBar) END_EVENT_TABLE() // ---------------------------------------------------------------------------- // private classes // ---------------------------------------------------------------------------- -class wxToolBarTool : public wxToolBarToolBase +class wxToolMenuBarTool : public wxToolBarToolBase { public: - wxToolBarTool(wxToolBar *tbar, + wxToolMenuBarTool(wxToolBar *tbar, int id, const wxString& label, const wxBitmap& bmpNormal, @@ -145,7 +100,7 @@ public: m_bitmapIndex = -1; } - wxToolBarTool(wxToolBar *tbar, wxControl *control) + wxToolMenuBarTool(wxToolBar *tbar, wxControl *control) : wxToolBarToolBase(tbar, control) { m_nSepCount = 1; @@ -187,7 +142,7 @@ private: // wxToolBarTool // ---------------------------------------------------------------------------- -wxToolBarToolBase *wxToolBar::CreateTool(int id, +wxToolBarToolBase *wxToolMenuBar::CreateTool(int id, const wxString& label, const wxBitmap& bmpNormal, const wxBitmap& bmpDisabled, @@ -196,31 +151,28 @@ wxToolBarToolBase *wxToolBar::CreateTool(int id, const wxString& shortHelp, const wxString& longHelp) { - return new wxToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind, + return new wxToolMenuBarTool(this, id, label, bmpNormal, bmpDisabled, kind, clientData, shortHelp, longHelp); } -wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) +wxToolBarToolBase *wxToolMenuBar::CreateTool(wxControl *control) { - return new wxToolBarTool(this, control); + return new wxToolMenuBarTool(this, control); } // ---------------------------------------------------------------------------- // wxToolBar construction // ---------------------------------------------------------------------------- -void wxToolBar::Init() +void wxToolMenuBar::Init() { - m_nButtons = 0; - - m_defaultWidth = DEFAULTBITMAPX; - m_defaultHeight = DEFAULTBITMAPY; - - m_pInTool = 0; + wxToolBar::Init(); + + m_nButtons = 0; m_menuBar = NULL; } -bool wxToolBar::Create(wxWindow *parent, +bool wxToolMenuBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, @@ -243,20 +195,12 @@ bool wxToolBar::Create(wxWindow *parent, return true; } -#ifndef TBSTYLE_NO_DROPDOWN_ARROW -#define TBSTYLE_NO_DROPDOWN_ARROW 0x0080 -#endif - -bool wxToolBar::MSWCreateToolbar(const wxPoint& WXUNUSED(pos), const wxSize& WXUNUSED(size), wxMenuBar* menuBar) +bool wxToolMenuBar::MSWCreateToolbar(const wxPoint& WXUNUSED(pos), const wxSize& WXUNUSED(size), wxMenuBar* menuBar) { SetMenuBar(menuBar); if (m_menuBar) m_menuBar->SetToolBar(this); - // Smartphone doesn't show a toolbar, it uses menu buttons. - -#if !defined(__SMARTPHONE__) - #if defined(WINCE_WITHOUT_COMMANDBAR) // Create the menubar. SHMENUBARINFO mbi; @@ -291,83 +235,25 @@ bool wxToolBar::MSWCreateToolbar(const wxPoint& WXUNUSED(pos), const wxSize& WXU if (menuBar) menuBar->Create(); -#endif - // __SMARTPHONE__ return true; } -void wxToolBar::Recreate() +void wxToolMenuBar::Recreate() { -#if 0 - const HWND hwndOld = GetHwnd(); - if ( !hwndOld ) - { - // we haven't been created yet, no need to recreate - return; - } - - // get the position and size before unsubclassing the old toolbar - const wxPoint pos = GetPosition(); - const wxSize size = GetSize(); - - UnsubclassWin(); - - if ( !MSWCreateToolbar(pos, size) ) - { - // what can we do? - wxFAIL_MSG( _T("recreating the toolbar failed") ); - - return; - } - - // reparent all our children under the new toolbar - for ( wxWindowList::compatibility_iterator node = m_children.GetFirst(); - node; - node = node->GetNext() ) - { - wxWindow *win = node->GetData(); - if ( !win->IsTopLevel() ) - ::SetParent(GetHwndOf(win), GetHwnd()); - } - - // only destroy the old toolbar now -- after all the children had been - // reparented - ::DestroyWindow(hwndOld); - - Realize(); - UpdateSize(); -#endif + // TODO } -wxToolBar::~wxToolBar() +wxToolMenuBar::~wxToolMenuBar() { if (GetMenuBar()) GetMenuBar()->SetToolBar(NULL); - - // 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 - wxFrame *frame = wxDynamicCast(GetParent(), wxFrame); - if ( frame && !frame->IsBeingDeleted() ) - { - frame->SendSizeEvent(); - } -} - -wxSize wxToolBar::DoGetBestSize() const -{ - wxSize sizeBest = GetToolSize(); - sizeBest.x *= GetToolsCount(); - - // reverse horz and vertical components if necessary - return HasFlag(wxTB_VERTICAL) ? wxSize(sizeBest.y, sizeBest.x) : sizeBest; } // Return HMENU for the menu associated with the commandbar -WXHMENU wxToolBar::GetHMenu() +WXHMENU wxToolMenuBar::GetHMenu() { #if defined(__HANDHELDPC__) - // TODO ??? return 0; #else if (GetHWND()) @@ -379,57 +265,11 @@ WXHMENU wxToolBar::GetHMenu() #endif } - -WXDWORD wxToolBar::MSWGetStyle(long style, WXDWORD *exstyle) const -{ - // toolbars never have border, giving one to them results in broken - // appearance - WXDWORD msStyle = wxControl::MSWGetStyle - ( - (style & ~wxBORDER_MASK) | wxBORDER_NONE, exstyle - ); - - // always include this one, it never hurts and setting it later only if we - // do have tooltips wouldn't work - msStyle |= TBSTYLE_TOOLTIPS; - - if ( style & (wxTB_FLAT | wxTB_HORZ_LAYOUT) ) - { - // static as it doesn't change during the program lifetime - static int s_verComCtl = wxTheApp->GetComCtl32Version(); - - // comctl32.dll 4.00 doesn't support the flat toolbars and using this - // style with 6.00 (part of Windows XP) leads to the toolbar with - // incorrect background colour - and not using it still results in the - // correct (flat) toolbar, so don't use it there - if ( s_verComCtl > 400 && s_verComCtl < 600 ) - { - msStyle |= TBSTYLE_FLAT | TBSTYLE_TRANSPARENT; - } - - if ( s_verComCtl >= 470 && style & wxTB_HORZ_LAYOUT ) - { - msStyle |= TBSTYLE_LIST; - } - } - - if ( style & wxTB_NODIVIDER ) - msStyle |= CCS_NODIVIDER; - - if ( style & wxTB_NOALIGN ) - msStyle |= CCS_NOPARENTALIGN; - - if ( style & wxTB_VERTICAL ) - msStyle |= CCS_VERT; - - return msStyle; -} - // ---------------------------------------------------------------------------- // adding/removing tools // ---------------------------------------------------------------------------- -bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) +bool wxToolMenuBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) { // nothing special to do here - we really create the toolbar buttons in // Realize() later @@ -438,7 +278,7 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) return true; } -bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool) +bool wxToolMenuBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool) { // 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 @@ -461,7 +301,7 @@ bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool) if ( tool2->IsControl() ) { - pos += ((wxToolBarTool *)tool2)->GetSeparatorsCount() - 1; + pos += ((wxToolMenuBarTool *)tool2)->GetSeparatorsCount() - 1; } } @@ -479,7 +319,7 @@ bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool) if ( tool->IsControl() ) { - nButtonsToDelete = ((wxToolBarTool *)tool)->GetSeparatorsCount(); + nButtonsToDelete = ((wxToolMenuBarTool *)tool)->GetSeparatorsCount(); width *= nButtonsToDelete; } @@ -515,11 +355,8 @@ bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool) return true; } -bool wxToolBar::Realize() +bool wxToolMenuBar::Realize() { -#if defined(__SMARTPHONE__) - return true; -#else const size_t nTools = GetToolsCount(); if ( nTools == 0 ) { @@ -542,7 +379,7 @@ bool wxToolBar::Realize() wxToolBarToolsList::Node* node; for ( node = m_tools.GetFirst(); node; node = node->GetNext() ) { - wxToolBarTool *tool = (wxToolBarTool*) node->GetData(); + wxToolMenuBarTool *tool = (wxToolMenuBarTool*) node->GetData(); TBBUTTON buttons[1] ; @@ -648,15 +485,9 @@ bool wxToolBar::Realize() } return true; -#endif - // __SMARTPHONE__ } -// ---------------------------------------------------------------------------- -// message handlers -// ---------------------------------------------------------------------------- - -bool wxToolBar::MSWCommand(WXUINT WXUNUSED(cmd), WXWORD id) +bool wxToolMenuBar::MSWCommand(WXUINT WXUNUSED(cmd), WXWORD id) { wxToolBarToolBase *tool = FindById((int)id); if ( !tool ) @@ -696,285 +527,97 @@ bool wxToolBar::MSWCommand(WXUINT WXUNUSED(cmd), WXWORD id) return true; } -bool wxToolBar::MSWOnNotify(int WXUNUSED(idCtrl), - WXLPARAM lParam, - WXLPARAM *WXUNUSED(result)) -{ -#if wxUSE_TOOLTIPS - // First check if this applies to us - NMHDR *hdr = (NMHDR *)lParam; - - // the tooltips control created by the toolbar is sometimes Unicode, even - // in an ANSI application - this seems to be a bug in comctl32.dll v5 - UINT code = hdr->code; - if ( (code != (UINT) TTN_NEEDTEXTA) && (code != (UINT) TTN_NEEDTEXTW) ) - return false; - - HWND toolTipWnd = (HWND)::SendMessage((HWND)GetHWND(), TB_GETTOOLTIPS, 0, 0); - if ( toolTipWnd != hdr->hwndFrom ) - return false; - - LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam; - int id = (int)ttText->hdr.idFrom; - - wxToolBarToolBase *tool = FindById(id); - if ( !tool ) - return false; - - return HandleTooltipNotify(code, lParam, tool->GetShortHelp()); #else - wxUnusedVar(lParam); - return false; -#endif -} + +////////////// For Smartphone // ---------------------------------------------------------------------------- -// toolbar geometry +// Event table // ---------------------------------------------------------------------------- -void wxToolBar::SetToolBitmapSize(const wxSize& size) -{ - wxToolBarBase::SetToolBitmapSize(size); +IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase) - ::SendMessage(GetHwnd(), TB_SETBITMAPSIZE, 0, MAKELONG(size.x, size.y)); -} +BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) +END_EVENT_TABLE() -void wxToolBar::SetRows(int nRows) +wxToolBarToolBase *wxToolBar::CreateTool(int id, + const wxString& label, + const wxBitmap& bmpNormal, + const wxBitmap& bmpDisabled, + wxItemKind kind, + wxObject *clientData, + const wxString& shortHelp, + const wxString& longHelp) { - if ( nRows == m_maxRows ) - { - // avoid resizing the frame uselessly - return; - } - - // TRUE in wParam means to create at least as many rows, FALSE - - // at most as many - RECT rect; - ::SendMessage(GetHwnd(), TB_SETROWS, - MAKEWPARAM(nRows, !(GetWindowStyle() & wxTB_VERTICAL)), - (LPARAM) &rect); - - m_maxRows = nRows; - - UpdateSize(); + return new wxToolBarToolBase(this, id, label, bmpNormal, bmpDisabled, kind, + clientData, shortHelp, longHelp); } -// The button size is bigger than the bitmap size -wxSize wxToolBar::GetToolSize() const +wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) { - // TB_GETBUTTONSIZE is supported from version 4.70 -#if defined(_WIN32_IE) && (_WIN32_IE >= 0x300 ) \ - && !( defined(__GNUWIN32__) && !wxCHECK_W32API_VERSION( 1, 0 ) ) - if ( wxTheApp->GetComCtl32Version() >= 470 ) - { - DWORD dw = ::SendMessage(GetHwnd(), TB_GETBUTTONSIZE, 0, 0); - - return wxSize(LOWORD(dw), HIWORD(dw)); - } - else -#endif // comctl32.dll 4.70+ - { - // defaults - return wxSize(m_defaultWidth + 8, m_defaultHeight + 7); - } + return new wxToolBarToolBase(this, control); } -static -wxToolBarToolBase *GetItemSkippingDummySpacers(const wxToolBarToolsList& tools, - size_t index ) +bool wxToolBar::Create(wxWindow *parent, + wxWindowID WXUNUSED(id), + const wxPoint& WXUNUSED(pos), + const wxSize& WXUNUSED(size), + long style, + const wxString& name) { - wxToolBarToolsList::compatibility_iterator current = tools.GetFirst(); - - for ( ; current != 0; current = current->GetNext() ) - { - if ( index == 0 ) - return current->GetData(); - - wxToolBarTool *tool = (wxToolBarTool *)current->GetData(); - size_t separators = tool->GetSeparatorsCount(); - - // if it is a normal button, sepcount == 0, so skip 1 item (the button) - // otherwise, skip as many items as the separator count, plus the - // control itself - index -= separators ? separators + 1 : 1; - } + // TODO: we may need to make this a dummy hidden window to + // satisfy other parts of wxWidgets. - return 0; + parent->AddChild(this); + + SetWindowStyle(style); + SetName(name); + + return true; } -wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const -{ - POINT pt; - pt.x = x; - pt.y = y; - int index = (int)::SendMessage(GetHwnd(), TB_HITTEST, 0, (LPARAM)&pt); - // MBN: when the point ( x, y ) is close to the toolbar border - // TB_HITTEST returns m_nButtons ( not -1 ) - if ( index < 0 || (size_t)index >= m_nButtons ) - { - // it's a separator or there is no tool at all there - return (wxToolBarToolBase *)NULL; - } +// ---------------------------------------------------------------------------- +// adding/removing tools +// ---------------------------------------------------------------------------- - // if comctl32 version < 4.71 wxToolBar95 adds dummy spacers -#if defined(_WIN32_IE) && (_WIN32_IE >= 0x400 ) - if ( wxTheApp->GetComCtl32Version() >= 471 ) - { - return m_tools.Item((size_t)index)->GetData(); - } - else -#endif - { - return GetItemSkippingDummySpacers( m_tools, (size_t) index ); - } +bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) +{ + tool->Attach(this); + return true; } -void wxToolBar::UpdateSize() +bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) { - // the toolbar size changed - ::SendMessage(GetHwnd(), TB_AUTOSIZE, 0, 0); - - // we must also refresh the frame after the toolbar size (possibly) changed - wxFrame *frame = wxDynamicCast(GetParent(), wxFrame); - if ( frame ) - { - frame->SendSizeEvent(); - } + tool->Detach(); + return true; } -// ---------------------------------------------------------------------------- -// toolbar styles -// --------------------------------------------------------------------------- - -void wxToolBar::SetWindowStyleFlag(long style) +wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y)) const { - // the style bits whose changes force us to recreate the toolbar - static const long MASK_NEEDS_RECREATE = wxTB_TEXT | wxTB_NOICONS; - - const long styleOld = GetWindowStyle(); - - wxToolBarBase::SetWindowStyleFlag(style); - - // don't recreate an empty toolbar: not only this is unnecessary, but it is - // also fatal as we'd then try to recreate the toolbar when it's just being - // created - if ( GetToolsCount() && - (style & MASK_NEEDS_RECREATE) != (styleOld & MASK_NEEDS_RECREATE) ) - { - // to remove the text labels, simply re-realizing the toolbar is enough - // but I don't know of any way to add the text to an existing toolbar - // other than by recreating it entirely - Recreate(); - } + return NULL; } // ---------------------------------------------------------------------------- // tool state // ---------------------------------------------------------------------------- -void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool enable) +void wxToolBar::DoEnableTool(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(enable)) { - ::SendMessage(GetHwnd(), TB_ENABLEBUTTON, - (WPARAM)tool->GetId(), (LPARAM)MAKELONG(enable, 0)); } -void wxToolBar::DoToggleTool(wxToolBarToolBase *tool, bool toggle) +void wxToolBar::DoToggleTool(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle)) { - ::SendMessage(GetHwnd(), TB_CHECKBUTTON, - (WPARAM)tool->GetId(), (LPARAM)MAKELONG(toggle, 0)); } void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle)) { - // VZ: AFAIK, the button has to be created either with TBSTYLE_CHECK or - // without, so we really need to delete the button and recreate it here wxFAIL_MSG( _T("not implemented") ); } -// ---------------------------------------------------------------------------- -// event handlers -// ---------------------------------------------------------------------------- - -// Responds to colour changes, and passes event on to children. -void wxToolBar::OnSysColourChanged(wxSysColourChangedEvent& event) -{ - wxRGBToColour(m_backgroundColour, ::GetSysColor(COLOR_BTNFACE)); - - // Remap the buttons - Realize(); - - // Relayout the toolbar - int nrows = m_maxRows; - m_maxRows = 0; // otherwise SetRows() wouldn't do anything - SetRows(nrows); - - Refresh(); - - // let the event propagate further - event.Skip(); -} - -void wxToolBar::OnMouseEvent(wxMouseEvent& event) -{ - if (event.Leaving() && m_pInTool) - { - OnMouseEnter( -1 ); - event.Skip(); - return; - } - - 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(); - } -} - -void wxToolBar::HandleMouseMove(WXWPARAM WXUNUSED(wParam), WXLPARAM lParam) -{ - wxCoord x = GET_X_LPARAM(lParam), - y = GET_Y_LPARAM(lParam); - wxToolBarToolBase* tool = FindToolForPosition( x, y ); - - // cursor left current tool - if( tool != m_pInTool && !tool ) - { - m_pInTool = 0; - OnMouseEnter( -1 ); - } - - // cursor entered a tool - if( tool != m_pInTool && tool ) - { - m_pInTool = tool; - OnMouseEnter( tool->GetId() ); - } -} +#endif + // !__SMARTPHONE__ -WXLRESULT wxToolBar::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) -{ -#if 0 - switch ( nMsg ) - { - case WM_SIZE: - if ( HandleSize(wParam, lParam) ) - return 0; - break; - case WM_MOUSEMOVE: - // we don't handle mouse moves, so always pass the message to - // wxControl::MSWWindowProc - HandleMouseMove(wParam, lParam); - break; - } -#endif - return wxControl::MSWWindowProc(nMsg, wParam, lParam); -} #endif // wxUSE_TOOLBAR && Win95 -- 2.45.2