]> git.saurik.com Git - wxWidgets.git/commitdiff
Added WCE toolbar
authorJulian Smart <julian@anthemion.co.uk>
Fri, 18 Jul 2003 14:12:53 +0000 (14:12 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Fri, 18 Jul 2003 14:12:53 +0000 (14:12 +0000)
Got menubars working with WCE

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22085 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

12 files changed:
include/wx/msw/frame.h
include/wx/msw/menu.h
include/wx/msw/wince/tbarwce.h [new file with mode: 0644]
include/wx/msw/wx.rc
include/wx/toolbar.h
samples/minimal/minimal.cpp
src/msw/frame.cpp
src/msw/menu.cpp
src/msw/settings.cpp
src/msw/toplevel.cpp
src/msw/wince/tbarwce.cpp [new file with mode: 0644]
src/msw/window.cpp

index b90e37d8b0e18c9f599f6f15174790022c146ae3..cc8bd90b35dc33fdaa9743b1c98239fc0097ca3d 100644 (file)
@@ -102,12 +102,6 @@ public:
     // current size - this has an effect of refreshing the window layout
     virtual void SendSizeEvent();
 
-#ifdef __WXWINCE__
-    WXHWND GetCommandBar() { return m_commandBar; }
-    WXHWND CreateCommandBar() ;
-    void RemoveCommandBar() ;
-#endif
-
 protected:
     // common part of all ctors
     void Init();
@@ -155,9 +149,6 @@ private:
 #if wxUSE_TOOLTIPS
     WXHWND                m_hwndToolTip;
 #endif // tooltips
-#ifdef __WXWINCE__
-    WXHWND                m_commandBar;
-#endif
 
     // used by IconizeChildFrames(), see comments there
     bool m_wasMinimized;
index e3060763487b0229b4bcf7ccb97d4bfb1cefbb57..5d273cd57f63fc014c3233b0dfa6864931f4aa3c 100644 (file)
 
 class WXDLLEXPORT wxFrame;
 
+#if defined(__WXWINCE__) && wxUSE_TOOLBAR
+class WXDLLEXPORT wxToolBar;
+#endif
+
 // ----------------------------------------------------------------------------
 // Menu
 // ----------------------------------------------------------------------------
@@ -153,6 +157,12 @@ public:
     virtual void Detach();
     virtual void Attach(wxFrame *frame);
 
+#if defined(__WXWINCE__) && wxUSE_TOOLBAR
+    // Under WinCE, a menubar is owned by the frame's toolbar
+    void SetToolBar(wxToolBar* toolBar) { m_toolBar = toolBar; }
+    wxToolBar* GetToolBar() const { return m_toolBar; }
+#endif
+
 #if wxUSE_ACCEL
     // get the accel table for all the menus
     const wxAcceleratorTable& GetAccelTable() const { return m_accelTable; }
@@ -189,6 +199,10 @@ protected:
     wxAcceleratorTable m_accelTable;
 #endif // wxUSE_ACCEL
 
+#if defined(__WXWINCE__) && wxUSE_TOOLBAR
+    wxToolBar*  m_toolBar;
+#endif
+
 private:
     DECLARE_DYNAMIC_CLASS(wxMenuBar)
 };
diff --git a/include/wx/msw/wince/tbarwce.h b/include/wx/msw/wince/tbarwce.h
new file mode 100644 (file)
index 0000000..938559a
--- /dev/null
@@ -0,0 +1,148 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wx/msw/wince/tbarwce.h
+// Purpose:     Windows CE wxToolBar class
+// Author:      Julian Smart
+// Modified by:
+// Created:     2003-07-12
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_BARWCE_H_
+#define _WX_BARWCE_H_
+
+#ifdef __GNUG__
+    #pragma interface "tbarwce.h"
+#endif
+
+#if wxUSE_TOOLBAR
+
+#include "wx/dynarray.h"
+
+class WXDLLEXPORT wxToolBar : public wxToolBarBase
+{
+public:
+    // ctors and dtor
+    wxToolBar() { Init(); }
+
+    wxToolBar(wxWindow *parent,
+                wxWindowID id,
+                const wxPoint& pos = wxDefaultPosition,
+                const wxSize& size = wxDefaultSize,
+                long style = wxNO_BORDER | wxTB_HORIZONTAL,
+                const wxString& name = wxToolBarNameStr,
+                wxMenuBar* menuBar = NULL)
+    {
+        Init();
+
+        Create(parent, id, pos, size, style, name, menuBar);
+    }
+
+    bool Create(wxWindow *parent,
+                wxWindowID id,
+                const wxPoint& pos = wxDefaultPosition,
+                const wxSize& size = wxDefaultSize,
+                long style = wxNO_BORDER | wxTB_HORIZONTAL,
+                const wxString& name = wxToolBarNameStr,
+                wxMenuBar* menuBar = NULL);
+
+    virtual ~wxToolBar();
+
+    // 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();
+
+    // Set the wxMenuBar associated with this commandbar
+    void SetMenuBar(wxMenuBar* menuBar) { m_menuBar = menuBar; }
+
+    // Returns the wxMenuBar associated with this commandbar
+    wxMenuBar* GetMenuBar() const { return m_menuBar; }
+
+protected:
+    // common part of all ctors
+    void Init();
+
+    // create the native toolbar control
+    bool MSWCreateToolbar(const wxPoint& pos, const wxSize& size, wxMenuBar* menuBar);
+
+    // recreate the control completely
+    void Recreate();
+
+    // 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);
+
+    // override WndProc mainly to process WM_SIZE
+    virtual long 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 big bitmap containing all bitmaps of the toolbar buttons
+    WXHBITMAP m_hBitmap;
+
+    // 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)
+};
+
+#endif // wxUSE_TOOLBAR
+
+#endif
+    // _WX_BARWCE_H_
index e9371c812af02dd9f1d5d15e93497fc8e871260a..5f27ac35d83995aeedbf568de5883af8559dd597 100644 (file)
        #include <windows.h>
 #endif
 
+#if defined(_WIN32_WCE)
+        #include <commctrl.h>
+#endif
+
 //////////////////////////////////////////////////////////////////////////////
 //
 // This is the MDI Window menu
@@ -53,6 +57,34 @@ BEGIN
     END
 END
 
+#ifdef _WIN32_WCE
+
+// Dummy menubar/toolbar for WinCE
+
+5000 RCDATA DISCARDABLE
+BEGIN
+  // Popup menu name
+  5000,
+  // Count of items to put on the menu
+  0
+END
+
+5000 MENU DISCARDABLE
+BEGIN
+    POPUP "Dummy"
+    BEGIN
+    MENUITEM "Dummy" 99
+    END
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+    5001      "Dummy menu"
+END
+
+#endif
+
+
 //////////////////////////////////////////////////////////////////////////////
 //
 // Standard wxWindows Cursors
index 11878e4760623880a93bf47f26ee8f3c30f07300..c2ba87c44a33d9cb846e131a987077a5662bde39 100644 (file)
@@ -121,6 +121,8 @@ enum
     #else // wxUSE_TOOLBAR_NATIVE
         #if defined(__WXUNIVERSAL__)
            #include "wx/univ/toolbar.h"
+        #elif defined(__WXWINCE__)
+           #include "wx/msw/wince/tbarwce.h"
         #elif defined(__WXMSW__) && defined(__WIN95__)
            #include "wx/msw/tbar95.h"
         #elif defined(__WXMSW__)
index 8298169a69f2a31a0770925d7396598748d6cd49..d6ab0abbfee285a1c2522ba1ce0e650cfa6a3126 100644 (file)
@@ -121,7 +121,11 @@ bool MyApp::OnInit()
 {
     // create the main application window
     MyFrame *frame = new MyFrame(_T("Minimal wxWindows App"),
-                                 wxPoint(50, 50), wxSize(450, 340));
+#ifdef __WXWINCE__
+        wxPoint(0, 0), wxDefaultSize, wxNO_BORDER);
+#else
+        wxPoint(50, 50), wxSize(450, 340));
+#endif
 
     // and show it (the frames, unlike simple controls, are not shown when
     // created initially)
@@ -163,7 +167,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
     SetMenuBar(menuBar);
 #endif // wxUSE_MENUS
 
-#if wxUSE_STATUSBAR
+#if wxUSE_STATUSBAR && !defined(__WXWINCE__)
     // create a status bar just for fun (by default with 1 pane only)
     CreateStatusBar(2);
     SetStatusText(_T("Welcome to wxWindows!"));
index f2dff269be21019194ddedd6b5b7f5964d2f933b..f17d23dddb1b9738a201e50e15465a24df9268c2 100644 (file)
@@ -106,9 +106,6 @@ void wxFrame::Init()
 #if wxUSE_TOOLTIPS
     m_hwndToolTip = 0;
 #endif
-#ifdef __WXWINCE__
-    m_commandBar = 0;
-#endif
 
     // Data to save/restore when calling ShowFullScreen
     m_fsStatusBarFields = 0;
@@ -140,10 +137,6 @@ wxFrame::~wxFrame()
 {
     m_isBeingDeleted = TRUE;
     DeleteAllBars();
-#ifdef __WXWINCE__
-    RemoveCommandBar();
-#endif
-
 }
 
 // ----------------------------------------------------------------------------
@@ -271,6 +264,7 @@ void wxFrame::AttachMenuBar(wxMenuBar *menubar)
     }
     else // set new non NULL menu bar
     {
+#ifndef __WXWINCE__
         // Can set a menubar several times.
         if ( menubar->GetHMenu() )
         {
@@ -286,7 +280,7 @@ void wxFrame::AttachMenuBar(wxMenuBar *menubar)
                 return;
             }
         }
-
+#endif
         InternalSetMenuBar();
     }
 }
@@ -296,18 +290,14 @@ void wxFrame::InternalSetMenuBar()
 #ifdef __WXMICROWIN__
     // Nothing
 #elif defined(__WXWINCE__)
-    
-    CreateCommandBar() ;
 
-    if (m_commandBar)
+    if (!GetToolBar())
     {
-        if (!CommandBar_InsertMenubarEx((HWND) m_commandBar, NULL,
-            (LPTSTR) (HMENU) m_hMenu, 0))
-        {
-            wxFAIL_MSG( _T("failed to set menubar") );
-            return;
-        }
-        CommandBar_DrawMenuBar((HWND) m_commandBar, 0);
+        wxToolBar* toolBar = new wxToolBar(this, -1,
+                         wxDefaultPosition, wxDefaultSize,
+                         wxBORDER_NONE | wxTB_HORIZONTAL,
+                         wxToolBarNameStr, GetMenuBar());
+        SetToolBar(toolBar);
     }
 #else
     if ( !::SetMenu(GetHwnd(), (HMENU)m_hMenu) )
@@ -434,6 +424,11 @@ bool wxFrame::ShowFullScreen(bool show, long style)
 
 wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
 {
+#ifdef __WXWINCE__
+    // We may already have a toolbar from calling SetMenuBar.
+    if (GetToolBar())
+        return GetToolBar();
+#endif
     if ( wxFrameBase::CreateToolBar(style, id, name) )
     {
         PositionToolBar();
@@ -850,30 +845,3 @@ bool wxFrame::HandleInitMenuPopup(WXHMENU hMenu)
 
     return GetEventHandler()->ProcessEvent(event);
 }
-
-#ifdef __WXWINCE__
-WXHWND wxFrame::CreateCommandBar()
-{
-    if (m_commandBar)
-        return m_commandBar;
-
-    m_commandBar = (WXHWND) CommandBar_Create(wxGetInstance(), GetHwnd(), NewControlId());
-    if (!m_commandBar)
-    {
-        wxFAIL_MSG( _T("failed to create commandbar") );
-        return 0;
-    }
-    return m_commandBar;
-}
-
-void wxFrame::RemoveCommandBar()
-{
-    if (m_commandBar)
-    {
-        ::DestroyWindow((HWND) m_commandBar);
-        m_commandBar = NULL;
-    }
-}
-#endif
-
-
index f1a7bb4a2c43a7b3fc5223d4118f6a17131f72b0..6bce598d97bcbefbf583ab69716a91fdc89233f4 100644 (file)
 
 #include "wx/msw/private.h"
 
+#ifdef __WXWINCE__
+#include <windows.h>
+#include <windowsx.h>
+#include <tchar.h>
+#include <ole2.h>
+#include <commctrl.h>
+#include <aygshell.h>
+
+#ifndef TBSTYLE_NO_DROPDOWN_ARROW
+#define TBSTYLE_NO_DROPDOWN_ARROW 0x0080
+#endif
+
+#endif
+
 // other standard headers
 #include <string.h>
 
@@ -260,6 +274,10 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
         id = pItem->GetId();
     }
 
+#ifdef __WXWINCE__
+    wxString strippedString;
+#endif
+
     LPCTSTR pData;
 
 #if wxUSE_OWNER_DRAWN
@@ -274,7 +292,12 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
         // menu is just a normal string (passed in data parameter)
         flags |= MF_STRING;
 
+#ifdef __WXWINCE__
+        strippedString = wxStripMenuCodes(pItem->GetText());
+        pData = (wxChar*)strippedString.c_str();
+#else
         pData = (wxChar*)pItem->GetText().c_str();
+#endif
     }
 
     BOOL ok;
@@ -558,6 +581,9 @@ void wxMenuBar::Init()
 {
     m_eventHandler = this;
     m_hMenu = 0;
+#ifdef __WXWINCE__
+    m_toolBar = NULL;
+#endif
 }
 
 wxMenuBar::wxMenuBar()
@@ -587,6 +613,9 @@ wxMenuBar::wxMenuBar(int count, wxMenu *menus[], const wxString titles[])
 
 wxMenuBar::~wxMenuBar()
 {
+    // In Windows CE, the menubar is always associated
+    // with a toolbar, which destroys the menu implicitly.
+#ifndef __WXWINCE__
     // we should free Windows resources only if Windows doesn't do it for us
     // which happens if we're attached to a frame
     if (m_hMenu && !IsAttached())
@@ -594,6 +623,7 @@ wxMenuBar::~wxMenuBar()
         ::DestroyMenu((HMENU)m_hMenu);
         m_hMenu = (WXHMENU)NULL;
     }
+#endif
 }
 
 // ---------------------------------------------------------------------------
@@ -604,11 +634,53 @@ void wxMenuBar::Refresh()
 {
     wxCHECK_RET( IsAttached(), wxT("can't refresh unattached menubar") );
 
+#ifdef __WXWINCE__
+    if (GetToolBar())
+    {
+        CommandBar_DrawMenuBar((HWND) GetToolBar()->GetHWND(), 0);
+    }
+#else
     DrawMenuBar(GetHwndOf(GetFrame()));
+#endif
 }
 
 WXHMENU wxMenuBar::Create()
 {
+#ifdef __WXWINCE__
+    if ( m_hMenu != 0 )
+        return m_hMenu;
+
+    if (!GetToolBar())
+        return 0;
+
+    HWND hCommandBar = (HWND) GetToolBar()->GetHWND();
+    HMENU hMenu = (HMENU)::SendMessage(hCommandBar, SHCMBM_GETMENU, (WPARAM)0, (LPARAM)0);
+    if (hMenu)
+    {
+        TBBUTTON tbButton; 
+        memset(&tbButton, 0, sizeof(TBBUTTON));
+        tbButton.iBitmap = I_IMAGENONE;
+        tbButton.fsState = TBSTATE_ENABLED;
+        tbButton.fsStyle = TBSTYLE_DROPDOWN | TBSTYLE_NO_DROPDOWN_ARROW | TBSTYLE_AUTOSIZE;
+        
+        size_t i;
+        for (i = 0; i < GetMenuCount(); i++)
+        {
+            HMENU hPopupMenu = (HMENU) GetMenu(i)->GetHMenu() ;
+            tbButton.dwData = (DWORD)hPopupMenu;
+            wxString label = wxStripMenuCodes(GetLabelTop(i));
+            tbButton.iString = (int) label.c_str();
+            
+            tbButton.idCommand = NewControlId();
+            if (!::SendMessage(hCommandBar, TB_INSERTBUTTON, i, (LPARAM)&tbButton))
+            {
+                wxLogLastError(wxT("TB_INSERTBUTTON"));
+            }
+        }
+    }
+    m_hMenu = (WXHMENU) hMenu;
+    return m_hMenu;
+#else
     if ( m_hMenu != 0 )
         return m_hMenu;
 
@@ -634,6 +706,7 @@ WXHMENU wxMenuBar::Create()
     }
 
     return m_hMenu;
+#endif
 }
 
 // ---------------------------------------------------------------------------
@@ -768,13 +841,34 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
 
     if ( IsAttached() )
     {
+#ifdef __WXWINCE__
+        if (!GetToolBar())
+            return FALSE;
+        TBBUTTON tbButton; 
+        memset(&tbButton, 0, sizeof(TBBUTTON));
+        tbButton.iBitmap = I_IMAGENONE;
+        tbButton.fsState = TBSTATE_ENABLED;
+        tbButton.fsStyle = TBSTYLE_DROPDOWN | TBSTYLE_NO_DROPDOWN_ARROW | TBSTYLE_AUTOSIZE;
+        
+        HMENU hPopupMenu = (HMENU) menu->GetHMenu() ;
+        tbButton.dwData = (DWORD)hPopupMenu;
+        wxString label = wxStripMenuCodes(title);
+        tbButton.iString = (int) label.c_str();
+            
+        tbButton.idCommand = NewControlId();
+        if (!::SendMessage((HWND) GetToolBar()->GetHWND(), TB_INSERTBUTTON, pos, (LPARAM)&tbButton))
+        {
+            wxLogLastError(wxT("TB_INSERTBUTTON"));
+            return FALSE;
+        }
+#else
         if ( !::InsertMenu(GetHmenu(), pos,
                            MF_BYPOSITION | MF_POPUP | MF_STRING,
                            (UINT)GetHmenuOf(menu), title) )
         {
             wxLogLastError(wxT("InsertMenu"));
         }
-
+#endif
 #if wxUSE_ACCEL
         if ( menu->HasAccels() )
         {
@@ -801,16 +895,39 @@ bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
 
     if ( IsAttached() )
     {
+#ifdef __WXWINCE__
+        if (!GetToolBar())
+            return FALSE;
+        TBBUTTON tbButton; 
+        memset(&tbButton, 0, sizeof(TBBUTTON));
+        tbButton.iBitmap = I_IMAGENONE;
+        tbButton.fsState = TBSTATE_ENABLED;
+        tbButton.fsStyle = TBSTYLE_DROPDOWN | TBSTYLE_NO_DROPDOWN_ARROW | TBSTYLE_AUTOSIZE;
+        
+        size_t pos = GetMenuCount();
+        HMENU hPopupMenu = (HMENU) menu->GetHMenu() ;
+        tbButton.dwData = (DWORD)hPopupMenu;
+        wxString label = wxStripMenuCodes(title);
+        tbButton.iString = (int) label.c_str();
+            
+        tbButton.idCommand = NewControlId();
+        if (!::SendMessage((HWND) GetToolBar()->GetHWND(), TB_INSERTBUTTON, pos, (LPARAM)&tbButton))
+        {
+            wxLogLastError(wxT("TB_INSERTBUTTON"));
+            return FALSE;
+        }
+#else
         if ( !::AppendMenu(GetHmenu(), MF_POPUP | MF_STRING,
                            (UINT)submenu, title) )
         {
             wxLogLastError(wxT("AppendMenu"));
         }
+#endif
 
 #if wxUSE_ACCEL
         if ( menu->HasAccels() )
         {
-            // need to rebuild accell table
+            // need to rebuild accelerator table
             RebuildAccelTable();
         }
 #endif // wxUSE_ACCEL
@@ -829,11 +946,20 @@ wxMenu *wxMenuBar::Remove(size_t pos)
 
     if ( IsAttached() )
     {
+#ifdef __WXWINCE__
+        if (GetToolBar())
+        {
+            if (!::SendMessage((HWND) GetToolBar()->GetHWND(), TB_DELETEBUTTON, (UINT) pos, (LPARAM) 0))
+            {
+                wxLogLastError(wxT("TB_DELETEBUTTON"));
+            }
+        }
+#else
         if ( !::RemoveMenu(GetHmenu(), (UINT)pos, MF_BYPOSITION) )
         {
             wxLogLastError(wxT("RemoveMenu"));
         }
-
+#endif
 #if wxUSE_ACCEL
         if ( menu->HasAccels() )
         {
index 1c5c52d6729235f7ff9c2c510ab126429652c2b3..9ba29bc069f33617f7b15b8df470adc93422525b 100644 (file)
@@ -200,7 +200,11 @@ wxColour wxSystemSettingsNative::GetColour(wxSystemColour index)
 
     if ( !hasCol )
     {
+#ifdef __WXWINCE__
+        colSys = ::GetSysColor(index|SYS_COLOR_INDEX_FLAG);
+#else
         colSys = ::GetSysColor(index);
+#endif
     }
 
     return wxRGBToColour(colSys);
index 961cd90c52989723b0181b633318bb2344bfb7da..6bc345507ea02864d3b4ee15dbcb685d4f745a1d 100644 (file)
@@ -156,7 +156,12 @@ WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
     if ( style & wxFRAME_TOOL_WINDOW )
         msflags |= WS_POPUP;
     else
-        msflags |= WS_OVERLAPPED;
+    {
+#ifdef __WXWINCE__
+        if (msflags & WS_BORDER)
+#endif
+            msflags |= WS_OVERLAPPED;
+    }
 
     // border and caption styles
     if ( style & wxRESIZE_BORDER )
@@ -167,13 +172,17 @@ WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
     }
     else if ( !(style & wxBORDER_NONE) )
         msflags |= WS_BORDER;
+#ifndef __WXWINCE__
     else
         msflags |= WS_POPUP;
+#endif
 
     if ( style & wxCAPTION )
         msflags |= WS_CAPTION;
+#ifndef __WXWINCE__
     else
         msflags |= WS_POPUP;
+#endif
 
     // next translate the individual flags
     if ( style & wxMINIMIZE_BOX )
diff --git a/src/msw/wince/tbarwce.cpp b/src/msw/wince/tbarwce.cpp
new file mode 100644 (file)
index 0000000..554b07d
--- /dev/null
@@ -0,0 +1,1258 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        msw/wince/tbarwce.cpp
+// Purpose:     wxToolBar for Windows CE
+// Author:      Julian Smart
+// Modified by:
+// Created:     2003-07-12
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+    #pragma implementation "tbarwce.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+    #include "wx/frame.h"
+    #include "wx/log.h"
+    #include "wx/intl.h"
+    #include "wx/dynarray.h"
+    #include "wx/settings.h"
+    #include "wx/bitmap.h"
+    #include "wx/dcmemory.h"
+    #include "wx/control.h"
+#endif
+
+#if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE
+
+#include "wx/toolbar.h"
+
+#if !defined(__GNUWIN32__) && !defined(__SALFORDC__)
+    #include "malloc.h"
+#endif
+
+#include "wx/msw/private.h"
+#include <windows.h>
+#include <windowsx.h>
+#include <tchar.h>
+#include <ole2.h>
+#include <commctrl.h>
+#include <aygshell.h>
+
+#include "wx/msw/winundef.h"
+
+#if defined(__MWERKS__) && defined(__WXMSW__)
+// including <windef.h> 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
+
+// ----------------------------------------------------------------------------
+// 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
+// ----------------------------------------------------------------------------
+
+// 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
+
+// these values correspond to those used by comctl32.dll
+#define DEFAULTBITMAPX   16
+#define DEFAULTBITMAPY   15
+#define DEFAULTBUTTONX   24
+#define DEFAULTBUTTONY   24
+#define DEFAULTBARHEIGHT 27
+
+// ----------------------------------------------------------------------------
+// wxWin macros
+// ----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
+
+BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
+    EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent)
+    EVT_SYS_COLOUR_CHANGED(wxToolBar::OnSysColourChanged)
+END_EVENT_TABLE()
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+class wxToolBarTool : public wxToolBarToolBase
+{
+public:
+    wxToolBarTool(wxToolBar *tbar,
+                  int id,
+                  const wxString& label,
+                  const wxBitmap& bmpNormal,
+                  const wxBitmap& bmpDisabled,
+                  wxItemKind kind,
+                  wxObject *clientData,
+                  const wxString& shortHelp,
+                  const wxString& longHelp)
+        : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpDisabled, kind,
+                            clientData, shortHelp, longHelp)
+    {
+        m_nSepCount = 0;
+    }
+
+    wxToolBarTool(wxToolBar *tbar, wxControl *control)
+        : wxToolBarToolBase(tbar, control)
+    {
+        m_nSepCount = 1;
+    }
+
+    virtual void SetLabel(const wxString& label)
+    {
+        if ( label == m_label )
+            return;
+
+        wxToolBarToolBase::SetLabel(label);
+
+        // we need to update the label shown in the toolbar because it has a
+        // pointer to the internal buffer of the old label
+        //
+        // TODO: use TB_SETBUTTONINFO
+    }
+
+    // set/get the number of separators which we use to cover the space used by
+    // a control in the toolbar
+    void SetSeparatorsCount(size_t count) { m_nSepCount = count; }
+    size_t GetSeparatorsCount() const { return m_nSepCount; }
+
+private:
+    size_t m_nSepCount;
+};
+
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxToolBarTool
+// ----------------------------------------------------------------------------
+
+wxToolBarToolBase *wxToolBar::CreateTool(int id,
+                                         const wxString& label,
+                                         const wxBitmap& bmpNormal,
+                                         const wxBitmap& bmpDisabled,
+                                         wxItemKind kind,
+                                         wxObject *clientData,
+                                         const wxString& shortHelp,
+                                         const wxString& longHelp)
+{
+    return new wxToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
+                             clientData, shortHelp, longHelp);
+}
+
+wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
+{
+    return new wxToolBarTool(this, control);
+}
+
+// ----------------------------------------------------------------------------
+// wxToolBar construction
+// ----------------------------------------------------------------------------
+
+void wxToolBar::Init()
+{
+    m_hBitmap = 0;
+
+    m_nButtons = 0;
+
+    m_defaultWidth = DEFAULTBITMAPX;
+    m_defaultHeight = DEFAULTBITMAPY;
+
+    m_pInTool = 0;
+    m_menuBar = NULL;
+}
+
+bool wxToolBar::Create(wxWindow *parent,
+                       wxWindowID id,
+                       const wxPoint& pos,
+                       const wxSize& size,
+                       long style,
+                       const wxString& name,
+                       wxMenuBar* menuBar)
+{
+    // common initialisation
+    if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) )
+        return FALSE;
+
+    // MSW-specific initialisation
+    if ( !MSWCreateToolbar(pos, size, menuBar) )
+        return FALSE;
+
+    // set up the colors and fonts
+    SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR));
+    SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
+
+    return TRUE;
+}
+
+#ifndef TBSTYLE_NO_DROPDOWN_ARROW
+#define TBSTYLE_NO_DROPDOWN_ARROW 0x0080
+#endif
+
+bool wxToolBar::MSWCreateToolbar(const wxPoint& pos, const wxSize& size, wxMenuBar* menuBar)
+{
+    SetMenuBar(menuBar);
+    if (m_menuBar)
+        m_menuBar->SetToolBar(this);
+
+    // Create the menubar.
+    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") );
+        return FALSE;
+    }
+    
+    SetHWND((WXHWND) mbi.hwndMB);
+/*
+    if (!::SendMessage((HWND) GetHWND(), TB_DELETEBUTTON, 0, (LPARAM) 0))
+    {
+        wxLogLastError(wxT("TB_DELETEBUTTON"));
+    }
+*/    
+    // install wxWindows window proc for this window
+    SubclassWin(m_hWnd);
+
+    if (menuBar)
+        menuBar->Create();
+#if 0
+    {
+        HMENU hMenu = (HMENU)::SendMessage(mbi.hwndMB, SHCMBM_GETMENU, (WPARAM)0, (LPARAM)0);
+        if (hMenu)
+        {
+            TBBUTTON tbButton; 
+            memset(&tbButton, 0, sizeof(TBBUTTON));
+            tbButton.iBitmap = I_IMAGENONE;
+            tbButton.fsState = TBSTATE_ENABLED;
+            tbButton.fsStyle = TBSTYLE_DROPDOWN | TBSTYLE_NO_DROPDOWN_ARROW | TBSTYLE_AUTOSIZE;
+            
+            size_t i;
+            for (i = 0; i < menuBar->GetMenuCount(); i++)
+            {
+                HMENU hPopupMenu = (HMENU) menuBar->GetMenu(i)->GetHMenu() ;
+                tbButton.dwData = (DWORD)hPopupMenu;
+                wxString label = wxStripMenuCodes(menuBar->GetLabelTop(i));
+                tbButton.iString = (int) label.c_str();
+
+                tbButton.idCommand = NewControlId();
+                if (!::SendMessage((HWND) GetHWND(), TB_INSERTBUTTON, i, (LPARAM)&tbButton))
+                {
+                    wxLogLastError(wxT("TB_INSERTBUTTON"));
+                }
+            }
+        }
+    }
+#endif
+    
+#if 0
+    CommandBar_AddToolTips(    hwndCB,    uNumSmallTips,szSmallTips);
+    
+    CommandBar_AddBitmap(hwndCB, HINST_COMMCTRL, IDB_STD_SMALL_COLOR,
+        15, 16, 16);
+    // Add buttons in tbSTDButton to Commandbar
+    CommandBar_AddButtons(hwndCB, sizeof(tbSTDButton)/sizeof(TBBUTTON),
+        tbSTDButton);
+#endif    
+    return TRUE;
+}
+
+void wxToolBar::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);
+
+    // it is for the old bitmap control and can't be used with the new one
+    if ( m_hBitmap )
+    {
+        ::DeleteObject((HBITMAP) m_hBitmap);
+        m_hBitmap = 0;
+    }
+
+    Realize();
+    UpdateSize();
+#endif
+}
+
+wxToolBar::~wxToolBar()
+{
+    // 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();
+    }
+
+    if ( m_hBitmap )
+    {
+        ::DeleteObject((HBITMAP) m_hBitmap);
+    }
+}
+
+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()
+{
+    if (GetHWND())
+    {
+        return (WXHMENU) (HMENU)::SendMessage((HWND) GetHWND(), SHCMBM_GETMENU, (WPARAM)0, (LPARAM)0);
+    }
+    else
+        return 0;
+}
+
+
+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)
+{
+    // nothing special to do here - we really create the toolbar buttons in
+    // Realize() later
+    tool->Attach(this);
+
+    return TRUE;
+}
+
+bool wxToolBar::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
+    // 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::compatibility_iterator 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() - 1;
+        }
+    }
+
+    // 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
+    RECT r;
+    if ( !::SendMessage(GetHwnd(), TB_GETITEMRECT, pos, (LPARAM)&r) )
+    {
+        wxLogLastError(_T("TB_GETITEMRECT"));
+    }
+
+    int width = r.right - r.left;
+
+    if ( tool->IsControl() )
+    {
+        nButtonsToDelete = ((wxToolBarTool *)tool)->GetSeparatorsCount();
+
+        width *= nButtonsToDelete;
+    }
+
+    // do delete all buttons
+    m_nButtons -= nButtonsToDelete;
+    while ( nButtonsToDelete-- > 0 )
+    {
+        if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, pos, 0) )
+        {
+            wxLogLastError(wxT("TB_DELETEBUTTON"));
+
+            return FALSE;
+        }
+    }
+
+    tool->Detach();
+
+    // 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() )
+        {
+            int x;
+            wxControl *control = tool2->GetControl();
+            control->GetPosition(&x, NULL);
+            control->Move(x - width, -1);
+        }
+    }
+
+    return TRUE;
+}
+
+bool wxToolBar::Realize()
+{
+    const size_t nTools = GetToolsCount();
+    if ( nTools == 0 )
+    {
+        // nothing to do
+        return TRUE;
+    }
+
+    const bool isVertical = HasFlag(wxTB_VERTICAL);
+
+#if 0
+    // delete all old buttons, if any
+    for ( size_t pos = 0; pos < m_nButtons; pos++ )
+    {
+        if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, 0, 0) )
+        {
+            wxLogDebug(wxT("TB_DELETEBUTTON failed"));
+        }
+    }
+#endif
+
+    // add the buttons and separators
+    // ------------------------------
+
+    TBBUTTON *buttons = new TBBUTTON[nTools];
+
+    // this array will hold the indices of all controls in the toolbar
+    wxArrayInt controlIds;
+
+    bool lastWasRadio = FALSE;
+    int i = 0;
+    wxToolBarToolsList::Node* node;
+    for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
+    {
+        wxToolBarToolBase *tool = node->GetData();
+
+        TBBUTTON& button = buttons[i];
+
+        wxZeroMemory(button);
+
+        bool isRadio = FALSE;
+        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:
+                    // TODO
+#if 0
+                if ( !HasFlag(wxTB_NOICONS) )
+                    button.iBitmap = bitmapId;
+
+                if ( HasFlag(wxTB_TEXT) )
+                {
+                    const wxString& label = tool->GetLabel();
+                    if ( !label.empty() )
+                    {
+                        button.iString = (int)label.c_str();
+                    }
+                }
+
+                button.idCommand = tool->GetId();
+
+                if ( tool->IsEnabled() )
+                    button.fsState |= TBSTATE_ENABLED;
+                if ( tool->IsToggled() )
+                    button.fsState |= TBSTATE_CHECKED;
+
+                switch ( tool->GetKind() )
+                {
+                    case wxITEM_RADIO:
+                        button.fsStyle = TBSTYLE_CHECKGROUP;
+
+                        if ( !lastWasRadio )
+                        {
+                            // the first item in the radio group is checked by
+                            // default to be consistent with wxGTK and the menu
+                            // radio items
+                            button.fsState |= TBSTATE_CHECKED;
+
+                            tool->Toggle(TRUE);
+                        }
+
+                        isRadio = TRUE;
+                        break;
+
+                    case wxITEM_CHECK:
+                        button.fsStyle = TBSTYLE_CHECK;
+                        break;
+
+                    default:
+                        wxFAIL_MSG( _T("unexpected toolbar button kind") );
+                        // fall through
+
+                    case wxITEM_NORMAL:
+                        button.fsStyle = TBSTYLE_BUTTON;
+                }
+
+                bitmapId++;
+#endif
+                break;
+        }
+
+        lastWasRadio = isRadio;
+
+        i++;
+    }
+
+    // Add buttons in tbSTDButton to Commandbar
+    if (!CommandBar_AddButtons(GetHwnd(), i, buttons))
+    {
+        wxLogLastError(wxT("CommandBar_AddButtons"));
+    }
+
+    delete [] buttons;
+
+#if 0
+    // Deal with the controls finally
+    // ------------------------------
+
+    // adjust the controls size to fit nicely in the toolbar
+    int y = 0;
+    size_t index = 0;
+    for ( node = m_tools.GetFirst(); node; node = node->GetNext(), index++ )
+    {
+        wxToolBarToolBase *tool = node->GetData();
+
+        // we calculate the running y coord for vertical toolbars so we need to
+        // get the items size for all items but for the horizontal ones we
+        // don't need to deal with the non controls
+        bool isControl = tool->IsControl();
+        if ( !isControl && !isVertical )
+            continue;
+
+        // 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(wxT("TB_GETITEMRECT"));
+        }
+
+        if ( !isControl )
+        {
+            // can only be control if isVertical
+            y += r.bottom - r.top;
+
+            continue;
+        }
+
+        wxControl *control = tool->GetControl();
+
+        wxSize size = control->GetSize();
+
+        // the position of the leftmost controls corner
+        int left = -1;
+
+        // 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(wxT("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;
+            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(wxT("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);
+        }
+
+        // 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;
+        }
+
+        int top;
+        if ( isVertical )
+        {
+            left = 0;
+            top = y;
+
+            y += height + 2*GetMargins().y;
+        }
+        else // horizontal toolbar
+        {
+            if ( left == -1 )
+                left = r.left;
+
+            top = r.top;
+        }
+
+        control->Move(left, 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);
+        }
+    }
+#endif
+
+    return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// message handlers
+// ----------------------------------------------------------------------------
+
+bool wxToolBar::MSWCommand(WXUINT WXUNUSED(cmd), WXWORD id)
+{
+    wxToolBarToolBase *tool = FindById((int)id);
+    if ( !tool )
+    {
+        wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED);
+        event.SetEventObject(this);
+        event.SetId(id);
+        event.SetInt(id);
+
+        return GetEventHandler()->ProcessEvent(event);
+    }
+
+    if ( tool->CanBeToggled() )
+    {
+        LRESULT state = ::SendMessage(GetHwnd(), TB_GETSTATE, id, 0);
+        tool->Toggle((state & TBSTATE_CHECKED) != 0);
+    }
+
+    bool toggled = tool->IsToggled();
+
+    // avoid sending the event when a radio button is released, this is not
+    // interesting
+    if ( !tool->CanBeToggled() || tool->GetKind() != wxITEM_RADIO || toggled )
+    {
+        // OnLeftClick() can veto the button state change - for buttons which
+        // may be toggled only, of couse
+        if ( !OnLeftClick((int)id, toggled) && tool->CanBeToggled() )
+        {
+            // revert back
+            toggled = !toggled;
+            tool->SetToggle(toggled);
+
+            ::SendMessage(GetHwnd(), TB_CHECKBUTTON, id, MAKELONG(toggled, 0));
+        }
+    }
+
+    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
+    return FALSE;
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// toolbar geometry
+// ----------------------------------------------------------------------------
+
+void wxToolBar::SetToolBitmapSize(const wxSize& size)
+{
+    wxToolBarBase::SetToolBitmapSize(size);
+
+    ::SendMessage(GetHwnd(), TB_SETBITMAPSIZE, 0, MAKELONG(size.x, size.y));
+}
+
+void wxToolBar::SetRows(int nRows)
+{
+    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();
+}
+
+// The button size is bigger than the bitmap size
+wxSize wxToolBar::GetToolSize() const
+{
+    // 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);
+    }
+}
+
+static
+wxToolBarToolBase *GetItemSkippingDummySpacers(const wxToolBarToolsList& tools,
+                                               size_t index )
+{
+    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;
+    }
+
+    return 0;
+}
+
+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;
+    }
+
+    // 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 );
+    }
+}
+
+void wxToolBar::UpdateSize()
+{
+    // 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();
+    }
+}
+
+// ----------------------------------------------------------------------------
+// toolbar styles
+// ---------------------------------------------------------------------------
+
+void wxToolBar::SetWindowStyleFlag(long style)
+{
+    // 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();
+    }
+}
+
+// ----------------------------------------------------------------------------
+// tool state
+// ----------------------------------------------------------------------------
+
+void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool enable)
+{
+    ::SendMessage(GetHwnd(), TB_ENABLEBUTTON,
+                  (WPARAM)tool->GetId(), (LPARAM)MAKELONG(enable, 0));
+}
+
+void wxToolBar::DoToggleTool(wxToolBarToolBase *tool, bool 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 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() );
+    }
+}
+
+long 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);
+}
+
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+WXHBITMAP wxToolBar::MapBitmap(WXHBITMAP bitmap, int width, int height)
+{
+    MemoryHDC hdcMem;
+
+    if ( !hdcMem )
+    {
+        wxLogLastError(_T("CreateCompatibleDC"));
+
+        return bitmap;
+    }
+
+    SelectInHDC bmpInHDC(hdcMem, (HBITMAP)bitmap);
+
+    if ( !bmpInHDC )
+    {
+        wxLogLastError(_T("SelectObject"));
+
+        return bitmap;
+    }
+
+    wxCOLORMAP *cmap = wxGetStdColourMap();
+
+    for ( int i = 0; i < width; i++ )
+    {
+        for ( int j = 0; j < height; j++ )
+        {
+            COLORREF pixel = ::GetPixel(hdcMem, i, j);
+
+            for ( size_t k = 0; k < wxSTD_COL_MAX; k++ )
+            {
+                COLORREF col = cmap[k].from;
+                if ( abs(GetRValue(pixel) - GetRValue(col)) < 10 &&
+                     abs(GetGValue(pixel) - GetGValue(col)) < 10 &&
+                     abs(GetBValue(pixel) - GetBValue(col)) < 10 )
+                {
+                    ::SetPixel(hdcMem, i, j, cmap[k].to);
+                    break;
+                }
+            }
+        }
+    }
+
+    return bitmap;
+
+    // VZ: I leave here my attempts to map the bitmap to the system colours
+    //     faster by using BitBlt() even though it's broken currently - but
+    //     maybe someone else can finish it? It should be faster than iterating
+    //     over all pixels...
+#if 0
+    MemoryHDC hdcMask, hdcDst;
+    if ( !hdcMask || !hdcDst )
+    {
+        wxLogLastError(_T("CreateCompatibleDC"));
+
+        return bitmap;
+    }
+
+    // create the target bitmap
+    HBITMAP hbmpDst = ::CreateCompatibleBitmap(hdcDst, width, height);
+    if ( !hbmpDst )
+    {
+        wxLogLastError(_T("CreateCompatibleBitmap"));
+
+        return bitmap;
+    }
+
+    // create the monochrome mask bitmap
+    HBITMAP hbmpMask = ::CreateBitmap(width, height, 1, 1, 0);
+    if ( !hbmpMask )
+    {
+        wxLogLastError(_T("CreateBitmap(mono)"));
+
+        ::DeleteObject(hbmpDst);
+
+        return bitmap;
+    }
+
+    SelectInHDC bmpInDst(hdcDst, hbmpDst),
+                bmpInMask(hdcMask, hbmpMask);
+
+    // for each colour:
+    for ( n = 0; n < NUM_OF_MAPPED_COLOURS; n++ )
+    {
+        // create the mask for this colour
+        ::SetBkColor(hdcMem, ColorMap[n].from);
+        ::BitBlt(hdcMask, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY);
+
+        // replace this colour with the target one in the dst bitmap
+        HBRUSH hbr = ::CreateSolidBrush(ColorMap[n].to);
+        HGDIOBJ hbrOld = ::SelectObject(hdcDst, hbr);
+
+        ::MaskBlt(hdcDst, 0, 0, width, height,
+                  hdcMem, 0, 0,
+                  hbmpMask, 0, 0,
+                  MAKEROP4(PATCOPY, SRCCOPY));
+
+        (void)::SelectObject(hdcDst, hbrOld);
+        ::DeleteObject(hbr);
+    }
+
+    ::DeleteObject((HBITMAP)bitmap);
+
+    return (WXHBITMAP)hbmpDst;
+#endif // 0
+}
+
+#endif // wxUSE_TOOLBAR && Win95
+
index 78e16bb4d20bea3053fa471cb416023aab11be8f..51243e639252b8a7d971b1b29c40bd30c974b57f 100644 (file)
@@ -2978,18 +2978,37 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
     // do create the window
     wxWindowCreationHook hook(this);
 
-    m_hWnd = (WXHWND)::CreateWindowEx
-                       (
-                            extendedStyle,
-                            className,
-                            title ? title : wxEmptyString,
-                            style,
-                            x, y, w, h,
-                            (HWND)MSWGetParent(),
-                            (HMENU)controlId,
-                            wxGetInstance(),
-                            NULL                        // no extra data
-                       );
+#ifdef __WXWINCE__
+    if (extendedStyle == 0)
+    {
+        m_hWnd = (WXHWND)::CreateWindow
+            (
+            className,
+            title ? title : wxEmptyString,
+            style,
+            x, y, w, h,
+            (HWND)MSWGetParent(),
+            (HMENU)controlId,
+            wxGetInstance(),
+            NULL                        // no extra data
+            );
+    }
+    else
+#endif
+    {
+        m_hWnd = (WXHWND)::CreateWindowEx
+            (
+            extendedStyle,
+            className,
+            title ? title : wxEmptyString,
+            style,
+            x, y, w, h,
+            (HWND)MSWGetParent(),
+            (HMENU)controlId,
+            wxGetInstance(),
+            NULL                        // no extra data
+            );
+    }
 
     if ( !m_hWnd )
     {