]> git.saurik.com Git - wxWidgets.git/commitdiff
*** empty log message ***
authorDavid Webster <Dave.Webster@bhmi.com>
Mon, 18 Oct 1999 03:30:47 +0000 (03:30 +0000)
committerDavid Webster <Dave.Webster@bhmi.com>
Mon, 18 Oct 1999 03:30:47 +0000 (03:30 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4043 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

28 files changed:
include/wx/os2/setup.h
include/wx/os2/setup0.h
include/wx/os2/stattext.h
include/wx/os2/statusbr.h
include/wx/os2/tabctrl.h
include/wx/os2/taskbar.h
include/wx/os2/textctrl.h
include/wx/os2/timer.h
include/wx/os2/toolbar.h
include/wx/os2/tooltip.h
include/wx/os2/treectrl.h
include/wx/os2/wave.h
include/wx/treectrl.h
src/os2/makefile.va
src/os2/statbrpm.cpp [new file with mode: 0644]
src/os2/stattext.cpp
src/os2/statusbr.cpp
src/os2/tabctrl.cpp
src/os2/taskbar.cpp
src/os2/textctrl.cpp
src/os2/thread.cpp
src/os2/timer.cpp
src/os2/toolbar.cpp
src/os2/tooltip.cpp [new file with mode: 0644]
src/os2/treectrl.cpp
src/os2/utils.cpp
src/os2/utilsexc.cpp
src/os2/wave.cpp

index 0c84daebefa931af0aabb0bf99f6437dc452dbca..2e9ba2801af4a50dc118be499a1c1f2cd387c833 100644 (file)
@@ -30,6 +30,8 @@
 // General features
 // ----------------------------------------------------------------------------
 
+#define wxUSE_NET_API          1 // Utilize OS/2's UPM netapi's
+
 #define wxUSE_CONFIG           1
                                 // Use wxConfig, with CreateConfig in wxApp
 
index 0c84daebefa931af0aabb0bf99f6437dc452dbca..2e9ba2801af4a50dc118be499a1c1f2cd387c833 100644 (file)
@@ -30,6 +30,8 @@
 // General features
 // ----------------------------------------------------------------------------
 
+#define wxUSE_NET_API          1 // Utilize OS/2's UPM netapi's
+
 #define wxUSE_CONFIG           1
                                 // Use wxConfig, with CreateConfig in wxApp
 
index aa8eaf229eb9731065a8474cffd145c543ad046e..bd58678f7663053fb70032c5c47e6689594e8784 100644 (file)
@@ -1,12 +1,12 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        stattext.h
 // Purpose:     wxStaticText class
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_STATTEXT_H_
@@ -22,34 +22,41 @@ WXDLLEXPORT_DATA(extern const char*) wxStaticTextNameStr;
 
 class WXDLLEXPORT wxStaticText: public wxControl
 {
-  DECLARE_DYNAMIC_CLASS(wxStaticText)
+ DECLARE_DYNAMIC_CLASS(wxStaticText)
+
  public:
-  inline wxStaticText() { }
+    inline wxStaticText() { }
 
-  inline wxStaticText(wxWindow *parent, wxWindowID id,
+    inline wxStaticText(wxWindow *parent, wxWindowID id,
            const wxString& label,
            const wxPoint& pos = wxDefaultPosition,
            const wxSize& size = wxDefaultSize,
            long style = 0,
            const wxString& name = wxStaticTextNameStr)
-  {
-    Create(parent, id, label, pos, size, style, name);
-  }
+    {
+        Create(parent, id, label, pos, size, style, name);
+    }
 
-  bool Create(wxWindow *parent, wxWindowID id,
+    bool Create(wxWindow *parent, wxWindowID id,
            const wxString& label,
            const wxPoint& pos = wxDefaultPosition,
            const wxSize& size = wxDefaultSize,
            long style = 0,
            const wxString& name = wxStaticTextNameStr);
 
-  // accessors
-  void SetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO);
-  void SetLabel(const wxString&);
+    // accessors
+    void SetLabel(const wxString&);
+
+    // overriden base class virtuals
+    virtual bool AcceptsFocus() const { return FALSE; }
+
+    // callbacks
+    virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
+                                WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
+    virtual MRESULT OS2WindowProc(HWND hwnd, WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
 
-  // operations
-  virtual void Command(wxCommandEvent& WXUNUSED(event)) {};
-  virtual void ProcessCommand(wxCommandEvent& WXUNUSED(event)) {};
+protected:
+    virtual wxSize DoGetBestSize();
 };
 
 #endif
index 28567b19e1fed20b9e3dff8488b1df863378c4fc..3e8b21e7057e5bcc9e4b2b8936a408c91db7c02b 100644 (file)
@@ -2,31 +2,25 @@
 // Name:        statusbr.h
 // Purpose:     native implementation of wxStatusBar. Optional; can use generic
 //              version instead.
-// Author:      AUTHOR
-// Modified by: 
-// Created:     ??/??/98
+// Author:      David Webster
+// Modified by:
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
+// Copyright:   (c) David Webster
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 #ifndef   _WX_STATBAR_H_
 #define   _WX_STATBAR_H_
 
-#ifdef __GNUG__
-#pragma interface "statbar.h"
-#endif
-
-#include "wx/generic/statusbr.h"
-
-class WXDLLEXPORT wxStatusBarXX : public wxStatusBar
+class WXDLLEXPORT wxStatusBarPM : public wxStatusBar
 {
-  DECLARE_DYNAMIC_CLASS(wxStatusBarXX);
+  DECLARE_DYNAMIC_CLASS(wxStatusBarPM);
 
 public:
   // ctors
-  wxStatusBarXX();
-  wxStatusBarXX(wxWindow *parent, wxWindowID id = -1, long style = wxST_SIZEGRIP);
+  wxStatusBarPM();
+  wxStatusBarPM(wxWindow *parent, wxWindowID id = -1, long style = wxST_SIZEGRIP);
 
   // create status line
   bool Create(wxWindow *parent, wxWindowID id = -1, long style = wxST_SIZEGRIP);
@@ -50,4 +44,5 @@ protected:
   void SetFieldsWidth();
 };
 
-#endif
+#endif // _WX_STATBAR_H_
+
index 80740019b432287a5217841dd1acd14203b0b8bf..524af3ed90d9faa87692f69ac18ccebc33e18e98 100644 (file)
@@ -1,21 +1,17 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        tabctrl.h
 // Purpose:     wxTabCtrl class
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
 // Created:     ??/??/98
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_TABCTRL_H_
 #define _WX_TABCTRL_H_
 
-#ifdef __GNUG__
-#pragma interface "tabctrl.h"
-#endif
-
 class wxImageList;
 
 /*
@@ -111,7 +107,10 @@ class WXDLLEXPORT wxTabCtrl: public wxControl
     // Insert an item
     bool InsertItem(int item, const wxString& text, int imageId = -1, void* data = NULL);
 
-    void Command(wxCommandEvent& event);
+    virtual bool OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
+
+    // Responds to colour changes
+    void OnSysColourChanged(wxSysColourChangedEvent& event);
 
 protected:
     wxImageList*    m_imageList;
index 7f4a36b8b4e7a125539eb4a496d77addab4dd967..aa25c67c414852ba8bcc7609f8fbf2c8caaf8c0a 100644 (file)
@@ -2,48 +2,91 @@
 // File:        taskbar.h
 // Purpose:        Defines wxTaskBarIcon class for manipulating icons on the
 //              task bar. Optional.
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c)
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_TASKBAR_H_
 #define _WX_TASKBAR_H_
 
-#ifdef __GNUG__
-#pragma interface "taskbar.h"
-#endif
-
+#include <wx/event.h>
 #include <wx/list.h>
 #include <wx/icon.h>
 
-class wxTaskBarIcon: public wxObject
-{
+class WXDLLEXPORT wxTaskBarIcon: public wxEvtHandler {
+    DECLARE_DYNAMIC_CLASS(wxTaskBarIcon)
 public:
-       wxTaskBarIcon();
-       virtual ~wxTaskBarIcon();
+    wxTaskBarIcon(void);
+    virtual ~wxTaskBarIcon(void);
 
 // Accessors
+    inline WXHWND GetHWND() const { return m_hWnd; }
+    inline bool IsOK() const { return (m_hWnd != 0) ; }
+    inline bool IsIconInstalled() const { return m_iconAdded; }
 
 // Operations
     bool SetIcon(const wxIcon& icon, const wxString& tooltip = "");
-    bool RemoveIcon();
+    bool RemoveIcon(void);
+    bool PopupMenu(wxMenu *menu); //, int x, int y);
 
 // Overridables
-    virtual void OnMouseMove();
-    virtual void OnLButtonDown();
-    virtual void OnLButtonUp();
-    virtual void OnRButtonDown();
-    virtual void OnRButtonUp();
-    virtual void OnLButtonDClick();
-    virtual void OnRButtonDClick();
+    virtual void OnMouseMove(wxEvent&);
+    virtual void OnLButtonDown(wxEvent&);
+    virtual void OnLButtonUp(wxEvent&);
+    virtual void OnRButtonDown(wxEvent&);
+    virtual void OnRButtonUp(wxEvent&);
+    virtual void OnLButtonDClick(wxEvent&);
+    virtual void OnRButtonDClick(wxEvent&);
+
+// Implementation
+    static wxTaskBarIcon* FindObjectForHWND(WXHWND hWnd);
+    static void AddObject(wxTaskBarIcon* obj);
+    static void RemoveObject(wxTaskBarIcon* obj);
+    static bool RegisterWindowClass();
+    static WXHWND CreateTaskBarWindow();
+    MRESULT WindowProc( WXHWND hWnd, UINT msg, MPARAM wParam, MPARAM lParam );
 
 // Data members
 protected:
+    WXHWND          m_hWnd;
+    bool            m_iconAdded;
+    static wxList   sm_taskBarIcons;
+    static bool     sm_registeredClass;
+    static unsigned int sm_taskbarMsg;
+
+    // non-virtual default event handlers to forward events to the virtuals
+    void _OnMouseMove(wxEvent&);
+    void _OnLButtonDown(wxEvent&);
+    void _OnLButtonUp(wxEvent&);
+    void _OnRButtonDown(wxEvent&);
+    void _OnRButtonUp(wxEvent&);
+    void _OnLButtonDClick(wxEvent&);
+    void _OnRButtonDClick(wxEvent&);
+
+    DECLARE_EVENT_TABLE()
 };
 
+const wxEventType wxEVT_TASKBAR_MOVE =                  wxEVT_FIRST + 1550;
+const wxEventType wxEVT_TASKBAR_LEFT_DOWN =             wxEVT_FIRST + 1551;
+const wxEventType wxEVT_TASKBAR_LEFT_UP =               wxEVT_FIRST + 1552;
+const wxEventType wxEVT_TASKBAR_RIGHT_DOWN =            wxEVT_FIRST + 1553;
+const wxEventType wxEVT_TASKBAR_RIGHT_UP =              wxEVT_FIRST + 1554;
+const wxEventType wxEVT_TASKBAR_LEFT_DCLICK =           wxEVT_FIRST + 1555;
+const wxEventType wxEVT_TASKBAR_RIGHT_DCLICK =          wxEVT_FIRST + 1556;
+
+#define EVT_TASKBAR_MOVE(fn)         { wxEVT_TASKBAR_MOVE, -1, -1, (wxObjectEventFunction) (wxEventFunction) &fn, NULL },
+#define EVT_TASKBAR_LEFT_DOWN(fn)    { wxEVT_TASKBAR_LEFT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) &fn, NULL },
+#define EVT_TASKBAR_LEFT_UP(fn)      { wxEVT_TASKBAR_LEFT_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) &fn, NULL },
+#define EVT_TASKBAR_RIGHT_DOWN(fn)   { wxEVT_TASKBAR_RIGHT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) &fn, NULL },
+#define EVT_TASKBAR_RIGHT_UP(fn)     { wxEVT_TASKBAR_RIGHT_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) &fn, NULL },
+#define EVT_TASKBAR_LEFT_DCLICK(fn)  { wxEVT_TASKBAR_LEFT_DCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) &fn, NULL },
+#define EVT_TASKBAR_RIGHT_DCLICK(fn) { wxEVT_TASKBAR_RIGHT_DCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) &fn, NULL },
+
+
 #endif
-    // _WX_TASKBAR_H_
+    // _TASKBAR_H_
+
index 09c11e063e5cd3c58a90c39678b7dfdccef175f6..7bf7bdb077b30528039e16f3fa5386dca5d05163 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
 // Name:        textctrl.h
 // Purpose:     wxTextCtrl class
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_TEXTCTRL_H_
 #define _WX_TEXTCTRL_H_
 
-#ifdef __GNUG__
-#pragma interface "textctrl.h"
-#endif
-
-#include "wx/control.h"
-
-#if wxUSE_IOSTREAMH
-#include <iostream.h>
-#else
-#include <iostream>
-#endif
-
-WXDLLEXPORT_DATA(extern const char*) wxTextCtrlNameStr;
-WXDLLEXPORT_DATA(extern const char*) wxEmptyString;
-
-// Single-line text item
-class WXDLLEXPORT wxTextCtrl: public wxControl
+class WXDLLEXPORT wxTextCtrl : public wxTextCtrlBase
+{
+public:
+    // creation
+    // --------
+
+    wxTextCtrl();
+    wxTextCtrl(wxWindow *parent, wxWindowID id,
+               const wxString& value = wxEmptyString,
+               const wxPoint& pos = wxDefaultPosition,
+               const wxSize& size = wxDefaultSize,
+               long style = 0,
+               const wxValidator& validator = wxDefaultValidator,
+               const wxString& name = wxTextCtrlNameStr)
+    {
+        Create(parent, id, value, pos, size, style, validator, name);
+    }
+
+    bool Create(wxWindow *parent, wxWindowID id,
+                const wxString& value = wxEmptyString,
+                const wxPoint& pos = wxDefaultPosition,
+                const wxSize& size = wxDefaultSize,
+                long style = 0,
+                const wxValidator& validator = wxDefaultValidator,
+                const wxString& name = wxTextCtrlNameStr);
+
+    // implement base class pure virtuals
+    // ----------------------------------
+
+    virtual wxString GetValue() const;
+    virtual void SetValue(const wxString& value);
+
+    virtual int GetLineLength(long lineNo) const;
+    virtual wxString GetLineText(long lineNo) const;
+    virtual int GetNumberOfLines() const;
+
+    virtual bool IsModified() const;
+    virtual bool IsEditable() const;
+
+    // If the return values from and to are the same, there is no selection.
+    virtual void GetSelection(long* from, long* to) const;
+
+    // operations
+    // ----------
+
+    // editing
+    virtual void Clear();
+    virtual void Replace(long from, long to, const wxString& value);
+    virtual void Remove(long from, long to);
+
+    // load the controls contents from the file
+    virtual bool LoadFile(const wxString& file);
+
+    // clears the dirty flag
+    virtual void DiscardEdits();
+
+    // writing text inserts it at the current position, appending always
+    // inserts it at the end
+    virtual void WriteText(const wxString& text);
+    virtual void AppendText(const wxString& text);
+
+    // translate between the position (which is just an index in the text ctrl
+    // considering all its contents as a single strings) and (x, y) coordinates
+    // which represent column and line.
+    virtual long XYToPosition(long x, long y) const;
+    virtual bool PositionToXY(long pos, long *x, long *y) const;
+
+    virtual void ShowPosition(long pos);
+
+    // Clipboard operations
+    virtual void Copy();
+    virtual void Cut();
+    virtual void Paste();
+
+    virtual bool CanCopy() const;
+    virtual bool CanCut() const;
+    virtual bool CanPaste() const;
+
+    // Undo/redo
+    virtual void Undo();
+    virtual void Redo();
+
+    virtual bool CanUndo() const;
+    virtual bool CanRedo() const;
+
+    // Insertion point
+    virtual void SetInsertionPoint(long pos);
+    virtual void SetInsertionPointEnd();
+    virtual long GetInsertionPoint() const;
+    virtual long GetLastPosition() const;
+
+    virtual void SetSelection(long from, long to);
+    virtual void SetEditable(bool editable);
+
+    // Implementation from now on
+    // --------------------------
+
+    virtual void Command(wxCommandEvent& event);
+    virtual bool OS2Command(WXUINT param, WXWORD id);
+
+    virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
+                                WXUINT message, WXWPARAM wParam,
+                                WXLPARAM lParam);
+
+    virtual void AdoptAttributesFromHWND();
+    virtual void SetupColours();
+
+    virtual bool AcceptsFocus() const;
+
+    // callbacks
+    void OnDropFiles(wxDropFilesEvent& event);
+    void OnChar(wxKeyEvent& event); // Process 'enter' if required
 
-// TODO Some platforms/compilers don't like inheritance from streambuf.
+    void OnCut(wxCommandEvent& event);
+    void OnCopy(wxCommandEvent& event);
+    void OnPaste(wxCommandEvent& event);
+    void OnUndo(wxCommandEvent& event);
+    void OnRedo(wxCommandEvent& event);
 
-#if (defined(__BORLANDC__) && !defined(__WIN32__)) || defined(__MWERKS__)
-#define NO_TEXT_WINDOW_STREAM
-#endif
+    void OnUpdateCut(wxUpdateUIEvent& event);
+    void OnUpdateCopy(wxUpdateUIEvent& event);
+    void OnUpdatePaste(wxUpdateUIEvent& event);
+    void OnUpdateUndo(wxUpdateUIEvent& event);
+    void OnUpdateRedo(wxUpdateUIEvent& event);
 
-#ifndef NO_TEXT_WINDOW_STREAM
-, public streambuf
-#endif
+protected:
+    // call this to increase the size limit (will do nothing if the current
+    // limit is big enough)
+    void AdjustSpaceLimit();
 
-{
-  DECLARE_DYNAMIC_CLASS(wxTextCtrl)
-    
-public:
-  // creation
-  // --------
-  wxTextCtrl();
-  inline wxTextCtrl(wxWindow *parent, wxWindowID id,
-                    const wxString& value = wxEmptyString,
-                    const wxPoint& pos = wxDefaultPosition,
-                    const wxSize& size = wxDefaultSize, long style = 0,
-                    const wxValidator& validator = wxDefaultValidator,
-                    const wxString& name = wxTextCtrlNameStr)
-#ifndef NO_TEXT_WINDOW_STREAM
-    :streambuf()
-#endif
-  {
-    Create(parent, id, value, pos, size, style, validator, name);
-  }
-  
-  bool Create(wxWindow *parent, wxWindowID id,
-              const wxString& value = wxEmptyString,
-              const wxPoint& pos = wxDefaultPosition,
-              const wxSize& size = wxDefaultSize, long style = 0,
-              const wxValidator& validator = wxDefaultValidator,
-              const wxString& name = wxTextCtrlNameStr);
-  
-  // accessors
-  // ---------
-  virtual wxString GetValue() const ;
-  virtual void SetValue(const wxString& value);
-
-  virtual int GetLineLength(long lineNo) const;
-  virtual wxString GetLineText(long lineNo) const;
-  virtual int GetNumberOfLines() const;
-
-  // operations
-  // ----------
-  virtual void SetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO);
-  
-  // Clipboard operations
-  virtual void Copy();
-  virtual void Cut();
-  virtual void Paste();
-  
-  virtual bool CanCopy() const;
-  virtual bool CanCut() const;
-  virtual bool CanPaste() const;
-
-  // Undo/redo
-  virtual void Undo();
-  virtual void Redo();
-
-  virtual bool CanUndo() const;
-  virtual bool CanRedo() const;
-
-  virtual void SetInsertionPoint(long pos);
-  virtual void SetInsertionPointEnd();
-  virtual long GetInsertionPoint() const ;
-  virtual long GetLastPosition() const ;
-  virtual void Replace(long from, long to, const wxString& value);
-  virtual void Remove(long from, long to);
-  virtual void SetSelection(long from, long to);
-  virtual void SetEditable(bool editable);
-
-  // If the return values from and to are the same, there is no
-  // selection.
-  virtual void GetSelection(long* from, long* to) const;
-  virtual bool IsEditable() const ;
-
-  // streambuf implementation
-#ifndef NO_TEXT_WINDOW_STREAM
-  int overflow(int i);
-  int sync();
-  int underflow();
-#endif
-  
-  wxTextCtrl& operator<<(const wxString& s);
-  wxTextCtrl& operator<<(int i);
-  wxTextCtrl& operator<<(long i);
-  wxTextCtrl& operator<<(float f);
-  wxTextCtrl& operator<<(double d);
-  wxTextCtrl& operator<<(const char c);
-  
-  virtual bool LoadFile(const wxString& file);
-  virtual bool SaveFile(const wxString& file);
-  virtual void WriteText(const wxString& text);
-  virtual void AppendText(const wxString& text);
-  virtual void DiscardEdits();
-  virtual bool IsModified() const;
-  
-  virtual long XYToPosition(long x, long y) const ;
-  virtual void PositionToXY(long pos, long *x, long *y) const ;
-  virtual void ShowPosition(long pos);
-  virtual void Clear();
-  
-  // callbacks
-  // ---------
-  void OnDropFiles(wxDropFilesEvent& event);
-//  void OnChar(wxKeyEvent& event); // Process 'enter' if required
-//  void OnEraseBackground(wxEraseEvent& event);
-  void OnCut(wxCommandEvent& event);
-  void OnCopy(wxCommandEvent& event);
-  void OnPaste(wxCommandEvent& event);
-  void OnUndo(wxCommandEvent& event);
-  void OnRedo(wxCommandEvent& event);
-
-  void OnUpdateCut(wxUpdateUIEvent& event);
-  void OnUpdateCopy(wxUpdateUIEvent& event);
-  void OnUpdatePaste(wxUpdateUIEvent& event);
-  void OnUpdateUndo(wxUpdateUIEvent& event);
-  void OnUpdateRedo(wxUpdateUIEvent& event);
-
-  // Implementation
-  // --------------
-  virtual void Command(wxCommandEvent& event);
+    virtual wxSize DoGetBestSize();
 
-protected:
-  wxString  m_fileName;
-  
-  DECLARE_EVENT_TABLE()
+private:
+    DECLARE_EVENT_TABLE()
+    DECLARE_DYNAMIC_CLASS(wxTextCtrl)
 };
 
 #endif
index d24372425a0cde42d9d5c3352e23fa71399830cc..975e76499bd44776150c6a130a2553f3b1ecf674 100644 (file)
@@ -1,25 +1,23 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        timer.h
 // Purpose:     wxTimer class
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_TIMER_H_
 #define _WX_TIMER_H_
 
-#ifdef __GNUG__
-#pragma interface "timer.h"
-#endif
-
 #include "wx/object.h"
 
 class WXDLLEXPORT wxTimer: public wxObject
 {
+friend void wxProcessTimer(wxTimer& timer);
+
 public:
     wxTimer();
     ~wxTimer();
@@ -31,32 +29,19 @@ public:
     virtual void Notify() = 0;                 // Override this member
 
     // Returns the current interval time (0 if stop)
-    int Interval() const { return m_milli; };
-    bool OneShot() const { return m_oneShot; }
+    int Interval() const { return milli; };
+    bool OneShot() const { return oneShot; }
 
 protected:
-    bool m_oneShot ;
-    int  m_milli ;
-    int  m_lastMilli ;
+    bool oneShot ;
+    int  milli ;
+    int  lastMilli ;
 
-    long m_id;
+    long id;
 
 private:
     DECLARE_ABSTRACT_CLASS(wxTimer)
 };
 
-/* Note: these are implemented in common/timercmn.cpp, so need to implement them separately.
- * But you may need to modify timercmn.cpp.
- */
-
-// Timer functions (milliseconds)
-void WXDLLEXPORT wxStartTimer();
-
-// EXPERIMENTAL: comment this out if it doesn't compile.
-bool WXDLLEXPORT wxGetLocalTime(long *timeZone, int *dstObserved);
-
-// Get number of seconds since 00:00:00 GMT, Jan 1st 1970.
-long WXDLLEXPORT wxGetCurrentTime();
-
 #endif
     // _WX_TIMER_H_
index e9fa1e679addb7edecaf2d66e7c9c9ce9f128fad..9b1eff8e721c03ec2ea08241aa6800398b58c0c6 100644 (file)
@@ -1,24 +1,21 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        toolbar.h
 // Purpose:     wxToolBar class
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/98
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_TOOLBAR_H_
 #define _WX_TOOLBAR_H_
 
-#ifdef __GNUG__
-#pragma interface "toolbar.h"
-#endif
-
+#if wxUSE_TOOLBAR
 #include "wx/tbarbase.h"
 
-WXDLLEXPORT_DATA(extern const char*) wxToolBarNameStr;
+WXDLLEXPORT_DATA(extern const wxChar*) wxToolBarNameStr;
 
 class WXDLLEXPORT wxToolBar: public wxToolBarBase
 {
@@ -42,6 +39,9 @@ class WXDLLEXPORT wxToolBar: public wxToolBarBase
             long style = wxNO_BORDER|wxTB_HORIZONTAL,
             const wxString& name = wxToolBarNameStr);
 
+  // Call default behaviour
+  void OnMouseEvent(wxMouseEvent& event);
+
   // If pushedBitmap is NULL, a reversed version of bitmap is
   // created and used as the pushed/toggled image.
   // If toggle is TRUE, the button toggles between the two states.
@@ -60,18 +60,30 @@ class WXDLLEXPORT wxToolBar: public wxToolBarBase
 
   wxSize GetMaxSize() const;
 
+  virtual bool GetToolState(int toolIndex) const;
+
   // Add all the buttons
   virtual bool CreateTools();
-  virtual bool Layout() { return TRUE; }
+  virtual void SetRows(int nRows);
+  virtual void LayoutButtons() {}
 
-  // The post-tool-addition call. TODO: do here whatever's
-  // necessary for completing the toolbar construction.
+  // The post-tool-addition call
   bool Realize() { return CreateTools(); };
 
+  // IMPLEMENTATION
+  virtual bool OS2Command(WXUINT param, WXWORD id);
+  virtual bool OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
+
+  // Responds to colour changes
+  void OnSysColourChanged(wxSysColourChangedEvent& event);
+
 protected:
+  WXHBITMAP         m_hBitmap;
 
 DECLARE_EVENT_TABLE()
 };
 
+#endif // wxUSE_TOOLBAR
+
 #endif
     // _WX_TOOLBAR_H_
index 8b7f805f1aa277a356605a0bf5ae6153854795c7..493225f84fd9985d990400fe1542f66e81f71abf 100644 (file)
@@ -1,11 +1,11 @@
 ///////////////////////////////////////////////////////////////////////////////
 // Name:        msw/tooltip.h
 // Purpose:     wxToolTip class - tooltip control
-// Author:      Vadim Zeitlin
+// Author:      David Webster
 // Modified by:
-// Created:     31.01.99
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) 1999 Robert Roebling, Vadim Zeitlin
+// Copyright:   (c) David Webster
 // Licence:     wxWindows license
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -35,6 +35,7 @@ public:
     void RelayEvent(WXMSG *msg);
 
 private:
+    static WXHWND hwndTT;
     // create the tooltip ctrl for our parent frame if it doesn't exist yet
     // and return its window handle
     WXHWND GetToolTipCtrl();
index cb307ec0e97284e31b80b0ea031e5f84ada85f87..03a386c715a95a53a7254ebb974b3e578687d772 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
 // Name:        treectrl.h
 // Purpose:     wxTreeCtrl class
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_TREECTRL_H_
 #define _WX_TREECTRL_H_
 
-#ifdef __GNUG__
-#pragma interface "treectrl.h"
-#endif
-
-#include "wx/control.h"
-#include "wx/event.h"
-#include "wx/imaglist.h"
-
-#define wxTREE_MASK_HANDLE          0x0001
-#define wxTREE_MASK_STATE           0x0002
-#define wxTREE_MASK_TEXT            0x0004
-#define wxTREE_MASK_IMAGE           0x0008
-#define wxTREE_MASK_SELECTED_IMAGE  0x0010
-#define wxTREE_MASK_CHILDREN        0x0020
-#define wxTREE_MASK_DATA            0x0040
-
-#define wxTREE_STATE_BOLD           0x0001
-#define wxTREE_STATE_DROPHILITED    0x0002
-#define wxTREE_STATE_EXPANDED       0x0004
-#define wxTREE_STATE_EXPANDEDONCE   0x0008
-#define wxTREE_STATE_FOCUSED        0x0010
-#define wxTREE_STATE_SELECTED       0x0020
-#define wxTREE_STATE_CUT            0x0040
-
-#define wxTREE_HITTEST_ABOVE            0x0001  // Above the client area.
-#define wxTREE_HITTEST_BELOW            0x0002  // Below the client area.
-#define wxTREE_HITTEST_NOWHERE          0x0004  // In the client area but below the last item.
-#define wxTREE_HITTEST_ONITEMBUTTON     0x0010  // On the button associated with an item.
-#define wxTREE_HITTEST_ONITEMICON       0x0020  // On the bitmap associated with an item.
-#define wxTREE_HITTEST_ONITEMINDENT     0x0040  // In the indentation associated with an item.
-#define wxTREE_HITTEST_ONITEMLABEL      0x0080  // On the label (string) associated with an item.
-#define wxTREE_HITTEST_ONITEMRIGHT      0x0100  // In the area to the right of an item.
-#define wxTREE_HITTEST_ONITEMSTATEICON  0x0200  // On the state icon for a tree view item that is in a user-defined state.
-#define wxTREE_HITTEST_TOLEFT           0x0400  // To the right of the client area.
-#define wxTREE_HITTEST_TORIGHT          0x0800  // To the left of the client area.
-
-#define wxTREE_HITTEST_ONITEM (wxTREE_HITTEST_ONITEMICON | wxTREE_HITTEST_ONITEMLABEL | wxTREE_HITTEST_ONITEMSTATEICON)
-
-// Flags for GetNextItem
-enum {
-    wxTREE_NEXT_CARET,                 // Retrieves the currently selected item.
-    wxTREE_NEXT_CHILD,                 // Retrieves the first child item. The hItem parameter must be NULL.
-    wxTREE_NEXT_DROPHILITE,            // Retrieves the item that is the target of a drag-and-drop operation.
-    wxTREE_NEXT_FIRSTVISIBLE,          // Retrieves the first visible item.
-    wxTREE_NEXT_NEXT,                 // Retrieves the next sibling item.
-    wxTREE_NEXT_NEXTVISIBLE,           // Retrieves the next visible item that follows the specified item.
-    wxTREE_NEXT_PARENT,                // Retrieves the parent of the specified item.
-    wxTREE_NEXT_PREVIOUS,              // Retrieves the previous sibling item.
-    wxTREE_NEXT_PREVIOUSVISIBLE,       // Retrieves the first visible item that precedes the specified item.
-    wxTREE_NEXT_ROOT                   // Retrieves the first child item of the root item of which the specified item is a part.
-};
-
-// Flags for ExpandItem
-enum {
+#include "wx/textctrl.h"
+#include "wx/dynarray.h"
+
+// the type for "untyped" data
+typedef long wxDataType;
+
+// fwd decl
+class  WXDLLEXPORT wxImageList;
+struct WXDLLEXPORT wxTreeViewItem;
+
+// a callback function used for sorting tree items, it should return -1 if the
+// first item precedes the second, +1 if the second precedes the first or 0 if
+// they're equivalent
+class wxTreeItemData;
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// values for the `flags' parameter of wxTreeCtrl::HitTest() which determine
+// where exactly the specified point is situated:
+    // above the client area.
+static const int wxTREE_HITTEST_ABOVE            = 0x0001;
+    // below the client area.
+static const int wxTREE_HITTEST_BELOW            = 0x0002;
+    // in the client area but below the last item.
+static const int wxTREE_HITTEST_NOWHERE          = 0x0004;
+    // on the button associated with an item.
+static const int wxTREE_HITTEST_ONITEMBUTTON     = 0x0010;
+    // on the bitmap associated with an item.
+static const int wxTREE_HITTEST_ONITEMICON       = 0x0020;
+    // in the indentation associated with an item.
+static const int wxTREE_HITTEST_ONITEMINDENT     = 0x0040;
+    // on the label (string) associated with an item.
+static const int wxTREE_HITTEST_ONITEMLABEL      = 0x0080;
+    // in the area to the right of an item.
+static const int wxTREE_HITTEST_ONITEMRIGHT      = 0x0100;
+    // on the state icon for a tree view item that is in a user-defined state.
+static const int wxTREE_HITTEST_ONITEMSTATEICON  = 0x0200;
+    // to the right of the client area.
+static const int wxTREE_HITTEST_TOLEFT           = 0x0400;
+    // to the left of the client area.
+static const int wxTREE_HITTEST_TORIGHT          = 0x0800;
+    // anywhere on the item
+static const int wxTREE_HITTEST_ONITEM  = wxTREE_HITTEST_ONITEMICON |
+                                          wxTREE_HITTEST_ONITEMLABEL |
+                                          wxTREE_HITTEST_ONITEMSTATEICON;
+
+// NB: all the following flags are for compatbility only and will be removed in the
+//     next versions
+
+// flags for deprecated `Expand(int action)'
+enum
+{
     wxTREE_EXPAND_EXPAND,
     wxTREE_EXPAND_COLLAPSE,
     wxTREE_EXPAND_COLLAPSE_RESET,
     wxTREE_EXPAND_TOGGLE
 };
 
-// Flags for InsertItem
-enum {
-    wxTREE_INSERT_LAST = -1,
-    wxTREE_INSERT_FIRST = -2,
-    wxTREE_INSERT_SORT = -3
+// flags for deprecated InsertItem() variant
+#define wxTREE_INSERT_FIRST 0xFFFF0001
+#define wxTREE_INSERT_LAST  0xFFFF0002
+
+// ----------------------------------------------------------------------------
+// wxTreeItemId identifies an element of the tree. In this implementation, it's
+// just a trivial wrapper around Win32 HTREEITEM. It's opaque for the
+// application.
+// ----------------------------------------------------------------------------
+class WXDLLEXPORT wxTreeItemId
+{
+public:
+    // ctors
+        // 0 is invalid value for HTREEITEM
+    wxTreeItemId() { m_itemId = 0; }
+
+        // default copy ctor/assignment operator are ok for us
+
+    // accessors
+        // is this a valid tree item?
+    bool IsOk() const { return m_itemId != 0; }
+
+    // conversion to/from either real (system-dependent) tree item id or
+    // to "long" which used to be the type for tree item ids in previous
+    // versions of wxWindows
+
+    // for wxTreeCtrl usage only
+    wxTreeItemId(WXHTREEITEM itemId) { m_itemId = (long)itemId; }
+    operator WXHTREEITEM() const { return (WXHTREEITEM)m_itemId; }
+
+    void operator=(WXHTREEITEM item) { m_itemId = (long) item; }
+
+protected:
+    long m_itemId;
 };
 
-class WXDLLEXPORT wxTreeItem: public wxObject
+WX_DEFINE_EXPORTED_ARRAY(wxTreeItemId, wxArrayTreeItemIds);
+
+// ----------------------------------------------------------------------------
+// wxTreeItemData is some (arbitrary) user class associated with some item. The
+// main advantage of having this class (compared to old untyped interface) is
+// that wxTreeItemData's are destroyed automatically by the tree and, as this
+// class has virtual dtor, it means that the memory will be automatically
+// freed. OTOH, we don't just use wxObject instead of wxTreeItemData because
+// the size of this class is critical: in any real application, each tree leaf
+// will have wxTreeItemData associated with it and number of leaves may be
+// quite big.
+//
+// Because the objects of this class are deleted by the tree, they should
+// always be allocated on the heap!
+// ----------------------------------------------------------------------------
+class WXDLLEXPORT wxTreeItemData : private wxTreeItemId
 {
- DECLARE_DYNAMIC_CLASS(wxTreeItem)
 public:
-    long            m_mask;
-    long            m_itemId;
-    long            m_state;
-    long            m_stateMask;
-    wxString        m_text;
-    int             m_image;
-    int             m_selectedImage;
-    int             m_children;
-    long            m_data;
-
-    wxTreeItem();
-
-// Accessors
-    inline long GetMask() const { return m_mask; }
-    inline long GetItemId() const { return m_itemId; }
-    inline long GetState() const { return m_state; }
-    inline long GetStateMask() const { return m_stateMask; }
-    inline wxString GetText() const { return m_text; }
-    inline int GetImage() const { return m_image; }
-    inline int GetSelectedImage() const { return m_selectedImage; }
-    inline int GetChildren() const { return m_children; }
-    inline long GetData() const { return m_data; }
-
-    inline void SetMask(long mask) { m_mask = mask; }
-    inline void SetItemId(long id) { m_itemId = m_itemId = id; }
-    inline void SetState(long state) { m_state = state; }
-    inline void SetStateMask(long stateMask) { m_stateMask = stateMask; }
-    inline void GetText(const wxString& text) { m_text = text; }
-    inline void SetImage(int image) { m_image = image; }
-    inline void GetSelectedImage(int selImage) { m_selectedImage = selImage; }
-    inline void SetChildren(int children) { m_children = children; }
-    inline void SetData(long data) { m_data = data; }
+    // default ctor/copy ctor/assignment operator are ok
+
+    // dtor is virtual and all the items are deleted by the tree control when
+    // it's deleted, so you normally don't have to care about freeing memory
+    // allocated in your wxTreeItemData-derived class
+    virtual ~wxTreeItemData() { }
+
+    // accessors: set/get the item associated with this node
+    void SetId(const wxTreeItemId& id) { m_itemId = id; }
+    const wxTreeItemId GetId() const { return *this; }
 };
 
-class WXDLLEXPORT wxTreeCtrl: public wxControl
+// ----------------------------------------------------------------------------
+// wxTreeCtrl
+// ----------------------------------------------------------------------------
+class WXDLLEXPORT wxTreeCtrl : public wxControl
 {
 public:
-   /*
-    * Public interface
-    */
-    
     // creation
     // --------
-    wxTreeCtrl();
-    
-    inline wxTreeCtrl(wxWindow *parent, wxWindowID id = -1,
-        const wxPoint& pos = wxDefaultPosition,
-        const wxSize& size = wxDefaultSize,
-        long style = wxTR_HAS_BUTTONS|wxTR_LINES_AT_ROOT,
-        const wxValidator& validator = wxDefaultValidator,
-        const wxString& name = "wxTreeCtrl")
+    wxTreeCtrl() { Init(); }
+
+    wxTreeCtrl(wxWindow *parent, wxWindowID id = -1,
+               const wxPoint& pos = wxDefaultPosition,
+               const wxSize& size = wxDefaultSize,
+               long style = wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT,
+               const wxValidator& validator = wxDefaultValidator,
+               const wxString& name = "wxTreeCtrl")
     {
         Create(parent, id, pos, size, style, validator, name);
     }
-    ~wxTreeCtrl();
-    
+
+    virtual ~wxTreeCtrl();
+
     bool Create(wxWindow *parent, wxWindowID id = -1,
                 const wxPoint& pos = wxDefaultPosition,
                 const wxSize& size = wxDefaultSize,
-                long style = wxTR_HAS_BUTTONS|wxTR_LINES_AT_ROOT,
+                long style = wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT,
                 const wxValidator& validator = wxDefaultValidator,
                 const wxString& name = "wxTreeCtrl");
-    
+
     // accessors
     // ---------
-      //
-    int GetCount() const;
-
-      // indent
-    int GetIndent() const;
-    void SetIndent(int indent);
-      // image list
-    wxImageList *GetImageList(int which = wxIMAGE_LIST_NORMAL) const;
-    void SetImageList(wxImageList *imageList, int which = wxIMAGE_LIST_NORMAL);
-
-      // navigation inside the tree
-    long GetNextItem(long item, int code) const;
-    bool ItemHasChildren(long item) const;
-    long GetChild(long item) const;
-    long GetParent(long item) const;
-    long GetFirstVisibleItem() const;
-    long GetNextVisibleItem(long item) const;
-    long GetSelection() const;
-    long GetRootItem() const;
-
-      // generic function for (g|s)etting item attributes
-    bool GetItem(wxTreeItem& info) const;
-    bool SetItem(wxTreeItem& info);
-      // item state
-    int  GetItemState(long item, long stateMask) const;
-    bool SetItemState(long item, long state, long stateMask);
-      // item image
-    bool SetItemImage(long item, int image, int selImage);
-      // item text
-    wxString GetItemText(long item) const;
-    void SetItemText(long item, const wxString& str);
-      // custom data associated with the item
-    long GetItemData(long item) const;
-    bool SetItemData(long item, long data);
-      // convenience function
-    bool IsItemExpanded(long item) 
-    { 
-      return (GetItemState(item, wxTREE_STATE_EXPANDED) & 
-                           wxTREE_STATE_EXPANDED) != 0;
-    }
 
-      // bounding rect
-    bool GetItemRect(long item, wxRect& rect, bool textOnly = FALSE) const;
-      //
-    wxTextCtrl* GetEditControl() const;
-    
+        // get the total number of items in the control
+    size_t GetCount() const;
+
+        // indent is the number of pixels the children are indented relative to
+        // the parents position. SetIndent() also redraws the control
+        // immediately.
+    unsigned int GetIndent() const;
+    void SetIndent(unsigned int indent);
+
+    // spacing is the number of pixels between the start and the Text
+        // not implemented under wxMSW
+    unsigned int GetSpacing() const { return 18; } // return wxGTK default
+    void SetSpacing(unsigned int WXUNUSED(spacing)) { }
+
+        // image list: these functions allow to associate an image list with
+        // the control and retrieve it. Note that the control does _not_ delete
+        // the associated image list when it's deleted in order to allow image
+        // lists to be shared between different controls.
+        //
+        // The normal image list is for the icons which correspond to the
+        // normal tree item state (whether it is selected or not).
+        // Additionally, the application might choose to show a state icon
+        // which corresponds to an app-defined item state (for example,
+        // checked/unchecked) which are taken from the state image list.
+    wxImageList *GetImageList() const;
+    wxImageList *GetStateImageList() const;
+
+    void SetImageList(wxImageList *imageList);
+    void SetStateImageList(wxImageList *imageList);
+
+    // Functions to work with tree ctrl items. Unfortunately, they can _not_ be
+    // member functions of wxTreeItem because they must know the tree the item
+    // belongs to for Windows implementation and storing the pointer to
+    // wxTreeCtrl in each wxTreeItem is just too much waste.
+
+    // accessors
+    // ---------
+
+        // retrieve items label
+    wxString GetItemText(const wxTreeItemId& item) const;
+        // get one of the images associated with the item (normal by default)
+    int GetItemImage(const wxTreeItemId& item,
+                     wxTreeItemIcon which = wxTreeItemIcon_Normal) const;
+        // get the data associated with the item
+    wxTreeItemData *GetItemData(const wxTreeItemId& item) const;
+
+    // modifiers
+    // ---------
+
+        // set items label
+    void SetItemText(const wxTreeItemId& item, const wxString& text);
+        // get one of the images associated with the item (normal by default)
+    void SetItemImage(const wxTreeItemId& item, int image,
+                      wxTreeItemIcon which = wxTreeItemIcon_Normal);
+        // associate some data with the item
+    void SetItemData(const wxTreeItemId& item, wxTreeItemData *data);
+
+        // force appearance of [+] button near the item. This is useful to
+        // allow the user to expand the items which don't have any children now
+        // - but instead add them only when needed, thus minimizing memory
+        // usage and loading time.
+    void SetItemHasChildren(const wxTreeItemId& item, bool has = TRUE);
+
+        // the item will be shown in bold
+    void SetItemBold(const wxTreeItemId& item, bool bold = TRUE);
+
+        // the item will be shown with a drop highlight
+    void SetItemDropHighlight(const wxTreeItemId& item, bool highlight = TRUE);
+
+    // item status inquiries
+    // ---------------------
+
+        // is the item visible (it might be outside the view or not expanded)?
+    bool IsVisible(const wxTreeItemId& item) const;
+        // does the item has any children?
+    bool ItemHasChildren(const wxTreeItemId& item) const;
+        // is the item expanded (only makes sense if HasChildren())?
+    bool IsExpanded(const wxTreeItemId& item) const;
+        // is this item currently selected (the same as has focus)?
+    bool IsSelected(const wxTreeItemId& item) const;
+        // is item text in bold font?
+    bool IsBold(const wxTreeItemId& item) const;
+
+    // number of children
+    // ------------------
+
+        // if 'recursively' is FALSE, only immediate children count, otherwise
+        // the returned number is the number of all items in this branch
+    size_t GetChildrenCount(const wxTreeItemId& item,
+                            bool recursively = TRUE) const;
+
+    // navigation
+    // ----------
+
+    // wxTreeItemId.IsOk() will return FALSE if there is no such item
+
+        // get the root tree item
+    wxTreeItemId GetRootItem() const;
+
+        // get the item currently selected (may return NULL if no selection)
+    wxTreeItemId GetSelection() const;
+
+        // get the items currently selected, return the number of such item
+        //
+        // NB: this operation is expensive and can take a long time for a
+        //     control with a lot of items (~ O(number of items)).
+    size_t GetSelections(wxArrayTreeItemIds& selections) const;
+
+        // get the parent of this item (may return NULL if root)
+    wxTreeItemId GetParent(const wxTreeItemId& item) const;
+
+        // for this enumeration function you must pass in a "cookie" parameter
+        // which is opaque for the application but is necessary for the library
+        // to make these functions reentrant (i.e. allow more than one
+        // enumeration on one and the same object simultaneously). Of course,
+        // the "cookie" passed to GetFirstChild() and GetNextChild() should be
+        // the same!
+
+        // get the first child of this item
+    wxTreeItemId GetFirstChild(const wxTreeItemId& item, long& _cookie) const;
+        // get the next child
+    wxTreeItemId GetNextChild(const wxTreeItemId& item, long& _cookie) const;
+        // get the last child of this item - this method doesn't use cookies
+    wxTreeItemId GetLastChild(const wxTreeItemId& item) const;
+
+        // get the next sibling of this item
+    wxTreeItemId GetNextSibling(const wxTreeItemId& item) const;
+        // get the previous sibling
+    wxTreeItemId GetPrevSibling(const wxTreeItemId& item) const;
+
+        // get first visible item
+    wxTreeItemId GetFirstVisibleItem() const;
+        // get the next visible item: item must be visible itself!
+        // see IsVisible() and wxTreeCtrl::GetFirstVisibleItem()
+    wxTreeItemId GetNextVisible(const wxTreeItemId& item) const;
+        // get the previous visible item: item must be visible itself!
+    wxTreeItemId GetPrevVisible(const wxTreeItemId& item) const;
+
     // operations
     // ----------
-      // adding/deleting items
-    bool DeleteItem(long item);
-    long InsertItem(long parent, wxTreeItem& info,
-                    long insertAfter = wxTREE_INSERT_LAST);
-      // If image > -1 and selImage == -1, the same image is used for
-      // both selected and unselected items.
-    long InsertItem(long parent, const wxString& label,
-                    int image = -1, int selImage = -1, 
-                    long insertAfter = wxTREE_INSERT_LAST);
-
-      // changing item state
-    bool ExpandItem(long item)   { return ExpandItem(item, wxTREE_EXPAND_EXPAND);   }
-    bool CollapseItem(long item) { return ExpandItem(item, wxTREE_EXPAND_COLLAPSE); }
-    bool ToggleItem(long item)   { return ExpandItem(item, wxTREE_EXPAND_TOGGLE);   }
-      // common interface for {Expand|Collapse|Toggle}Item
-    bool ExpandItem(long item, int action);
-    
-      // 
-    bool SelectItem(long item);
-    bool ScrollTo(long item);
-    bool DeleteAllItems();
-
-    // Edit the label (tree must have the focus)
-    wxTextCtrl* EditLabel(long item, wxClassInfo* textControlClass = CLASSINFO(wxTextCtrl));
-
-    // End label editing, optionally cancelling the edit
-    bool EndEditLabel(bool cancel);
-
-    long HitTest(const wxPoint& point, int& flags);
-    //  wxImageList *CreateDragImage(long item);
-    bool SortChildren(long item);
-    bool EnsureVisible(long item);
-    
-    void Command(wxCommandEvent& event) { ProcessCommand(event); };
+
+        // add the root node to the tree
+    wxTreeItemId AddRoot(const wxString& text,
+                         int image = -1, int selectedImage = -1,
+                         wxTreeItemData *data = NULL);
+
+        // insert a new item in as the first child of the parent
+    wxTreeItemId PrependItem(const wxTreeItemId& parent,
+                             const wxString& text,
+                             int image = -1, int selectedImage = -1,
+                             wxTreeItemData *data = NULL);
+
+        // insert a new item after a given one
+    wxTreeItemId InsertItem(const wxTreeItemId& parent,
+                            const wxTreeItemId& idPrevious,
+                            const wxString& text,
+                            int image = -1, int selectedImage = -1,
+                            wxTreeItemData *data = NULL);
+
+        // insert a new item in as the last child of the parent
+    wxTreeItemId AppendItem(const wxTreeItemId& parent,
+                            const wxString& text,
+                            int image = -1, int selectedImage = -1,
+                            wxTreeItemData *data = NULL);
+
+        // delete this item and associated data if any
+    void Delete(const wxTreeItemId& item);
+        // delete all children (but don't delete the item itself)
+        // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events
+    void DeleteChildren(const wxTreeItemId& item);
+        // delete all items from the tree
+        // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events
+    void DeleteAllItems();
+
+        // expand this item
+    void Expand(const wxTreeItemId& item);
+        // collapse the item without removing its children
+    void Collapse(const wxTreeItemId& item);
+        // collapse the item and remove all children
+    void CollapseAndReset(const wxTreeItemId& item);
+        // toggles the current state
+    void Toggle(const wxTreeItemId& item);
+
+        // remove the selection from currently selected item (if any)
+    void Unselect();
+        // unselect all items (only makes sense for multiple selection control)
+    void UnselectAll();
+        // select this item
+    void SelectItem(const wxTreeItemId& item);
+        // make sure this item is visible (expanding the parent item and/or
+        // scrolling to this item if necessary)
+    void EnsureVisible(const wxTreeItemId& item);
+        // scroll to this item (but don't expand its parent)
+    void ScrollTo(const wxTreeItemId& item);
+
+        // start editing the item label: this (temporarily) replaces the item
+        // with a one line edit control. The item will be selected if it hadn't
+        // been before. textCtrlClass parameter allows you to create an edit
+        // control of arbitrary user-defined class deriving from wxTextCtrl.
+    wxTextCtrl* EditLabel(const wxTreeItemId& item,
+                          wxClassInfo* textCtrlClass = CLASSINFO(wxTextCtrl));
+        // returns the same pointer as StartEdit() if the item is being edited,
+        // NULL otherwise (it's assumed that no more than one item may be
+        // edited simultaneously)
+    wxTextCtrl* GetEditControl() const;
+        // end editing and accept or discard the changes to item label
+    void EndEditLabel(const wxTreeItemId& item, bool discardChanges = FALSE);
+
+    // sorting
+        // this function is called to compare 2 items and should return -1, 0
+        // or +1 if the first item is less than, equal to or greater than the
+        // second one. The base class version performs alphabetic comparaison
+        // of item labels (GetText)
+    virtual int OnCompareItems(const wxTreeItemId& item1,
+                               const wxTreeItemId& item2);
+        // sort the children of this item using OnCompareItems
+        //
+        // NB: this function is not reentrant and not MT-safe (FIXME)!
+    void SortChildren(const wxTreeItemId& item);
+
+    // helpers
+    // -------
+
+        // determine to which item (if any) belongs the given point (the
+        // coordinates specified are relative to the client area of tree ctrl)
+        // and fill the flags parameter with a bitmask of wxTREE_HITTEST_xxx
+        // constants.
+        //
+        // The first function is more portable (because easier to implement
+        // on other platforms), but the second one returns some extra info.
+    wxTreeItemId HitTest(const wxPoint& point)
+        { int dummy; return HitTest(point, dummy); }
+    wxTreeItemId HitTest(const wxPoint& point, int& flags);
+
+        // get the bounding rectangle of the item (or of its label only)
+    bool GetBoundingRect(const wxTreeItemId& item,
+                         wxRect& rect,
+                         bool textOnly = FALSE) const;
+
+    // deprecated
+    // ----------
+
+    // these methods are deprecated and will be removed in future versions of
+    // wxWindows, they're here for compatibility only, don't use them in new
+    // code (the comments indicate why these methods are now useless and how to
+    // replace them)
+
+        // use Expand, Collapse, CollapseAndReset or Toggle
+    void ExpandItem(const wxTreeItemId& item, int action);
+
+        // use AddRoot, PrependItem or AppendItem
+    wxTreeItemId InsertItem(const wxTreeItemId& parent,
+                            const wxString& text,
+                            int image = -1, int selImage = -1,
+                            long insertAfter = wxTREE_INSERT_LAST);
+
+        // use Set/GetImageList and Set/GetStateImageList
+    wxImageList *GetImageList(int) const
+        { return GetImageList(); }
+    void SetImageList(wxImageList *imageList, int)
+        { SetImageList(imageList); }
+
+    // use Set/GetItemImage directly
+        // get the selected item image
+    int GetItemSelectedImage(const wxTreeItemId& item) const
+        { return GetItemImage(item, wxTreeItemIcon_Selected); }
+        // set the selected item image
+    void SetItemSelectedImage(const wxTreeItemId& item, int image)
+        { SetItemImage(item, image, wxTreeItemIcon_Selected); }
+
+    // implementation
+    // --------------
+    virtual bool OS2Command(WXUINT param, WXWORD id);
+    virtual bool OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
+
+    // get/set the check state for the item (only for wxTR_MULTIPLE)
+    bool IsItemChecked(const wxTreeItemId& item) const;
+    void SetItemCheck(const wxTreeItemId& item, bool check = TRUE);
 
 protected:
-    wxTextCtrl*  m_textCtrl;
-    wxImageList* m_imageListNormal;
-    wxImageList* m_imageListState;
+    // SetImageList helper
+    void SetAnyImageList(wxImageList *imageList, int which);
 
-    DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
-};
+    wxTextCtrl  *m_textCtrl;        // used while editing the item label
+    wxImageList *m_imageListNormal, // images for tree elements
+                *m_imageListState;  // special images for app defined states
 
-/*
- wxEVT_COMMAND_TREE_BEGIN_DRAG,
- wxEVT_COMMAND_TREE_BEGIN_RDRAG,
- wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT,
- wxEVT_COMMAND_TREE_END_LABEL_EDIT,
- wxEVT_COMMAND_TREE_DELETE_ITEM,
- wxEVT_COMMAND_TREE_GET_INFO,
- wxEVT_COMMAND_TREE_SET_INFO,
- wxEVT_COMMAND_TREE_ITEM_EXPANDED,
- wxEVT_COMMAND_TREE_ITEM_EXPANDING,
- wxEVT_COMMAND_TREE_ITEM_COLLAPSED,
- wxEVT_COMMAND_TREE_ITEM_COLLAPSING,
- wxEVT_COMMAND_TREE_SEL_CHANGED,
- wxEVT_COMMAND_TREE_SEL_CHANGING,
- wxEVT_COMMAND_TREE_KEY_DOWN
-*/
-
-class WXDLLEXPORT wxTreeEvent: public wxCommandEvent
-{
-  DECLARE_DYNAMIC_CLASS(wxTreeEvent)
+private:
+    // the common part of all ctors
+    void Init();
 
- public:
-  wxTreeEvent(wxEventType commandType = wxEVT_NULL, int id = 0);
+    // helper functions
+    inline bool DoGetItem(wxTreeViewItem *tvItem) const;
+    inline void DoSetItem(wxTreeViewItem *tvItem);
 
-  int           m_code;
-  wxTreeItem    m_item;
-  long          m_oldItem;
-  wxPoint       m_pointDrag;
+    inline void DoExpand(const wxTreeItemId& item, int flag);
 
-  inline long GetOldItem() const { return m_oldItem; }
-  inline wxTreeItem& GetItem() const { return (wxTreeItem&) m_item; }
-  inline wxPoint GetPoint() const { return m_pointDrag; }
-  inline int GetCode() const { return m_code; }
-};
+    wxTreeItemId DoInsertItem(const wxTreeItemId& parent,
+                              wxTreeItemId hInsertAfter,
+                              const wxString& text,
+                              int image, int selectedImage,
+                              wxTreeItemData *data);
+
+    int DoGetItemImageFromData(const wxTreeItemId& item,
+                               wxTreeItemIcon which) const;
+    void DoSetItemImageFromData(const wxTreeItemId& item,
+                                int image,
+                                wxTreeItemIcon which) const;
+    void DoSetItemImages(const wxTreeItemId& item, int image, int imageSel);
 
-typedef void (wxEvtHandler::*wxTreeEventFunction)(wxTreeEvent&);
-
-#define EVT_TREE_BEGIN_DRAG(id, fn) { wxEVT_COMMAND_TREE_BEGIN_DRAG, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_BEGIN_RDRAG(id, fn) { wxEVT_COMMAND_TREE_BEGIN_RDRAG, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_BEGIN_LABEL_EDIT(id, fn) { wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_END_LABEL_EDIT(id, fn) { wxEVT_COMMAND_TREE_END_LABEL_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_DELETE_ITEM(id, fn) { wxEVT_COMMAND_TREE_DELETE_ITEM, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_GET_INFO(id, fn) { wxEVT_COMMAND_TREE_GET_INFO, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_SET_INFO(id, fn) { wxEVT_COMMAND_TREE_SET_INFO, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_ITEM_EXPANDED(id, fn) { wxEVT_COMMAND_TREE_ITEM_EXPANDED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_ITEM_EXPANDING(id, fn) { wxEVT_COMMAND_TREE_ITEM_EXPANDING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_ITEM_COLLAPSED(id, fn) { wxEVT_COMMAND_TREE_ITEM_COLLAPSED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_ITEM_COLLAPSING(id, fn) { wxEVT_COMMAND_TREE_ITEM_COLLAPSING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_SEL_CHANGED(id, fn) { wxEVT_COMMAND_TREE_SEL_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_SEL_CHANGING(id, fn) { wxEVT_COMMAND_TREE_SEL_CHANGING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
-#define EVT_TREE_KEY_DOWN(id, fn) { wxEVT_COMMAND_TREE_KEY_DOWN, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
+    void DeleteTextCtrl();
+
+    // support for additional item images
+    friend class wxTreeItemIndirectData;
+    void SetIndirectItemData(const wxTreeItemId& item,
+                             wxTreeItemIndirectData *data);
+    bool HasIndirectData(const wxTreeItemId& item) const;
+
+    wxArrayTreeItemIds m_itemsWithIndirectData;
+
+    DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
+};
 
 #endif
     // _WX_TREECTRL_H_
index e55bd5aa5f4a220c725c37df5ca76fd28a309e12..fdfce64dc743062b633d123d510d30c33f4e9064 100644 (file)
@@ -2,21 +2,17 @@
 // Name:        wave.h
 // Purpose:     wxWave class (loads and plays short Windows .wav files).
 //              Optional on non-Windows platforms.
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_WAVE_H_
 #define _WX_WAVE_H_
 
-#ifdef __GNUG__
-#pragma interface "wave.h"
-#endif
-
 #include "wx/object.h"
 
 class wxWave : public wxObject
@@ -24,10 +20,15 @@ class wxWave : public wxObject
 public:
   wxWave();
   wxWave(const wxString& fileName, bool isResource = FALSE);
+  wxWave(int size, const wxByte* data);
   ~wxWave();
 
 public:
+  // Create from resource or file
   bool  Create(const wxString& fileName, bool isResource = FALSE);
+  // Create from data
+  bool Create(int size, const wxByte* data);
+
   bool  IsOk() const { return (m_waveData ? TRUE : FALSE); };
   bool  Play(bool async = TRUE, bool looped = FALSE) const;
 
@@ -35,7 +36,7 @@ protected:
   bool  Free();
 
 private:
-  char* m_waveData;
+  wxByte* m_waveData;
   int   m_waveLength;
   bool  m_isResource;
 };
index cacdbe2dc3eab448358f9fd0eded5b885b5b9ec6..33dbe7a1262d5c4d94db4564cacf1de6cb1a7112 100644 (file)
@@ -48,7 +48,7 @@ enum wxTreeItemIcon
 #elif defined(__WXMAC__)
     #include "wx/generic/treectrl.h"
 #elif defined(__WXPM__)
-    #include "wx/generic/treectrl.h"
+    #include "wx/os2/treectrl.h"
 #elif defined(__WXSTUBS__)
     #include "wx/generic/treectrl.h"
 #endif
@@ -119,7 +119,7 @@ typedef void (wxEvtHandler::*wxTreeEventFunction)(wxTreeEvent&);
 #define EVT_TREE_GET_INFO(id, fn) { wxEVT_COMMAND_TREE_GET_INFO, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
 #define EVT_TREE_SET_INFO(id, fn) { wxEVT_COMMAND_TREE_SET_INFO, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
 
-// GetItem() is the item being expanded/collapsed, the "ING" versions can use 
+// GetItem() is the item being expanded/collapsed, the "ING" versions can use
 #define EVT_TREE_ITEM_EXPANDED(id, fn) { wxEVT_COMMAND_TREE_ITEM_EXPANDED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
 #define EVT_TREE_ITEM_EXPANDING(id, fn) { wxEVT_COMMAND_TREE_ITEM_EXPANDING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
 #define EVT_TREE_ITEM_COLLAPSED(id, fn) { wxEVT_COMMAND_TREE_ITEM_COLLAPSED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
index 144f3dc781181530ca4783c194055794d9120e77..9f9526ac33a9fc3d4fe86c21a14423d9db9dd816 100644 (file)
@@ -351,6 +351,19 @@ OS2OBJS = \
   ..\os2\$D\spinctrl.obj \
   ..\os2\$D\statbmp.obj \
   ..\os2\$D\statbox.obj \
+  ..\os2\$D\stattext.obj \
+  ..\os2\$D\statbrpm.obj \
+  ..\os2\$D\tabctrl.obj \
+  ..\os2\$D\taskbar.obj \
+  ..\os2\$D\textctrl.obj \
+  ..\os2\$D\thread.obj \
+  ..\os2\$D\timer.obj \
+  ..\os2\$D\toolbar.obj \
+  ..\os2\$D\tooltip.obj \
+  ..\os2\$D\treectrl.obj \
+  ..\os2\$D\utils.obj \
+  ..\os2\$D\utilsexc.obj \
+  ..\os2\$D\wave.obj \
   ..\os2\$D\window.obj
 
 OS2LIBOBJS1 = \
@@ -417,6 +430,19 @@ OS2LIBOBJS2 = \
   spinctrl.obj \
   statbmp.obj \
   statbox.obj \
+  stattext.obj \
+  statbrpm.obj \
+  tabctrl.obj \
+  taskbar.obj \
+  textctrl.obj \
+  thread.obj \
+  timer.obj \
+  toolbar.obj \
+  tooltip.obj \
+  treectrl.obj \
+  utils.obj \
+  utilsexc.obj \
+  wave.obj \
   window.obj
 
 HTMLOBJS = \
@@ -627,6 +653,19 @@ $(OS2LIBOBJS2):
   copy ..\os2\$D\spinctrl.obj
   copy ..\os2\$D\statbmp.obj
   copy ..\os2\$D\statbox.obj
+  copy ..\os2\$D\stattext.obj
+  copy ..\os2\$D\statbrpm.obj
+  copy ..\os2\$D\tabctrl.obj
+  copy ..\os2\$D\taskbar.obj
+  copy ..\os2\$D\textctrl.obj
+  copy ..\os2\$D\thread.obj
+  copy ..\os2\$D\timer.obj
+  copy ..\os2\$D\toolbar.obj
+  copy ..\os2\$D\tooltip.obj
+  copy ..\os2\$D\treectrl.obj
+  copy ..\os2\$D\utils.obj
+  copy ..\os2\$D\utilsexc.obj
+  copy ..\os2\$D\wave.obj
   copy ..\os2\$D\window.obj
 
 # wxWindows library as DLL
diff --git a/src/os2/statbrpm.cpp b/src/os2/statbrpm.cpp
new file mode 100644 (file)
index 0000000..8f6b10a
--- /dev/null
@@ -0,0 +1,171 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        statbar.cpp
+// Purpose:     native implementation of wxStatusBar (optional)
+// Author:      David Webster
+// Modified by:
+// Created:     10/17/99
+// RCS-ID:      $Id$
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+  #include "wx/setup.h"
+  #include "wx/frame.h"
+  #include "wx/settings.h"
+  #include "wx/dcclient.h"
+#endif
+
+#include "wx/log.h"
+#include "wx/generic/statusbr.h"
+#include "wx/os2/statusbr.h"
+
+#include "wx/os2/private.h"
+
+#if     !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxStatusBarPM, wxStatusBar);
+
+BEGIN_EVENT_TABLE(wxStatusBarPM, wxStatusBar)
+    EVT_SIZE(wxStatusBarPM::OnSize)
+END_EVENT_TABLE()
+#endif  //USE_SHARED_LIBRARY
+
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxStatusBarPM class
+// ----------------------------------------------------------------------------
+
+wxStatusBarPM::wxStatusBarPM()
+{
+    SetParent(NULL);
+    m_hWnd = 0;
+    m_windowId = 0;
+}
+
+wxStatusBarPM::wxStatusBarPM(wxWindow *parent, wxWindowID id, long style)
+{
+    Create(parent, id, style);
+}
+
+bool wxStatusBarPM::Create(wxWindow *parent, wxWindowID id, long style)
+{
+    SetParent(parent);
+
+    if (id == -1)
+        m_windowId = NewControlId();
+    else
+        m_windowId = id;
+
+    // TODO: create status bar
+    return FALSE;
+}
+
+void wxStatusBarPM::CopyFieldsWidth(const int widths[])
+{
+  if (widths && !m_statusWidths)
+    m_statusWidths = new int[m_nFields];
+
+  if ( widths != NULL ) {
+    for ( int i = 0; i < m_nFields; i++ )
+      m_statusWidths[i] = widths[i];
+  }
+  else {
+    delete [] m_statusWidths;
+    m_statusWidths = NULL;
+  }
+}
+
+void wxStatusBarPM::SetFieldsCount(int nFields, const int widths[])
+{
+  wxASSERT( (nFields > 0) && (nFields < 255) );
+
+  m_nFields = nFields;
+
+  CopyFieldsWidth(widths);
+  SetFieldsWidth();
+}
+
+void wxStatusBarPM::SetStatusWidths(int n, const int widths[])
+{
+  wxASSERT( n == m_nFields );
+
+  CopyFieldsWidth(widths);
+  SetFieldsWidth();
+}
+
+void wxStatusBarPM::SetFieldsWidth()
+{
+  int *pWidths = new int[m_nFields];
+
+  int nWindowWidth, y;
+  GetClientSize(&nWindowWidth, &y);
+
+  if ( m_statusWidths == NULL ) {
+    // default: all fields have the same width
+    int nWidth = nWindowWidth / m_nFields;
+    for ( int i = 0; i < m_nFields; i++ )
+      pWidths[i] = (i + 1) * nWidth;
+  }
+  else {
+    // -1 doesn't mean the same thing for wxWindows and Win32, recalc
+    int nTotalWidth = 0,
+        nVarCount = 0,
+        i;
+    for ( i = 0; i < m_nFields; i++ ) {
+      if ( m_statusWidths[i] == -1 )
+        nVarCount++;
+      else
+        nTotalWidth += m_statusWidths[i];
+    }
+
+    if ( nVarCount == 0 ) {
+      // wrong! at least one field must be of variable width
+      wxFAIL;
+
+      nVarCount++;
+    }
+
+    int nVarWidth = (nWindowWidth - nTotalWidth) / nVarCount;
+
+    // do fill the array
+    int nCurPos = 0;
+    for ( i = 0; i < m_nFields; i++ ) {
+      if ( m_statusWidths[i] == -1 )
+        nCurPos += nVarWidth;
+      else
+        nCurPos += m_statusWidths[i];
+      pWidths[i] = nCurPos;
+    }
+  }
+
+  // TODO: set widths
+
+  delete [] pWidths;
+}
+
+void wxStatusBarPM::SetStatusText(const wxString& strText, int nField)
+{
+    // TODO
+}
+
+wxString wxStatusBarPM::GetStatusText(int nField) const
+{
+    wxASSERT( (nField > -1) && (nField < m_nFields) );
+
+    // TODO
+    return wxString("");
+}
+
+void wxStatusBarPM::OnSize(wxSizeEvent& event)
+{
+    // adjust fields widths to the new size
+    SetFieldsWidth();
+}
+
index 3b19c7184dbe9748fbb2adba56d8cd2f840134dc..91b15ada8fb3ded7fe3846394a205497ca59b142 100644 (file)
@@ -1,21 +1,25 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        stattext.cpp
 // Purpose:     wxStaticText
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     04/01/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "stattext.h"
-#endif
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
 
+#ifndef WX_PRECOMP
+#include "wx/event.h"
 #include "wx/app.h"
-#include "wx/stattext.h"
+#include "wx/brush.h"
+#endif
 
+#include "wx/stattext.h"
+#include "wx/os2/private.h"
 #include <stdio.h>
 
 #if !USE_SHARED_LIBRARY
@@ -29,32 +33,105 @@ bool wxStaticText::Create(wxWindow *parent, wxWindowID id,
            long style,
            const wxString& name)
 {
-  SetName(name);
-  if (parent) parent->AddChild(this);
+    SetName(name);
+    if (parent) parent->AddChild(this);
+
+    SetBackgroundColour(parent->GetBackgroundColour()) ;
+    SetForegroundColour(parent->GetForegroundColour()) ;
 
-  SetBackgroundColour(parent->GetBackgroundColour()) ;
-  SetForegroundColour(parent->GetForegroundColour()) ;
+    if ( id == -1 )
+        m_windowId = (int)NewControlId();
+    else
+        m_windowId = id;
 
-  if ( id == -1 )
-       m_windowId = (int)NewControlId();
-  else
-       m_windowId = id;
+    int x = pos.x;
+    int y = pos.y;
+    int width = size.x;
+    int height = size.y;
 
-  m_windowStyle = style;
+    m_windowStyle = style;
 
-  SetFont(parent->GetFont());
+    // TODO
+    SubclassWin(m_hWnd);
 
-  // TODO
-  return FALSE;
+    SetFont(parent->GetFont());
+    SetSize(x, y, width, height);
+
+    return FALSE;
 }
 
-void wxStaticText::SetSize(int x, int y, int width, int height, int sizeFlags)
+wxSize wxStaticText::DoGetBestSize()
 {
-    // TODO
+    wxString text(wxGetWindowText(GetHWND()));
+
+    int widthTextMax = 0, widthLine,
+        heightTextTotal = 0, heightLine;
+
+    wxString curLine;
+    for ( const wxChar *pc = text; ; pc++ ) {
+        if ( *pc == wxT('\n') || *pc == wxT('\0') ) {
+            GetTextExtent(curLine, &widthLine, &heightLine);
+            if ( widthLine > widthTextMax )
+                widthTextMax = widthLine;
+            heightTextTotal += heightLine;
+
+            if ( *pc == wxT('\n') ) {
+               curLine.Empty();
+            }
+            else {
+               // the end of string
+               break;
+            }
+        }
+        else {
+            curLine += *pc;
+        }
+    }
+
+    return wxSize(widthTextMax, heightTextTotal);
 }
 
 void wxStaticText::SetLabel(const wxString& label)
 {
     // TODO
+
+    // adjust the size of the window to fit to the label (this behaviour is
+    // backward compatible and generally makes sense but we might want to still
+    // provide the user a way to disable it) (VZ)
+    DoSetSize(-1, -1, -1, -1, wxSIZE_AUTO_WIDTH | wxSIZE_AUTO_HEIGHT);
+}
+
+WXHBRUSH wxStaticText::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
+      WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+{
+    // TODO:
+/*
+    if (GetParent()->GetTransparentBackground())
+        SetBkMode((HDC) pDC, TRANSPARENT);
+    else
+        SetBkMode((HDC) pDC, OPAQUE);
+
+    ::SetBkColor((HDC) pDC, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
+    ::SetTextColor((HDC) pDC, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue()));
+
+    wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
+    // Note that this will be cleaned up in wxApp::OnIdle, if backgroundBrush
+    // has a zero usage count.
+//  backgroundBrush->RealizeResource();
+    return (WXHBRUSH) backgroundBrush->GetResourceHandle();
+*/
+    return (WXHBRUSH)0;
+}
+
+MRESULT wxStaticText::OS2WindowProc(HWND hwnd, WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+  // Ensure that static items get messages. Some controls don't like this
+  // message to be intercepted (e.g. RichEdit), hence the tests.
+// TODO:
+/*
+  if (nMsg == WM_NCHITTEST)
+    return (long)HTCLIENT;
+*/
+  return wxWindow::OS2WindowProc(hwnd, nMsg, wParam, lParam);
 }
 
index dff1ddec349d403d75c6596fff23fa53337937d7..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,162 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Name:        statbar.cpp
-// Purpose:     native implementation of wxStatusBar (optional)
-// Author:      AUTHOR
-// Modified by: 
-// Created:     ??/??/98
-// RCS-ID:      $Id$
-// Copyright:   (c) 1998 AUTHOR
-// Licence:     wxWindows licence
-///////////////////////////////////////////////////////////////////////////////
-
-#ifdef __GNUG__
-#pragma implementation "statusbr.h"
-#endif
-
-// ----------------------------------------------------------------------------
-// headers
-// ----------------------------------------------------------------------------
-
-#include "wx/stubs/statusbr.h"
-
-#if     !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxStatusBarXX, wxStatusBar);
-
-BEGIN_EVENT_TABLE(wxStatusBarXX, wxStatusBar)
-    EVT_SIZE(wxStatusBarXX::OnSize)
-END_EVENT_TABLE()
-#endif  //USE_SHARED_LIBRARY
-
-
-// ============================================================================
-// implementation
-// ============================================================================
-
-// ----------------------------------------------------------------------------
-// wxStatusBarXX class
-// ----------------------------------------------------------------------------
-
-wxStatusBarXX::wxStatusBarXX()
-{
-    SetParent(NULL);
-}
-
-wxStatusBarXX::wxStatusBarXX(wxWindow *parent, wxWindowID id, long style)
-{
-    Create(parent, id, style);
-}
-
-bool wxStatusBarXX::Create(wxWindow *parent, wxWindowID id, long style)
-{
-    SetParent(parent);
-
-    if (id == -1)
-        m_windowId = NewControlId();
-    else
-        m_windowId = id;
-
-    // TODO: create status bar
-    return FALSE;
-}
-
-void wxStatusBarXX::SetFieldsCount(int nFields, const int widths[])
-{
-  wxASSERT( (nFields > 0) && (nFields < 255) );
-
-  m_nFields = nFields;
-
-  CopyFieldsWidth(widths);
-  SetFieldsWidth();
-}
-
-void wxStatusBarXX::SetStatusWidths(int n, const int widths[])
-{
-  wxASSERT( n == m_nFields );
-
-  CopyFieldsWidth(widths);
-  SetFieldsWidth();
-}
-
-void wxStatusBarXX::CopyFieldsWidth(const int widths[])
-{
-  if (widths && !m_statusWidths)
-    m_statusWidths = new int[m_nFields];
-
-  if ( widths != NULL ) {
-    for ( int i = 0; i < m_nFields; i++ )
-      m_statusWidths[i] = widths[i];
-  }
-  else {
-    delete [] m_statusWidths;
-    m_statusWidths = NULL;
-  }
-}
-
-void wxStatusBarXX::SetFieldsWidth()
-{
-  int *pWidths = new int[m_nFields];
-
-  int nWindowWidth, y;
-  GetClientSize(&nWindowWidth, &y);
-
-  if ( m_statusWidths == NULL ) {
-    // default: all fields have the same width
-    int nWidth = nWindowWidth / m_nFields;
-    for ( int i = 0; i < m_nFields; i++ )
-      pWidths[i] = (i + 1) * nWidth;
-  }
-  else {
-    // -1 doesn't mean the same thing for wxWindows and Win32, recalc
-    int nTotalWidth = 0, 
-        nVarCount = 0, 
-        i;
-    for ( i = 0; i < m_nFields; i++ ) {
-      if ( m_statusWidths[i] == -1 )
-        nVarCount++;
-      else
-        nTotalWidth += m_statusWidths[i];
-    }
-
-    if ( nVarCount == 0 ) {
-      // wrong! at least one field must be of variable width
-      wxFAIL;
-
-      nVarCount++;
-    }
-
-    int nVarWidth = (nWindowWidth - nTotalWidth) / nVarCount;
-
-    // do fill the array
-    int nCurPos = 0;
-    for ( i = 0; i < m_nFields; i++ ) {
-      if ( m_statusWidths[i] == -1 )
-        nCurPos += nVarWidth;
-      else
-        nCurPos += m_statusWidths[i];
-      pWidths[i] = nCurPos;
-    }
-  }
-
-  // TODO: set widths
-
-  delete [] pWidths;
-}
-
-void wxStatusBarXX::SetStatusText(const wxString& strText, int nField)
-{
-    // TODO
-}
-
-wxString wxStatusBarXX::GetStatusText(int nField) const
-{
-    wxASSERT( (nField > -1) && (nField < m_nFields) );
-
-    // TODO
-    return wxString("");
-}
-
-void wxStatusBarXX::OnSize(wxSizeEvent& event)
-{
-    // adjust fields widths to the new size
-    SetFieldsWidth();
-}
index b3b45a72d12a038b60322fd7c374ac7ca3108551..677ee8a69cf58a808af38496ef1914e24ea5af64 100644 (file)
@@ -1,20 +1,31 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        tabctrl.cpp
 // Purpose:     wxTabCtrl
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "tabctrl.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
 #endif
 
-#include "wx/control.h"
-#include "wx/tabctrl.h"
+#include "malloc.h"
+
+#define INCL_PM
+#include <os2.h>
+
+//#include "wx/msw/dib.h"
+#include "wx/os2/tabctrl.h"
+#include "wx/app.h"
+#include "wx/os2/private.h"
+#include "wx/os2/imaglist.h"
 
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_DYNAMIC_CLASS(wxTabCtrl, wxControl)
@@ -33,28 +44,106 @@ bool wxTabCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, cons
 {
     m_imageList = NULL;
 
+    m_backgroundColour = *wxWHITE; // TODO: wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
+//        GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
+    m_foregroundColour = *wxBLACK ;
+
     SetName(name);
 
+    int x = pos.x;
+    int y = pos.y;
+    int width = size.x;
+    int height = size.y;
+
     m_windowStyle = style;
 
+    SetFont(* (wxTheFontList->FindOrCreateFont(11, wxSWISS, wxNORMAL, wxNORMAL)));
+
     SetParent(parent);
 
+    DWORD msflags = 0;
+
+    if (width <= 0)
+        width = 100;
+    if (height <= 0)
+        height = 30;
+    if (x < 0)
+        x = 0;
+    if (y < 0)
+        y = 0;
+
     m_windowId = (id < 0 ? NewControlId() : id);
 
-    if (parent) parent->AddChild(this);
+    long tabStyle = 0;
 
+    // Create the toolbar control.
+    HWND hWndTabCtrl = 0;
     // TODO: create tab control
+
+    m_hWnd = (WXHWND) hWndTabCtrl;
+    if (parent) parent->AddChild(this);
+
+    SubclassWin((WXHWND) hWndTabCtrl);
+
     return FALSE;
 }
 
 wxTabCtrl::~wxTabCtrl()
 {
+    UnsubclassWin();
 }
 
-void wxTabCtrl::Command(wxCommandEvent& event)
+bool wxTabCtrl::OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
+    wxTabEvent event(wxEVT_NULL, m_windowId);
+    wxEventType eventType = wxEVT_NULL;
+// TODO:
+/*
+    NMHDR* hdr1 = (NMHDR*) lParam;
+    switch ( hdr1->code )
+    {
+        case TCN_SELCHANGE:
+            eventType = wxEVT_COMMAND_TAB_SEL_CHANGED;
+            break;
+
+        case TCN_SELCHANGING:
+            eventType = wxEVT_COMMAND_TAB_SEL_CHANGING;
+            break;
+
+        case TTN_NEEDTEXT:
+        {
+            // TODO
+//            if (tool->m_shortHelpString != "")
+//                ttText->lpszText = (char *) (const char *)tool->m_shortHelpString;
+        }
+
+        default :
+            return wxControl::OS2OnNotify(idCtrl, lParam, result);
+    }
+*/
+    event.SetEventObject( this );
+    event.SetEventType(eventType);
+    event.SetInt(idCtrl) ;
+
+    return ProcessEvent(event);
 }
 
+// Responds to colour changes, and passes event on to children.
+void wxTabCtrl::OnSysColourChanged(wxSysColourChangedEvent& event)
+{
+    // TODO:
+/*
+    m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
+                                  GetGValue(GetSysColor(COLOR_BTNFACE)),
+                                  GetBValue(GetSysColor(COLOR_BTNFACE)));
+
+    Refresh();
+*/
+    // Propagate the event to the non-top-level children
+    wxWindow::OnSysColourChanged(event);
+}
+
+
 // Delete all items
 bool wxTabCtrl::DeleteAllItems()
 {
@@ -191,6 +280,73 @@ void wxTabCtrl::SetPadding(const wxSize& padding)
     // TODO
 }
 
+#if 0
+// These are the default colors used to map the bitmap colors
+// to the current system colors
+
+#define BGR_BUTTONTEXT      (RGB(000,000,000))  // black
+#define BGR_BUTTONSHADOW    (RGB(128,128,128))  // dark grey
+#define BGR_BUTTONFACE      (RGB(192,192,192))  // bright grey
+#define BGR_BUTTONHILIGHT   (RGB(255,255,255))  // white
+#define BGR_BACKGROUNDSEL   (RGB(255,000,000))  // blue
+#define BGR_BACKGROUND      (RGB(255,000,255))  // magenta
+
+void wxMapBitmap(HBITMAP hBitmap, int width, int height)
+{
+  COLORMAP ColorMap[] = {
+    {BGR_BUTTONTEXT,    COLOR_BTNTEXT},     // black
+    {BGR_BUTTONSHADOW,  COLOR_BTNSHADOW},   // dark grey
+    {BGR_BUTTONFACE,    COLOR_BTNFACE},     // bright grey
+    {BGR_BUTTONHILIGHT, COLOR_BTNHIGHLIGHT},// white
+    {BGR_BACKGROUNDSEL, COLOR_HIGHLIGHT},   // blue
+    {BGR_BACKGROUND,    COLOR_WINDOW}       // magenta
+  };
+
+  int NUM_MAPS = (sizeof(ColorMap)/sizeof(COLORMAP));
+  int n;
+  for ( n = 0; n < NUM_MAPS; n++)
+  {
+    ColorMap[n].to = ::GetSysColor(ColorMap[n].to);
+  }
+
+  HBITMAP hbmOld;
+  HDC hdcMem = CreateCompatibleDC(NULL);
+
+  if (hdcMem)
+  {
+    hbmOld = SelectObject(hdcMem, hBitmap);
+
+    int i, j, k;
+    for ( i = 0; i < width; i++)
+    {
+        for ( j = 0; j < height; j++)
+        {
+            COLORREF pixel = ::GetPixel(hdcMem, i, j);
+/*
+            BYTE red = GetRValue(pixel);
+            BYTE green = GetGValue(pixel);
+            BYTE blue = GetBValue(pixel);
+*/
+
+            for ( k = 0; k < NUM_MAPS; k ++)
+            {
+                if ( ColorMap[k].from == pixel )
+                {
+                    /* COLORREF actualPixel = */ ::SetPixel(hdcMem, i, j, ColorMap[k].to);
+                    break;
+                }
+            }
+        }
+    }
+
+
+    SelectObject(hdcMem, hbmOld);
+    DeleteObject(hdcMem);
+  }
+
+}
+#endif
+
 // Tab event
 IMPLEMENT_DYNAMIC_CLASS(wxTabEvent, wxCommandEvent)
 
@@ -199,3 +355,4 @@ wxTabEvent::wxTabEvent(wxEventType commandType, int id):
 {
 }
 
+
index 5c91250cf0bbbbb33ebe134e90a07be55ef0c0f0..723ec93a3d6701de0bbad2a33fe19fab2bd13ce2 100644 (file)
 // File:        taskbar.cpp
 // Purpose:        Implements wxTaskBarIcon class for manipulating icons on
 //              the task bar. Optional.
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c)
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "taskbar.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#include "wx/window.h"
+#include "wx/frame.h"
+#include "wx/utils.h"
+#include "wx/menu.h"
+#endif
+
+#define INCL_PM
+#include <os2.h>
+#include <string.h>
+#include <wx/os2/taskbar.h>
+#include <wx/os2/private.h>
+
+MRESULT wxTaskBarIconWindowProc( HWND hWnd, UINT msg, MPARAM wParam, MPARAM lParam );
+
+wxChar *wxTaskBarWindowClass = wxT("wxTaskBarWindowClass");
+
+wxList wxTaskBarIcon::sm_taskBarIcons;
+bool   wxTaskBarIcon::sm_registeredClass = FALSE;
+UINT   wxTaskBarIcon::sm_taskbarMsg = 0;
+
+
+#if !USE_SHARED_LIBRARY
+BEGIN_EVENT_TABLE(wxTaskBarIcon, wxEvtHandler)
+    EVT_TASKBAR_MOVE         (wxTaskBarIcon::_OnMouseMove)
+    EVT_TASKBAR_LEFT_DOWN    (wxTaskBarIcon::_OnLButtonDown)
+    EVT_TASKBAR_LEFT_UP      (wxTaskBarIcon::_OnLButtonUp)
+    EVT_TASKBAR_RIGHT_DOWN   (wxTaskBarIcon::_OnRButtonDown)
+    EVT_TASKBAR_RIGHT_UP     (wxTaskBarIcon::_OnRButtonUp)
+    EVT_TASKBAR_LEFT_DCLICK  (wxTaskBarIcon::_OnLButtonDClick)
+    EVT_TASKBAR_RIGHT_DCLICK (wxTaskBarIcon::_OnRButtonDClick)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
 #endif
 
-#include <wx/taskbar.h>
 
-wxTaskBarIcon::wxTaskBarIcon()
+wxTaskBarIcon::wxTaskBarIcon(void)
 {
-    // TODO
+    m_hWnd = 0;
+    m_iconAdded = FALSE;
+
+    AddObject(this);
+// TODO:
+/*
+    if (RegisterWindowClass())
+        m_hWnd = CreateTaskBarWindow();
+*/
 }
 
-wxTaskBarIcon::~wxTaskBarIcon()
+wxTaskBarIcon::~wxTaskBarIcon(void)
 {
-    // TODO
+// TODO:
+/*
+    RemoveObject(this);
+
+    if (m_iconAdded)
+    {
+        RemoveIcon();
+    }
+
+    if (m_hWnd)
+    {
+        ::DestroyWindow((HWND) m_hWnd);
+        m_hWnd = 0;
+    }
+*/
 }
 
 // Operations
 bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
 {
-    // TODO
+    if (!IsOK())
+        return FALSE;
+// TODO:
+/*
+    NOTIFYICONDATA notifyData;
+
+    memset(&notifyData, 0, sizeof(notifyData));
+    notifyData.cbSize = sizeof(notifyData);
+    notifyData.hWnd = (HWND) m_hWnd;
+    notifyData.uCallbackMessage = sm_taskbarMsg;
+    notifyData.uFlags = NIF_MESSAGE ;
+    if (icon.Ok())
+    {
+        notifyData.uFlags |= NIF_ICON;
+        notifyData.hIcon = (HICON) icon.GetHICON();
+    }
+
+    if (((const wxChar*) tooltip != NULL) && (tooltip != wxT("")))
+    {
+        notifyData.uFlags |= NIF_TIP ;
+        lstrcpyn(notifyData.szTip, WXSTRINGCAST tooltip, sizeof(notifyData.szTip));
+    }
+
+    notifyData.uID = 99;
+
+    if (m_iconAdded)
+        return (Shell_NotifyIcon(NIM_MODIFY, & notifyData) != 0);
+    else
+    {
+        m_iconAdded = (Shell_NotifyIcon(NIM_ADD, & notifyData) != 0);
+        return m_iconAdded;
+    }
+*/
     return FALSE;
 }
 
-bool wxTaskBarIcon::RemoveIcon()
+bool wxTaskBarIcon::RemoveIcon(void)
 {
-    // TODO
+    if (!m_iconAdded)
+        return FALSE;
+//TODO:
+/*
+    NOTIFYICONDATA notifyData;
+
+    memset(&notifyData, 0, sizeof(notifyData));
+    notifyData.cbSize = sizeof(notifyData);
+    notifyData.hWnd = (HWND) m_hWnd;
+    notifyData.uCallbackMessage = sm_taskbarMsg;
+    notifyData.uFlags = NIF_MESSAGE;
+    notifyData.hIcon = 0 ; // hIcon;
+    notifyData.uID = 99;
+    m_iconAdded = FALSE;
+
+    return (Shell_NotifyIcon(NIM_DELETE, & notifyData) != 0);
+*/
     return FALSE;
 }
 
+bool wxTaskBarIcon::PopupMenu(wxMenu *menu) //, int x, int y);
+{
+    // OK, so I know this isn't thread-friendly, but
+    // what to do? We need this check.
+
+    static bool s_inPopup = FALSE;
+
+    if (s_inPopup)
+        return FALSE;
+
+    s_inPopup = TRUE;
+
+    bool        rval = FALSE;
+    wxWindow*   win;
+    int         x, y;
+    wxGetMousePosition(&x, &y);
+
+    // is wxFrame the best window type to use???
+    win = new wxFrame(NULL, -1, "", wxPoint(x,y), wxSize(-1,-1), 0);
+    win->PushEventHandler(this);
+
+    // Remove from record of top-level windows, or will confuse wxWindows
+    // if we try to exit right now.
+    wxTopLevelWindows.DeleteObject(win);
+
+    menu->UpdateUI();
+
+    rval = win->PopupMenu(menu, 0, 0);
+
+    win->PopEventHandler(FALSE);
+    win->Destroy();
+    delete win;
+
+    s_inPopup = FALSE;
+
+    return rval;
+}
+
 // Overridables
-void wxTaskBarIcon::OnMouseMove()
+void wxTaskBarIcon::OnMouseMove(wxEvent&)
 {
 }
 
-void wxTaskBarIcon::OnLButtonDown()
+void wxTaskBarIcon::OnLButtonDown(wxEvent&)
 {
 }
 
-void wxTaskBarIcon::OnLButtonUp()
+void wxTaskBarIcon::OnLButtonUp(wxEvent&)
 {
 }
 
-void wxTaskBarIcon::OnRButtonDown()
+void wxTaskBarIcon::OnRButtonDown(wxEvent&)
 {
 }
 
-void wxTaskBarIcon::OnRButtonUp()
+void wxTaskBarIcon::OnRButtonUp(wxEvent&)
 {
 }
 
-void wxTaskBarIcon::OnLButtonDClick()
+void wxTaskBarIcon::OnLButtonDClick(wxEvent&)
 {
 }
 
-void wxTaskBarIcon::OnRButtonDClick()
+void wxTaskBarIcon::OnRButtonDClick(wxEvent&)
+{
+}
+
+void wxTaskBarIcon::_OnMouseMove(wxEvent& e)      { OnMouseMove(e);     }
+void wxTaskBarIcon::_OnLButtonDown(wxEvent& e)    { OnLButtonDown(e);   }
+void wxTaskBarIcon::_OnLButtonUp(wxEvent& e)      { OnLButtonUp(e);     }
+void wxTaskBarIcon::_OnRButtonDown(wxEvent& e)    { OnRButtonDown(e);   }
+void wxTaskBarIcon::_OnRButtonUp(wxEvent& e)      { OnRButtonUp(e);     }
+void wxTaskBarIcon::_OnLButtonDClick(wxEvent& e)  { OnLButtonDClick(e); }
+void wxTaskBarIcon::_OnRButtonDClick(wxEvent& e)  { OnRButtonDClick(e); }
+
+
+wxTaskBarIcon* wxTaskBarIcon::FindObjectForHWND(WXHWND hWnd)
+{
+    wxNode*node = sm_taskBarIcons.First();
+    while (node)
+    {
+        wxTaskBarIcon* obj = (wxTaskBarIcon*) node->Data();
+        if (obj->GetHWND() == hWnd)
+            return obj;
+        node = node->Next();
+    }
+    return NULL;
+}
+
+void wxTaskBarIcon::AddObject(wxTaskBarIcon* obj)
+{
+    sm_taskBarIcons.Append(obj);
+}
+
+void wxTaskBarIcon::RemoveObject(wxTaskBarIcon* obj)
+{
+    sm_taskBarIcons.DeleteObject(obj);
+}
+
+bool wxTaskBarIcon::RegisterWindowClass()
+{
+    if (sm_registeredClass)
+        return TRUE;
+
+    // Also register the taskbar message here
+// TODO:
+/*
+    sm_taskbarMsg = ::RegisterWindowMessage(wxT("wxTaskBarIconMessage"));
+
+    WNDCLASS  wc;
+    bool      rc;
+
+    HINSTANCE hInstance = GetModuleHandle(NULL);
+
+    //
+    // set up and register window class
+    //
+    wc.style = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc = (WNDPROC) wxTaskBarIconWindowProc;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hInstance = hInstance;
+    wc.hIcon = 0;
+    wc.hCursor = 0;
+    wc.hbrBackground = 0;
+    wc.lpszMenuName = NULL;
+    wc.lpszClassName = wxTaskBarWindowClass ;
+    rc = (::RegisterClass( &wc ) != 0);
+
+    sm_registeredClass = (rc != 0);
+
+    return( (rc != 0) );
+*/
+    return FALSE;
+}
+
+WXHWND wxTaskBarIcon::CreateTaskBarWindow()
+{
+// TODO:
+/*
+    HINSTANCE hInstance = GetModuleHandle(NULL);
+
+    HWND hWnd = CreateWindowEx (0, wxTaskBarWindowClass,
+            wxT("wxTaskBarWindow"),
+            WS_OVERLAPPED,
+            0,
+            0,
+            10,
+            10,
+            NULL,
+            (HMENU) 0,
+            hInstance,
+            NULL);
+
+    return (WXHWND) hWnd;
+*/
+    return (WXHWND)0;
+}
+
+MRESULT wxTaskBarIcon::WindowProc( WXHWND hWnd, UINT msg, MPARAM wParam, MPARAM lParam )
+{
+    wxEventType eventType = 0;
+// TODO:
+/*
+    if (msg != sm_taskbarMsg)
+        return DefWindowProc((HWND) hWnd, msg, wParam, lParam);
+
+    switch (lParam)
+    {
+        case WM_LBUTTONDOWN:
+            eventType = wxEVT_TASKBAR_LEFT_DOWN;
+            break;
+
+        case WM_LBUTTONUP:
+            eventType = wxEVT_TASKBAR_LEFT_UP;
+            break;
+
+        case WM_RBUTTONDOWN:
+            eventType = wxEVT_TASKBAR_RIGHT_DOWN;
+            break;
+
+        case WM_RBUTTONUP:
+            eventType = wxEVT_TASKBAR_RIGHT_UP;
+            break;
+
+        case WM_LBUTTONDBLCLK:
+            eventType = wxEVT_TASKBAR_LEFT_DCLICK;
+            break;
+
+        case WM_RBUTTONDBLCLK:
+            eventType = wxEVT_TASKBAR_RIGHT_DCLICK;
+            break;
+
+        case WM_MOUSEMOVE:
+            eventType = wxEVT_TASKBAR_MOVE;
+            break;
+
+        default:
+            break;
+    }
+*/
+    if (eventType)
+    {
+        wxEvent event;
+        event.SetEventType(eventType);
+        event.SetEventObject(this);
+
+        ProcessEvent(event);
+    }
+    return 0;
+}
+
+MRESULT wxTaskBarIconWindowProc(
+  HWND                              hWnd
+, UINT                              msg
+, MPARAM                            wParam
+, MPARAM                            lParam
+)
 {
+    wxTaskBarIcon* obj = wxTaskBarIcon::FindObjectForHWND((WXHWND) hWnd);
+    if (obj)
+        return obj->WindowProc((WXHWND) hWnd, msg, wParam, lParam);
+    else
+        return (MRESULT)0;
+//        return DefWindowProc(hWnd, msg, wParam, lParam);
 }
 
index 720e6082be0ddc57b38b5d63999634d7d0435d1c..82022466ef52497a47301cf2e9ad75ef14ca2965 100644 (file)
@@ -1,40 +1,60 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        textctrl.cpp
 // Purpose:     wxTextCtrl
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "textctrl.h"
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/textctrl.h"
+    #include "wx/settings.h"
+    #include "wx/brush.h"
+    #include "wx/utils.h"
+    #include "wx/log.h"
 #endif
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fstream.h>
+#if wxUSE_CLIPBOARD
+    #include "wx/app.h"
+    #include "wx/clipbrd.h"
+#endif
 
-#include "wx/textctrl.h"
-#include "wx/settings.h"
-#include "wx/filefn.h"
-#include "wx/utils.h"
+#include "wx/textfile.h"
+
+#include "wx/os2/private.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
 
-#if defined(__BORLANDC__) && !defined(__WIN32__)
-#include <alloc.h>
+#if wxUSE_IOSTREAMH
+#   include <fstream.h>
 #else
-#ifndef __GNUWIN32__
-#include <malloc.h>
-#endif
+#   include <fstream>
 #endif
 
 #if !USE_SHARED_LIBRARY
+
+// ----------------------------------------------------------------------------
+// event tables and other macros
+// ----------------------------------------------------------------------------
+
 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
 
 BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
-       EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
+    EVT_CHAR(wxTextCtrl::OnChar)
+    EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
+
     EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
     EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
     EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste)
@@ -47,299 +67,584 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
     EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo)
     EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo)
 END_EVENT_TABLE()
-#endif
 
-// Text item
+#endif // USE_SHARED_LIBRARY
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// creation
+// ----------------------------------------------------------------------------
+
 wxTextCtrl::wxTextCtrl()
-#ifndef NO_TEXT_WINDOW_STREAM
- :streambuf()
-#endif
 {
-    m_fileName = "";
 }
 
 bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
-                  const wxString& value,
-           const wxPoint& pos,
-           const wxSize& size, long style,
-           const wxValidator& validator,
-           const wxString& name)
-{
-    m_fileName = "";
-    SetName(name);
-    SetValidator(validator);
-    if (parent) parent->AddChild(this);
+                        const wxString& value,
+                        const wxPoint& pos,
+                        const wxSize& size,
+                        long style,
+                        const wxValidator& validator,
+                        const wxString& name)
+{
+    // base initialization
+    if ( !CreateBase(parent, id, pos, size, style, validator, name) )
+        return FALSE;
 
-    m_windowStyle = style;
+    // Validator was set in CreateBase
+    //SetValidator(validator);
+    if ( parent )
+        parent->AddChild(this);
 
-    if ( id == -1 )
-           m_windowId = (int)NewControlId();
+    // set colours
+    SetupColours();
+
+    // translate wxWin style flags to MSW ones, checking for consistency while
+    // doing it
+// TODO:
+/*
+    long msStyle = ES_LEFT | WS_VISIBLE | WS_CHILD | WS_TABSTOP;
+    if ( m_windowStyle & wxTE_MULTILINE )
+    {
+        wxASSERT_MSG( !(m_windowStyle & wxTE_PROCESS_ENTER),
+                      wxT("wxTE_PROCESS_ENTER style is ignored for multiline "
+                         "text controls (they always process it)") );
+
+        msStyle |= ES_MULTILINE | ES_WANTRETURN;
+        if ((m_windowStyle & wxTE_NO_VSCROLL) == 0)
+            msStyle |= WS_VSCROLL;
+        m_windowStyle |= wxTE_PROCESS_ENTER;
+    }
     else
-           m_windowId = id;
+        msStyle |= ES_AUTOHSCROLL;
+
+    if (m_windowStyle & wxHSCROLL)
+        msStyle |= (WS_HSCROLL | ES_AUTOHSCROLL);
+
+    if (m_windowStyle & wxTE_READONLY)
+        msStyle |= ES_READONLY;
+
+    if (m_windowStyle & wxHSCROLL)
+        msStyle |= (WS_HSCROLL | ES_AUTOHSCROLL);
+    if (m_windowStyle & wxTE_PASSWORD) // hidden input
+        msStyle |= ES_PASSWORD;
+
+    // we always want the characters and the arrows
+    m_lDlgCode = DLGC_WANTCHARS | DLGC_WANTARROWS;
+
+    // we may have several different cases:
+    // 1. normal case: both TAB and ENTER are used for dialog navigation
+    // 2. ctrl which wants TAB for itself: ENTER is used to pass to the next
+    //    control in the dialog
+    // 3. ctrl which wants ENTER for itself: TAB is used for dialog navigation
+    // 4. ctrl which wants both TAB and ENTER: Ctrl-ENTER is used to pass to
+    //    the next control
+    if ( m_windowStyle & wxTE_PROCESS_ENTER )
+        m_lDlgCode |= DLGC_WANTMESSAGE;
+    if ( m_windowStyle & wxTE_PROCESS_TAB )
+        m_lDlgCode |= DLGC_WANTTAB;
+
+    // do create the control - either an EDIT or RICHEDIT
+    const wxChar *windowClass = wxT("EDIT");
+
+    bool want3D;
+    WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D);
+
+    // Even with extended styles, need to combine with WS_BORDER for them to
+    // look right.
+    if ( want3D || wxStyleHasBorder(m_windowStyle) )
+        msStyle |= WS_BORDER;
+
+    // NB: don't use pos and size as CreateWindowEx arguments because they
+    //     might be -1 in which case we should use the default values (and
+    //     SetSize called below takes care of it)
+    m_hWnd = (WXHWND)::CreateWindowEx(exStyle,
+                                      windowClass,
+                                      NULL,
+                                      msStyle,
+                                      0, 0, 0, 0,
+                                      GetHwndOf(parent),
+                                      (HMENU)m_windowId,
+                                      wxGetInstance(),
+                                      NULL);
+
+    wxCHECK_MSG( m_hWnd, FALSE, wxT("Failed to create text ctrl") );
+*/
+    SubclassWin(GetHWND());
+
+    // set font, position, size and initial value
+    wxFont& fontParent = parent->GetFont();
+    if ( fontParent.Ok() )
+    {
+        SetFont(fontParent);
+    }
+    else
+    {
+        SetFont(wxSystemSettings::GetSystemFont(wxSYS_SYSTEM_FONT));
+    }
+
+    SetSize(pos.x, pos.y, size.x, size.y);
 
     return TRUE;
 }
 
+// Make sure the window style (etc.) reflects the HWND style (roughly)
+void wxTextCtrl::AdoptAttributesFromHWND()
+{
+  wxWindow::AdoptAttributesFromHWND();
+
+  HWND hWnd = GetHwnd();
+  // TODO:
+  /*
+  long style = GetWindowLong(hWnd, GWL_STYLE);
+
+  if (style & ES_MULTILINE)
+    m_windowStyle |= wxTE_MULTILINE;
+  if (style & ES_PASSWORD)
+    m_windowStyle |= wxTE_PASSWORD;
+  if (style & ES_READONLY)
+    m_windowStyle |= wxTE_READONLY;
+  if (style & ES_WANTRETURN)
+    m_windowStyle |= wxTE_PROCESS_ENTER;
+  */
+}
+
+void wxTextCtrl::SetupColours()
+{
+    // FIXME why is bg colour not inherited from parent?
+    SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
+    SetForegroundColour(GetParent()->GetForegroundColour());
+}
+
+// ----------------------------------------------------------------------------
+// set/get the controls text
+// ----------------------------------------------------------------------------
+
 wxString wxTextCtrl::GetValue() const
 {
-    // TODO
-    return wxString("");
+    return wxGetWindowText(GetHWND());
 }
 
 void wxTextCtrl::SetValue(const wxString& value)
 {
-    // TODO
+// TODO:
+/*
+    wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos);
+
+    SetWindowText(GetHwnd(), valueDos);
+
+    AdjustSpaceLimit();
+*/
 }
 
-void wxTextCtrl::SetSize(int x, int y, int width, int height, int sizeFlags)
+void wxTextCtrl::WriteText(const wxString& value)
 {
-    // TODO
+// TODO:
+/*
+    wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos);
+
+    SendMessage(GetHwnd(), EM_REPLACESEL, 0, (LPARAM)valueDos.c_str());
+
+    AdjustSpaceLimit();
+*/
 }
 
+void wxTextCtrl::AppendText(const wxString& text)
+{
+// TODO:
+/*
+    SetInsertionPointEnd();
+    WriteText(text);
+*/
+}
+
+void wxTextCtrl::Clear()
+{
+//    SetWindowText(GetHwnd(), wxT(""));
+}
+
+// ----------------------------------------------------------------------------
 // Clipboard operations
+// ----------------------------------------------------------------------------
+
 void wxTextCtrl::Copy()
 {
-    // TODO
+    if (CanCopy())
+    {
+        HWND hWnd = GetHwnd();
+//        SendMessage(hWnd, WM_COPY, 0, 0L);
+    }
 }
 
 void wxTextCtrl::Cut()
 {
-    // TODO
+    if (CanCut())
+    {
+        HWND hWnd = GetHwnd();
+//        SendMessage(hWnd, WM_CUT, 0, 0L);
+    }
 }
 
 void wxTextCtrl::Paste()
 {
-    // TODO
+    if (CanPaste())
+    {
+        HWND hWnd = GetHwnd();
+//        SendMessage(hWnd, WM_PASTE, 0, 0L);
+    }
+}
+
+bool wxTextCtrl::CanCopy() const
+{
+    // Can copy if there's a selection
+    long from, to;
+//    GetSelection(& from, & to);
+    return (from != to);
+}
+
+bool wxTextCtrl::CanCut() const
+{
+    // Can cut if there's a selection
+    long from, to;
+//    GetSelection(& from, & to);
+    return (from != to);
+}
+
+bool wxTextCtrl::CanPaste() const
+{
+    if (!IsEditable())
+        return FALSE;
+
+    // Standard edit control: check for straight text on clipboard
+    bool isTextAvailable = FALSE;
+//TODO:
+/*
+    if ( ::OpenClipboard(GetHwndOf(wxTheApp->GetTopWindow())) )
+    {
+        isTextAvailable = (::IsClipboardFormatAvailable(CF_TEXT) != 0);
+        ::CloseClipboard();
+    }
+*/
+    return isTextAvailable;
 }
 
+// ----------------------------------------------------------------------------
+// Accessors
+// ----------------------------------------------------------------------------
+
 void wxTextCtrl::SetEditable(bool editable)
 {
-    // TODO
+    HWND hWnd = GetHwnd();
+//    SendMessage(hWnd, EM_SETREADONLY, (WPARAM)!editable, (LPARAM)0L);
 }
 
 void wxTextCtrl::SetInsertionPoint(long pos)
 {
-    // TODO
+// TODO:
+/*
+    HWND hWnd = GetHwnd();
+    {
+        SendMessage(hWnd, EM_SETSEL, pos, pos);
+        SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);
+    }
+    static const char *nothing = "";
+    SendMessage(hWnd, EM_REPLACESEL, 0, (LPARAM)nothing);
+*/
 }
 
 void wxTextCtrl::SetInsertionPointEnd()
 {
+// TODO:
+/*
     long pos = GetLastPosition();
     SetInsertionPoint(pos);
+*/
 }
 
 long wxTextCtrl::GetInsertionPoint() const
 {
-    // TODO
+// TODO:
+/*
+    DWORD Pos = (DWORD)SendMessage(GetHwnd(), EM_GETSEL, 0, 0L);
+    return Pos & 0xFFFF;
+*/
     return 0;
 }
 
 long wxTextCtrl::GetLastPosition() const
 {
-    // TODO
-    return 0;
-}
+    HWND hWnd = GetHwnd();
 
-void wxTextCtrl::Replace(long from, long to, const wxString& value)
-{
-    // TODO
-}
+// TODO:
+/*
+    // Will always return a number > 0 (according to docs)
+    int noLines = (int)SendMessage(hWnd, EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0L);
 
-void wxTextCtrl::Remove(long from, long to)
-{
-    // TODO
-}
+    // This gets the char index for the _beginning_ of the last line
+    int charIndex = (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)(noLines-1), (LPARAM)0L);
 
-void wxTextCtrl::SetSelection(long from, long to)
-{
-    // TODO
+    // Get number of characters in the last line. We'll add this to the character
+    // index for the last line, 1st position.
+    int lineLength = (int)SendMessage(hWnd, EM_LINELENGTH, (WPARAM)charIndex, (LPARAM)0L);
+
+    return (long)(charIndex + lineLength);
+*/
+    return 0L;
 }
 
-bool wxTextCtrl::LoadFile(const wxString& file)
+// If the return values from and to are the same, there is no
+// selection.
+void wxTextCtrl::GetSelection(long* from, long* to) const
 {
-    if (!wxFileExists(file))
-        return FALSE;
+    DWORD dwStart, dwEnd;
+    MPARAM wParam = (MPARAM) (DWORD*) & dwStart; // receives starting position
+    MPARAM lParam = (MPARAM) (DWORD*) & dwEnd;   // receives ending position
 
-    m_fileName = file;
+//    ::SendMessage(GetHwnd(), EM_GETSEL, wParam, lParam);
 
-    Clear();
+    *from = dwStart;
+    *to = dwEnd;
+}
 
-    ifstream input((char*) (const char*) file, ios::nocreate | ios::in);
+bool wxTextCtrl::IsEditable() const
+{
+// TODO:
+/*
+    long style = ::GetWindowLong(GetHwnd(), GWL_STYLE);
 
-    if (!input.bad())
-    {
-        struct stat stat_buf;
-        if (stat(file, &stat_buf) < 0)
-            return FALSE;
-        // This may need to be a bigger buffer than the file size suggests,
-        // if it's a UNIX file. Give it an extra 1000 just in case.
-        char *tmp_buffer = (char*)malloc((size_t)(stat_buf.st_size+1+1000));
-        long no_lines = 0;
-        long pos = 0;
-        while (!input.eof() && input.peek() != EOF)
-        {
-            input.getline(wxBuffer, 500);
-               int len = strlen(wxBuffer);
-               wxBuffer[len] = 13;
-               wxBuffer[len+1] = 10;
-               wxBuffer[len+2] = 0;
-               strcpy(tmp_buffer+pos, wxBuffer);
-               pos += strlen(wxBuffer);
-               no_lines++;
-         }
-
-         // TODO add line
-
-         free(tmp_buffer);
-
-         return TRUE;
-    }
+    return ((style & ES_READONLY) == 0);
+*/
     return FALSE;
 }
 
-// If file is null, try saved file name first
-// Returns TRUE if succeeds.
-bool wxTextCtrl::SaveFile(const wxString& file)
+// ----------------------------------------------------------------------------
+// Editing
+// ----------------------------------------------------------------------------
+
+void wxTextCtrl::Replace(long from, long to, const wxString& value)
 {
-    wxString theFile(file);
-    if (theFile == "")
-        theFile = m_fileName;
-    if (theFile == "")
-        return FALSE;
-    m_fileName = theFile;
+#if wxUSE_CLIPBOARD
+    HWND hWnd = GetHwnd();
+    long fromChar = from;
+    long toChar = to;
 
-    ofstream output((char*) (const char*) theFile);
-    if (output.bad())
-           return FALSE;
+    // Set selection and remove it
+//    SendMessage(hWnd, EM_SETSEL, fromChar, toChar);
+//    SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0);
 
-    // TODO get and save text
+    // Now replace with 'value', by pasting.
+    wxSetClipboardData(wxDF_TEXT, (wxObject *) (const wxChar *)value, 0, 0);
 
-    return FALSE;
+    // Paste into edit control
+//    SendMessage(hWnd, WM_PASTE, (WPARAM)0, (LPARAM)0L);
+#else
+    wxFAIL_MSG("wxTextCtrl::Replace not implemented if wxUSE_CLIPBOARD is 0.");
+#endif
 }
 
-void wxTextCtrl::WriteText(const wxString& text)
+void wxTextCtrl::Remove(long from, long to)
 {
-    // TODO write text to control
+    HWND hWnd = GetHwnd();
+    long fromChar = from;
+    long toChar = to;
+
+    // Cut all selected text
+//    SendMessage(hWnd, EM_SETSEL, fromChar, toChar);
+//    SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0);
 }
 
-void wxTextCtrl::AppendText(const wxString& text)
+void wxTextCtrl::SetSelection(long from, long to)
 {
-    // TODO append text to control
+    HWND hWnd = GetHwnd();
+    long fromChar = from;
+    long toChar = to;
+
+    // if from and to are both -1, it means (in wxWindows) that all text should
+    // be selected. Translate into Windows convention
+    if ((from == -1) && (to == -1))
+    {
+      fromChar = 0;
+      toChar = -1;
+    }
+
+//    SendMessage(hWnd, EM_SETSEL, (WPARAM)fromChar, (LPARAM)toChar);
+//    SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);
 }
 
-void wxTextCtrl::Clear()
+bool wxTextCtrl::LoadFile(const wxString& file)
 {
-    // TODO
+// TODO:
+/*
+    if ( wxTextCtrlBase::LoadFile(file) )
+    {
+        // update the size limit if needed
+        AdjustSpaceLimit();
+
+        return TRUE;
+    }
+*/
+    return FALSE;
 }
 
 bool wxTextCtrl::IsModified() const
 {
-    // TODO
+//    return (SendMessage(GetHwnd(), EM_GETMODIFY, 0, 0) != 0);
     return FALSE;
 }
 
 // Makes 'unmodified'
 void wxTextCtrl::DiscardEdits()
 {
-    // TODO
+//    SendMessage(GetHwnd(), EM_SETMODIFY, FALSE, 0L);
 }
 
 int wxTextCtrl::GetNumberOfLines() const
 {
-    // TODO
+//    return (int)SendMessage(GetHwnd(), EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0);
     return 0;
 }
 
 long wxTextCtrl::XYToPosition(long x, long y) const
 {
-    // TODO
-    return 0;
+    HWND hWnd = GetHwnd();
+
+    // This gets the char index for the _beginning_ of this line
+// TODO:
+/*
+    int charIndex = (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)y, (LPARAM)0);
+    return (long)(x + charIndex);
+*/
+    return 0L;
 }
 
-void wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
+bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
 {
-    // TODO
+    HWND hWnd = GetHwnd();
+
+    // This gets the line number containing the character
+    int lineNo;
+//    lineNo = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)pos, 0);
+
+    if ( lineNo == -1 )
+    {
+        // no such line
+        return FALSE;
+    }
+
+    // This gets the char index for the _beginning_ of this line
+    int charIndex = 0; // TODO: (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)lineNo, (LPARAM)0);
+    if ( charIndex == -1 )
+    {
+        return FALSE;
+    }
+
+    // The X position must therefore be the different between pos and charIndex
+    if ( x )
+        *x = (long)(pos - charIndex);
+    if ( y )
+        *y = (long)lineNo;
+
+    return TRUE;
 }
 
 void wxTextCtrl::ShowPosition(long pos)
 {
-    // TODO
+    HWND hWnd = GetHwnd();
+
+    // To scroll to a position, we pass the number of lines and characters
+    // to scroll *by*. This means that we need to:
+    // (1) Find the line position of the current line.
+    // (2) Find the line position of pos.
+    // (3) Scroll by (pos - current).
+    // For now, ignore the horizontal scrolling.
+
+    // Is this where scrolling is relative to - the line containing the caret?
+    // Or is the first visible line??? Try first visible line.
+//    int currentLineLineNo1 = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)-1, (LPARAM)0L);
+
+// TODO:
+/*
+    int currentLineLineNo = (int)SendMessage(hWnd, EM_GETFIRSTVISIBLELINE, (WPARAM)0, (LPARAM)0L);
+
+    int specifiedLineLineNo = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)pos, (LPARAM)0L);
+
+    int linesToScroll = specifiedLineLineNo - currentLineLineNo;
+
+    if (linesToScroll != 0)
+      (void)SendMessage(hWnd, EM_LINESCROLL, (WPARAM)0, (LPARAM)linesToScroll);
+*/
 }
 
 int wxTextCtrl::GetLineLength(long lineNo) const
 {
-    // TODO
+// TODO:
+/*
+
+    long charIndex = XYToPosition(0, lineNo);
+    int len = (int)SendMessage(GetHwnd(), EM_LINELENGTH, charIndex, 0);
+    return len;
+*/
     return 0;
 }
 
 wxString wxTextCtrl::GetLineText(long lineNo) const
 {
-    // TODO
-    return wxString("");
-}
+    size_t len = (size_t)GetLineLength(lineNo) + 1;
+    char *buf = (char *)malloc(len);
+    *(WORD *)buf = len;
+    int noChars = 0; // TODO:(int)SendMessage(GetHwnd(), EM_GETLINE, lineNo, (LPARAM)buf);
+    buf[noChars] = 0;
 
-bool wxTextCtrl::CanCopy() const
-{
-    // Can copy if there's a selection
-    long from, to;
-    GetSelection(& from, & to);
-    return (from != to) ;
-}
+    wxString str(buf);
 
-bool wxTextCtrl::CanCut() const
-{
-    // Can cut if there's a selection
-    long from, to;
-    GetSelection(& from, & to);
-    return (from != to) ;
-}
+    free(buf);
 
-bool wxTextCtrl::CanPaste() const
-{
-    return IsEditable() ;
+    return str;
 }
 
+// ----------------------------------------------------------------------------
 // Undo/redo
+// ----------------------------------------------------------------------------
+
 void wxTextCtrl::Undo()
 {
-    // TODO
+    if (CanUndo())
+    {
+//        ::SendMessage(GetHwnd(), EM_UNDO, 0, 0);
+    }
 }
 
 void wxTextCtrl::Redo()
 {
-    // TODO
+    if (CanRedo())
+    {
+        // Same as Undo, since Undo undoes the undo, i.e. a redo.
+//        ::SendMessage(GetHwnd(), EM_UNDO, 0, 0);
+    }
 }
 
 bool wxTextCtrl::CanUndo() const
 {
-    // TODO
+//    return (::SendMessage(GetHwnd(), EM_CANUNDO, 0, 0) != 0);
     return FALSE;
 }
 
 bool wxTextCtrl::CanRedo() const
 {
-    // TODO
+//    return (::SendMessage(GetHwnd(), EM_CANUNDO, 0, 0) != 0);
     return FALSE;
 }
 
-// If the return values from and to are the same, there is no
-// selection.
-void wxTextCtrl::GetSelection(long* from, long* to) const
-{
-    // TODO
-    *from = 0;
-    *to = 0;
-}
-
-bool wxTextCtrl::IsEditable() const
-{
-    // TODO
-    return FALSE;
-}
+// ----------------------------------------------------------------------------
+// implemenation details
+// ----------------------------------------------------------------------------
 
 void wxTextCtrl::Command(wxCommandEvent & event)
 {
-    SetValue (event.GetString());
+    SetValue(event.GetString());
     ProcessCommand (event);
 }
 
@@ -352,161 +657,166 @@ void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
     }
 }
 
-// The streambuf code was partly taken from chapter 3 by Jerry Schwarz of
-// AT&T's "C++ Lanuage System Release 3.0 Library Manual" - Stein Somers
-
-//=========================================================================
-// Called then the buffer is full (gcc 2.6.3) 
-// or when "endl" is output (Borland 4.5)
-//=========================================================================
-// Class declaration using multiple inheritance doesn't work properly for
-// Borland. See note in wb_text.h.
-#ifndef NO_TEXT_WINDOW_STREAM
-int wxTextCtrl::overflow(int c)
-{
-  // Make sure there is a holding area
-  if ( allocate()==EOF )
-  {
-    wxError("Streambuf allocation failed","Internal error");
-    return EOF;
-  }
-  
-  // Verify that there are no characters in get area
-  if ( gptr() && gptr() < egptr() )
-  {
-     wxError("Who's trespassing my get area?","Internal error");
-     return EOF;
-  }
-
-  // Reset get area
-  setg(0,0,0);
-
-  // Make sure there is a put area
-  if ( ! pptr() )
-  {
-/* This doesn't seem to be fatal so comment out error message */
-//    wxError("Put area not opened","Internal error");
-    setp( base(), base() );
-  }
-
-  // Determine how many characters have been inserted but no consumed
-  int plen = pptr() - pbase();
-
-  // Now Jerry relies on the fact that the buffer is at least 2 chars
-  // long, but the holding area "may be as small as 1" ???
-  // And we need an additional \0, so let's keep this inefficient but
-  // safe copy.
-
-  // If c!=EOF, it is a character that must also be comsumed
-  int xtra = c==EOF? 0 : 1;
-
-  // Write temporary C-string to wxTextWindow
-  {
-  char *txt = new char[plen+xtra+1];
-  memcpy(txt, pbase(), plen);
-  txt[plen] = (char)c;     // append c
-  txt[plen+xtra] = '\0';   // append '\0' or overwrite c
-    // If the put area already contained \0, output will be truncated there
-  AppendText(txt);
-    delete[] txt;
-  }
-
-  // Reset put area
-  setp(pbase(), epptr());
-
-#if defined(__WATCOMC__)
-  return __NOT_EOF;
-#elif defined(zapeof)     // HP-UX (all cfront based?)
-  return zapeof(c);
-#else
-  return c!=EOF ? c : 0;  // this should make everybody happy
-#endif
-}
+WXHBRUSH wxTextCtrl::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
+                                WXUINT message, WXWPARAM wParam,
+                                WXLPARAM lParam)
+{
+    HDC hdc = (HDC)pDC;
+// TODO:
+/*
+    SetBkMode(hdc, GetParent()->GetTransparentBackground() ? TRANSPARENT
+                                                           : OPAQUE);
 
-//=========================================================================
-// called then "endl" is output (gcc) or then explicit sync is done (Borland)
-//=========================================================================
-int wxTextCtrl::sync()
-{
-  // Verify that there are no characters in get area
-  if ( gptr() && gptr() < egptr() )
-  {
-     wxError("Who's trespassing my get area?","Internal error");
-     return EOF;
-  }
-
-  if ( pptr() && pptr() > pbase() ) return overflow(EOF);
-
-  return 0;
-/* OLD CODE
-  int len = pptr() - pbase();
-  char *txt = new char[len+1];
-  strncpy(txt, pbase(), len);
-  txt[len] = '\0';
-  (*this) << txt;
-  setp(pbase(), epptr());
-  delete[] txt;
-  return 0;
+    ::SetBkColor(hdc, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
+    ::SetTextColor(hdc, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue()));
 */
-}
+    wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
 
-//=========================================================================
-// Should not be called by a "ostream". Used by a "istream"
-//=========================================================================
-int wxTextCtrl::underflow()
-{
-  return EOF;
+    return (WXHBRUSH) backgroundBrush->GetResourceHandle();
 }
-#endif
 
-wxTextCtrl& wxTextCtrl::operator<<(const wxString& s)
+void wxTextCtrl::OnChar(wxKeyEvent& event)
 {
-    AppendText(s);
-    return *this;
-}
+    switch ( event.KeyCode() )
+    {
+// TODO:
+/*
+        case WXK_RETURN:
+            if ( !(m_windowStyle & wxTE_MULTILINE) )
+            {
+                wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
+                event.SetEventObject( this );
+                if ( GetEventHandler()->ProcessEvent(event) )
+                    return;
+            }
+            //else: multiline controls need Enter for themselves
+
+            break;
+
+        case WXK_TAB:
+            // always produce navigation event - even if we process TAB
+            // ourselves the fact that we got here means that the user code
+            // decided to skip processing of this TAB - probably to let it
+            // do its default job.
+            //
+            // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
+            //     handled by Windows
+            {
+                wxNavigationKeyEvent eventNav;
+                eventNav.SetDirection(!event.ShiftDown());
+                eventNav.SetWindowChange(FALSE);
+                eventNav.SetEventObject(this);
+
+                if ( GetEventHandler()->ProcessEvent(eventNav) )
+                    return;
+            }
+            break;
+*/
+        default:
+            event.Skip();
+            return;
+    }
 
-wxTextCtrl& wxTextCtrl::operator<<(float f)
-{
-    wxString str;
-    str.Printf("%.2f", f);
-    AppendText(str);
-    return *this;
+    // don't just call event.Skip() because this will cause TABs and ENTERs
+    // be passed upwards and we don't always want this - instead process it
+    // right here
+
+    // FIXME
+    event.Skip();
 }
 
-wxTextCtrl& wxTextCtrl::operator<<(double d)
+bool wxTextCtrl::OS2Command(WXUINT param, WXWORD WXUNUSED(id))
 {
-    wxString str;
-    str.Printf("%.2f", d);
-    AppendText(str);
-    return *this;
+    switch (param)
+    {
+// TODO:
+/*
+        case EN_SETFOCUS:
+        case EN_KILLFOCUS:
+            {
+                wxFocusEvent event(param == EN_KILLFOCUS ? wxEVT_KILL_FOCUS
+                        : wxEVT_SET_FOCUS,
+                        m_windowId);
+                event.SetEventObject( this );
+                GetEventHandler()->ProcessEvent(event);
+            }
+            break;
+
+        case EN_CHANGE:
+            {
+                wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
+                wxString val(GetValue());
+                if ( !val.IsNull() )
+                    event.m_commandString = WXSTRINGCAST val;
+                event.SetEventObject( this );
+                ProcessCommand(event);
+            }
+            break;
+
+        case EN_ERRSPACE:
+            // the text size limit has been hit - increase it
+            AdjustSpaceLimit();
+            break;
+
+            // the other notification messages are not processed
+        case EN_UPDATE:
+        case EN_MAXTEXT:
+        case EN_HSCROLL:
+        case EN_VSCROLL:
+*/
+        default:
+            return FALSE;
+    }
+
+    // processed
+    return TRUE;
 }
 
-wxTextCtrl& wxTextCtrl::operator<<(int i)
+void wxTextCtrl::AdjustSpaceLimit()
 {
-    wxString str;
-    str.Printf("%d", i);
-    AppendText(str);
-    return *this;
+// TODO:
+/*
+    unsigned int len = ::GetWindowTextLength(GetHwnd()),
+    limit = ::SendMessage(GetHwnd(), EM_GETLIMITTEXT, 0, 0);
+    if ( len > limit )
+    {
+        limit = len + 0x8000;    // 32Kb
+
+        if ( limit > 0xffff )
+            ::SendMessage(GetHwnd(), EM_LIMITTEXT, 0, limit);
+        else
+            ::SendMessage(GetHwnd(), EM_LIMITTEXT, limit, 0);
+    }
+*/
 }
 
-wxTextCtrl& wxTextCtrl::operator<<(long i)
+bool wxTextCtrl::AcceptsFocus() const
 {
-    wxString str;
-    str.Printf("%ld", i);
-    AppendText(str);
-    return *this;
+    // we don't want focus if we can't be edited
+    return IsEditable() && wxControl::AcceptsFocus();
 }
 
-wxTextCtrl& wxTextCtrl::operator<<(const char c)
+wxSize wxTextCtrl::DoGetBestSize()
 {
-    char buf[2];
+    int cx, cy;
+    wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
 
-    buf[0] = c;
-    buf[1] = 0;
-    AppendText(buf);
-    return *this;
+    int wText = DEFAULT_ITEM_WIDTH;
+
+    int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
+    if ( m_windowStyle & wxTE_MULTILINE )
+    {
+        hText *= wxMin(GetNumberOfLines(), 5);
+    }
+    //else: for single line control everything is ok
+
+    return wxSize(wText, hText);
 }
 
+// ----------------------------------------------------------------------------
+// standard handlers for standard edit menu events
+// ----------------------------------------------------------------------------
+
 void wxTextCtrl::OnCut(wxCommandEvent& event)
 {
     Cut();
@@ -556,3 +866,4 @@ void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
 {
     event.Enable( CanRedo() );
 }
+
index 34ad1a4f14ad02ddcb343efea7d17dbca7ea45db..c636e6e9ae6197089ff703a383bf7c2223ab3898 100644 (file)
 // Name:        thread.cpp
 // Purpose:     wxThread Implementation. For Unix ports, see e.g. src/gtk
 // Author:      Original from Wolfram Gloger/Guilhem Lavaux
-// Modified by:
+// Modified by: David Webster
 // Created:     04/22/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Wolfram Gloger (1996, 1997); Guilhem Lavaux (1998)
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "thread.h"
-#endif
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
 
-#include "wx/module.h"
-#include "wx/thread.h"
-#include "wx/utils.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
 
 #if wxUSE_THREADS
 
-enum thread_state {
-  STATE_IDLE = 0,
-  STATE_RUNNING,
-  STATE_CANCELED,
-  STATE_EXITED
+#include <stdio.h>
+
+#define INCL_DOS
+#include <os2.h>
+
+#include "wx/module.h"
+#include "wx/thread.h"
+
+// the possible states of the thread ("=>" shows all possible transitions from
+// this state)
+enum wxThreadState
+{
+    STATE_NEW,          // didn't start execution yet (=> RUNNING)
+    STATE_RUNNING,      // thread is running (=> PAUSED, CANCELED)
+    STATE_PAUSED,       // thread is temporarily suspended (=> RUNNING)
+    STATE_CANCELED,     // thread should terminate a.s.a.p. (=> EXITED)
+    STATE_EXITED        // thread is terminating
 };
 
-/////////////////////////////////////////////////////////////////////////////
-// Static variables
-/////////////////////////////////////////////////////////////////////////////
+// ----------------------------------------------------------------------------
+// static variables
+// ----------------------------------------------------------------------------
 
-wxMutex *wxMainMutex; // controls access to all GUI functions
+// TLS index of the slot where we store the pointer to the current thread
+static DWORD s_tlsThisThread = 0xFFFFFFFF;
 
-/////////////////////////////////////////////////////////////////////////////
-// Windows implementation
-/////////////////////////////////////////////////////////////////////////////
+// id of the main thread - the one which can call GUI functions without first
+// calling wxMutexGuiEnter()
+static DWORD s_idMainThread = 0;
+
+// if it's FALSE, some secondary thread is holding the GUI lock
+static bool s_bGuiOwnedByMainThread = TRUE;
 
-class wxMutexInternal {
+// critical section which controls access to all GUI functions: any secondary
+// thread (i.e. except the main one) must enter this crit section before doing
+// any GUI calls
+static wxCriticalSection *s_critsectGui = NULL;
+
+// critical section which protects s_nWaitingForGui variable
+static wxCriticalSection *s_critsectWaitingForGui = NULL;
+
+// number of threads waiting for GUI in wxMutexGuiEnter()
+static size_t s_nWaitingForGui = 0;
+
+// are we waiting for a thread termination?
+static bool s_waitingForThread = FALSE;
+
+// ============================================================================
+// Windows implementation of thread classes
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxMutex implementation
+// ----------------------------------------------------------------------------
+class wxMutexInternal
+{
 public:
-  // TODO: internal mutex handle
+    HANDLE p_mutex;
 };
 
 wxMutex::wxMutex()
 {
     p_internal = new wxMutexInternal;
-    // TODO: create internal mutext handle
+//    p_internal->p_mutex = CreateMutex(NULL, FALSE, NULL);
+    if ( !p_internal->p_mutex )
+    {
+        wxLogSysError(_("Can not create mutex."));
+    }
+
     m_locked = 0;
 }
 
 wxMutex::~wxMutex()
 {
     if (m_locked > 0)
-        wxDebugMsg("wxMutex warning: freeing a locked mutex (%d locks)\n", m_locked);
-    // TODO: free internal mutext handle
+        wxLogDebug(wxT("Warning: freeing a locked mutex (%d locks)."), m_locked);
+//    CloseHandle(p_internal->p_mutex);
 }
 
 wxMutexError wxMutex::Lock()
 {
-    // TODO
+    DWORD ret;
+
+// TODO:
+/*
+    ret = WaitForSingleObject(p_internal->p_mutex, INFINITE);
+    switch ( ret )
+    {
+        case WAIT_ABANDONED:
+            return wxMUTEX_BUSY;
+
+        case WAIT_OBJECT_0:
+            // ok
+            break;
+
+        case WAIT_FAILED:
+            wxLogSysError(_("Couldn't acquire a mutex lock"));
+            return wxMUTEX_MISC_ERROR;
+
+        case WAIT_TIMEOUT:
+        default:
+            wxFAIL_MSG(wxT("impossible return value in wxMutex::Lock"));
+    }
+
     m_locked++;
+*/
     return wxMUTEX_NO_ERROR;
 }
 
 wxMutexError wxMutex::TryLock()
 {
-    // TODO
+    DWORD ret;
+
+// TODO:
+/*
+    ret = WaitForSingleObject(p_internal->p_mutex, 0);
+    if (ret == WAIT_TIMEOUT || ret == WAIT_ABANDONED)
+        return wxMUTEX_BUSY;
+
     m_locked++;
+*/
     return wxMUTEX_NO_ERROR;
 }
 
@@ -74,192 +147,750 @@ wxMutexError wxMutex::Unlock()
     if (m_locked > 0)
         m_locked--;
 
-    // TODO
+    BOOL ret = 0; // TODO: ReleaseMutex(p_internal->p_mutex);
+    if ( ret == 0 )
+    {
+        wxLogSysError(_("Couldn't release a mutex"));
+        return wxMUTEX_MISC_ERROR;
+    }
+
     return wxMUTEX_NO_ERROR;
 }
 
-class wxConditionInternal {
+// ----------------------------------------------------------------------------
+// wxCondition implementation
+// ----------------------------------------------------------------------------
+
+class wxConditionInternal
+{
 public:
-  // TODO: internal handle
-  int waiters;
+    HANDLE event;
+    int waiters;
 };
 
 wxCondition::wxCondition()
 {
     p_internal = new wxConditionInternal;
-    // TODO: create internal handle
+// TODO:
+/*
+    p_internal->event = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if ( !p_internal->event )
+    {
+        wxLogSysError(_("Can not create event object."));
+    }
+*/
     p_internal->waiters = 0;
 }
 
 wxCondition::~wxCondition()
 {
-    // TODO: destroy internal handle
+//    CloseHandle(p_internal->event);
 }
 
 void wxCondition::Wait(wxMutex& mutex)
 {
     mutex.Unlock();
     p_internal->waiters++;
-    // TODO wait here
+//    WaitForSingleObject(p_internal->event, INFINITE);
     p_internal->waiters--;
     mutex.Lock();
 }
 
-bool wxCondition::Wait(wxMutex& mutex, unsigned long sec,
+bool wxCondition::Wait(wxMutex& mutex,
+                       unsigned long sec,
                        unsigned long nsec)
 {
+    DWORD ret;
+
     mutex.Unlock();
     p_internal->waiters++;
-
-    // TODO wait here
+//    ret = WaitForSingleObject(p_internal->event, (sec*1000)+(nsec/1000000));
     p_internal->waiters--;
     mutex.Lock();
 
+//    return (ret != WAIT_TIMEOUT);
     return FALSE;
 }
 
 void wxCondition::Signal()
 {
-    // TODO
+//    SetEvent(p_internal->event);
 }
 
 void wxCondition::Broadcast()
 {
-    // TODO
+    int i;
+
+// TODO:
+/*
+    for (i=0;i<p_internal->waiters;i++)
+    {
+        if ( SetEvent(p_internal->event) == 0 )
+        {
+            wxLogSysError(_("Couldn't change the state of event object."));
+        }
+    }
+*/
 }
 
-class wxThreadInternal {
+// ----------------------------------------------------------------------------
+// wxCriticalSection implementation
+// ----------------------------------------------------------------------------
+#define CRITICAL_SECTION  ULONG
+class wxCriticalSectionInternal
+{
 public:
-    // TODO
+    // init the critical section object
+    wxCriticalSectionInternal()
+        { //::InitializeCriticalSection(&m_data);
+        }
+
+    // implicit cast to the associated data
+    operator CRITICAL_SECTION *() { return &m_data; }
+
+    // free the associated ressources
+    ~wxCriticalSectionInternal()
+        { //::DeleteCriticalSection(&m_data);
+        }
+
+private:
+    CRITICAL_SECTION m_data;
 };
 
+wxCriticalSection::wxCriticalSection()
+{
+    m_critsect = new wxCriticalSectionInternal;
+}
+
+wxCriticalSection::~wxCriticalSection()
+{
+    delete m_critsect;
+}
+
+void wxCriticalSection::Enter()
+{
+//TODO:    ::EnterCriticalSection(*m_critsect);
+}
+
+void wxCriticalSection::Leave()
+{
+// TODO:    ::LeaveCriticalSection(*m_critsect);
+}
+
+// ----------------------------------------------------------------------------
+// wxThread implementation
+// ----------------------------------------------------------------------------
+
+// wxThreadInternal class
+// ----------------------
+
+class wxThreadInternal
+{
+public:
+    wxThreadInternal()
+    {
+        m_hThread = 0;
+        m_state = STATE_NEW;
+        m_priority = 0; // TODO: WXTHREAD_DEFAULT_PRIORITY;
+    }
+
+    // create a new (suspended) thread (for the given thread object)
+    bool Create(wxThread *thread);
+
+    // suspend/resume/terminate
+    bool Suspend();
+    bool Resume();
+    void Cancel() { m_state = STATE_CANCELED; }
+
+    // thread state
+    void SetState(wxThreadState state) { m_state = state; }
+    wxThreadState GetState() const { return m_state; }
+
+    // thread priority
+    void SetPriority(unsigned int priority) { m_priority = priority; }
+    unsigned int GetPriority() const { return m_priority; }
+
+    // thread handle and id
+    HANDLE GetHandle() const { return m_hThread; }
+    DWORD  GetId() const { return m_tid; }
+
+    // thread function
+    static DWORD OS2ThreadStart(wxThread *thread);
+
+private:
+    HANDLE        m_hThread;    // handle of the thread
+    wxThreadState m_state;      // state, see wxThreadState enum
+    unsigned int  m_priority;   // thread priority in "wx" units
+    DWORD         m_tid;        // thread id
+};
+
+DWORD wxThreadInternal::OS2ThreadStart(wxThread *thread)
+{
+    // store the thread object in the TLS
+// TODO:
+/*
+    if ( !::TlsSetValue(s_tlsThisThread, thread) )
+    {
+        wxLogSysError(_("Can not start thread: error writing TLS."));
+
+        return (DWORD)-1;
+    }
+*/
+    DWORD ret = (DWORD)thread->Entry();
+    thread->p_internal->SetState(STATE_EXITED);
+    thread->OnExit();
+
+    delete thread;
+
+    return ret;
+}
+
+bool wxThreadInternal::Create(wxThread *thread)
+{
+// TODO:
+/*
+    m_hThread = ::CreateThread
+                  (
+                    NULL,                               // default security
+                    0,                                  // default stack size
+                    (LPTHREAD_START_ROUTINE)            // thread entry point
+                    wxThreadInternal::OS2ThreadStart,   //
+                    (LPVOID)thread,                     // parameter
+                    CREATE_SUSPENDED,                   // flags
+                    &m_tid                              // [out] thread id
+                  );
+
+    if ( m_hThread == NULL )
+    {
+        wxLogSysError(_("Can't create thread"));
+
+        return FALSE;
+    }
+
+    // translate wxWindows priority to the Windows one
+    int win_priority;
+    if (m_priority <= 20)
+        win_priority = THREAD_PRIORITY_LOWEST;
+    else if (m_priority <= 40)
+        win_priority = THREAD_PRIORITY_BELOW_NORMAL;
+    else if (m_priority <= 60)
+        win_priority = THREAD_PRIORITY_NORMAL;
+    else if (m_priority <= 80)
+        win_priority = THREAD_PRIORITY_ABOVE_NORMAL;
+    else if (m_priority <= 100)
+        win_priority = THREAD_PRIORITY_HIGHEST;
+    else
+    {
+        wxFAIL_MSG(wxT("invalid value of thread priority parameter"));
+        win_priority = THREAD_PRIORITY_NORMAL;
+    }
+
+    if ( ::SetThreadPriority(m_hThread, win_priority) == 0 )
+    {
+        wxLogSysError(_("Can't set thread priority"));
+    }
+*/
+    return FALSE;
+}
+
+bool wxThreadInternal::Suspend()
+{
+// TODO:
+/*
+    DWORD nSuspendCount = ::SuspendThread(m_hThread);
+    if ( nSuspendCount == (DWORD)-1 )
+    {
+        wxLogSysError(_("Can not suspend thread %x"), m_hThread);
+
+        return FALSE;
+    }
+
+    m_state = STATE_PAUSED;
+*/
+    return FALSE;
+}
+
+bool wxThreadInternal::Resume()
+{
+// TODO:
+/*
+    DWORD nSuspendCount = ::ResumeThread(m_hThread);
+    if ( nSuspendCount == (DWORD)-1 )
+    {
+        wxLogSysError(_("Can not resume thread %x"), m_hThread);
+
+        return FALSE;
+    }
+
+    m_state = STATE_RUNNING;
+*/
+    return FALSE;
+}
+
+// static functions
+// ----------------
+
+wxThread *wxThread::This()
+{
+    wxThread *thread = NULL; // TODO (wxThread *)::TlsGetValue(s_tlsThisThread);
+
+// TODO:
+/*
+    // be careful, 0 may be a valid return value as well
+    if ( !thread && (::GetLastError() != NO_ERROR) )
+    {
+        wxLogSysError(_("Couldn't get the current thread pointer"));
+
+        // return NULL...
+    }
+*/
+    return thread;
+}
+
+bool wxThread::IsMain()
+{
+// TODO: return ::GetCurrentThreadId() == s_idMainThread;
+    return FALSE;
+}
+
+#ifdef Yield
+    #undef Yield
+#endif
+
+void wxThread::Yield()
+{
+    // 0 argument to Sleep() is special
+    ::DosSleep(0);
+}
+
+void wxThread::Sleep(unsigned long milliseconds)
+{
+    ::DosSleep(milliseconds);
+}
+
+// create/start thread
+// -------------------
+
 wxThreadError wxThread::Create()
 {
-    // TODO
+    if ( !p_internal->Create(this) )
+        return wxTHREAD_NO_RESOURCE;
+
     return wxTHREAD_NO_ERROR;
 }
 
-wxThreadError wxThread::Destroy()
+wxThreadError wxThread::Run()
 {
-    // TODO
-    return wxTHREAD_NO_ERROR;
+    wxCriticalSectionLocker lock(m_critsect);
+
+    if ( p_internal->GetState() != STATE_NEW )
+    {
+        // actually, it may be almost any state at all, not only STATE_RUNNING
+        return wxTHREAD_RUNNING;
+    }
+
+    return Resume();
 }
 
+// suspend/resume thread
+// ---------------------
+
 wxThreadError wxThread::Pause()
 {
-    // TODO
-    return wxTHREAD_NO_ERROR;
+    wxCriticalSectionLocker lock(m_critsect);
+
+    return p_internal->Suspend() ? wxTHREAD_NO_ERROR : wxTHREAD_MISC_ERROR;
 }
 
 wxThreadError wxThread::Resume()
 {
-    // TODO
-    return wxTHREAD_NO_ERROR;
-}
+    wxCriticalSectionLocker lock(m_critsect);
 
-void wxThread::Exit(void *status)
-{
-    // TODO
+    return p_internal->Resume() ? wxTHREAD_NO_ERROR : wxTHREAD_MISC_ERROR;
 }
 
-void wxThread::SetPriority(int prio)
+// stopping thread
+// ---------------
+
+wxThread::ExitCode wxThread::Delete()
 {
-    // TODO
+    ExitCode rc = 0;
+
+    // Delete() is always safe to call, so consider all possible states
+    if ( IsPaused() )
+        Resume();
+
+    if ( IsRunning() )
+    {
+        if ( IsMain() )
+        {
+            // set flag for wxIsWaitingForThread()
+            s_waitingForThread = TRUE;
+
+            wxBeginBusyCursor();
+        }
+
+        HANDLE hThread;
+        {
+            wxCriticalSectionLocker lock(m_critsect);
+
+            p_internal->Cancel();
+            hThread = p_internal->GetHandle();
+        }
+
+        // we can't just wait for the thread to terminate because it might be
+        // calling some GUI functions and so it will never terminate before we
+        // process the Windows messages that result from these functions
+        DWORD result;
+// TODO:
+/*
+        do
+        {
+            result = ::MsgWaitForMultipleObjects
+                     (
+                       1,              // number of objects to wait for
+                       &hThread,       // the objects
+                       FALSE,          // don't wait for all objects
+                       INFINITE,       // no timeout
+                       QS_ALLEVENTS    // return as soon as there are any events
+                     );
+
+            switch ( result )
+            {
+                case 0xFFFFFFFF:
+                    // error
+                    wxLogSysError(_("Can not wait for thread termination"));
+                    Kill();
+                    return (ExitCode)-1;
+
+                case WAIT_OBJECT_0:
+                    // thread we're waiting for terminated
+                    break;
+
+                case WAIT_OBJECT_0 + 1:
+                    // new message arrived, process it
+                    if ( !wxTheApp->DoMessage() )
+                    {
+                        // WM_QUIT received: kill the thread
+                        Kill();
+
+                        return (ExitCode)-1;
+                    }
+
+                    if ( IsMain() )
+                    {
+                        // give the thread we're waiting for chance to exit
+                        // from the GUI call it might have been in
+                        if ( (s_nWaitingForGui > 0) && wxGuiOwnedByMainThread() )
+                        {
+                            wxMutexGuiLeave();
+                        }
+                    }
+
+                    break;
+
+                default:
+                    wxFAIL_MSG(wxT("unexpected result of MsgWaitForMultipleObject"));
+            }
+        } while ( result != WAIT_OBJECT_0 );
+*/
+        if ( IsMain() )
+        {
+            s_waitingForThread = FALSE;
+
+            wxEndBusyCursor();
+        }
+
+// TODO:
+/*
+        if ( !::GetExitCodeThread(hThread, (LPDWORD)&rc) )
+        {
+            wxLogLastError("GetExitCodeThread");
+
+            rc = (ExitCode)-1;
+        }
+
+        wxASSERT_MSG( (LPVOID)rc != (LPVOID)STILL_ACTIVE,
+                      wxT("thread must be already terminated.") );
+
+        ::CloseHandle(hThread);
+*/
+    }
+
+    return rc;
 }
 
-int wxThread::GetPriority() const
+wxThreadError wxThread::Kill()
 {
-    // TODO
-    return 0;
+    if ( !IsRunning() )
+        return wxTHREAD_NOT_RUNNING;
+
+// TODO:
+/*
+    if ( !::TerminateThread(p_internal->GetHandle(), (DWORD)-1) )
+    {
+        wxLogSysError(_("Couldn't terminate thread"));
+
+        return wxTHREAD_MISC_ERROR;
+    }
+*/
+    delete this;
+
+    return wxTHREAD_NO_ERROR;
 }
 
-void wxThread::DeferDestroy(bool on)
+void wxThread::Exit(void *status)
 {
-    // TODO
+    delete this;
+
+// TODO:    ::ExitThread((DWORD)status);
+
+    wxFAIL_MSG(wxT("Couldn't return from ExitThread()!"));
 }
 
-void wxThread::TestDestroy()
+void wxThread::SetPriority(unsigned int prio)
 {
-    // TODO
+    wxCriticalSectionLocker lock(m_critsect);
+
+    p_internal->SetPriority(prio);
 }
 
-void *wxThread::Join()
+unsigned int wxThread::GetPriority() const
 {
-    // TODO
-    return (void*) NULL;
+    wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
+
+    return p_internal->GetPriority();
 }
 
 unsigned long wxThread::GetID() const
 {
-    // TODO
-    return 0;
+    wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
+
+    return (unsigned long)p_internal->GetId();
 }
 
-/*
-wxThread *wxThread::GetThreadFromID(unsigned long id)
+bool wxThread::IsRunning() const
 {
-    // TODO
-    return NULL;
+    wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
+
+    return p_internal->GetState() == STATE_RUNNING;
 }
-*/
 
 bool wxThread::IsAlive() const
 {
-    // TODO
-    return FALSE;
+    wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
+
+    return (p_internal->GetState() == STATE_RUNNING) ||
+           (p_internal->GetState() == STATE_PAUSED);
 }
 
-bool wxThread::IsRunning() const
+bool wxThread::IsPaused() const
 {
-    // TODO
-    return FALSE;
+    wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
+
+    return (p_internal->GetState() == STATE_PAUSED);
 }
 
-bool wxThread::IsMain()
+bool wxThread::TestDestroy()
 {
-    // TODO
-    return FALSE;
+    wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
+
+    return p_internal->GetState() == STATE_CANCELED;
 }
 
 wxThread::wxThread()
 {
     p_internal = new wxThreadInternal();
-
-    // TODO
 }
 
 wxThread::~wxThread()
 {
-    Destroy();
-    Join();
     delete p_internal;
 }
 
-// The default callback just joins the thread and throws away the result.
-void wxThread::OnExit()
-{
-    Join();
-}
+// ----------------------------------------------------------------------------
+// Automatic initialization for thread module
+// ----------------------------------------------------------------------------
 
-// Automatic initialization
-class wxThreadModule : public wxModule {
-  DECLARE_DYNAMIC_CLASS(wxThreadModule)
+class wxThreadModule : public wxModule
+{
 public:
-  virtual bool OnInit() {
-    /* TODO p_mainid = GetCurrentThread(); */
-    wxMainMutex = new wxMutex();
-    wxMainMutex->Lock();
-    return TRUE;
-  }
+    virtual bool OnInit();
+    virtual void OnExit();
 
-  // Global cleanup
-  virtual void OnExit() {
-    wxMainMutex->Unlock();
-    delete wxMainMutex;
-  }
+private:
+    DECLARE_DYNAMIC_CLASS(wxThreadModule)
 };
 
 IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
 
+bool wxThreadModule::OnInit()
+{
+    // allocate TLS index for storing the pointer to the current thread
+// TODO:
+/*
+    s_tlsThisThread = ::TlsAlloc();
+    if ( s_tlsThisThread == 0xFFFFFFFF )
+    {
+        // in normal circumstances it will only happen if all other
+        // TLS_MINIMUM_AVAILABLE (>= 64) indices are already taken - in other
+        // words, this should never happen
+        wxLogSysError(_("Thread module initialization failed: "
+                        "impossible to allocate index in thread "
+                        "local storage"));
+
+        return FALSE;
+    }
+*/
+    // main thread doesn't have associated wxThread object, so store 0 in the
+    // TLS instead
+
+// TODO:
+/*
+    if ( !::TlsSetValue(s_tlsThisThread, (LPVOID)0) )
+    {
+        ::TlsFree(s_tlsThisThread);
+        s_tlsThisThread = 0xFFFFFFFF;
+
+        wxLogSysError(_("Thread module initialization failed: "
+                        "can not store value in thread local storage"));
+
+        return FALSE;
+    }
+*/
+    s_critsectWaitingForGui = new wxCriticalSection();
+
+    s_critsectGui = new wxCriticalSection();
+    s_critsectGui->Enter();
+
+    // no error return for GetCurrentThreadId()
+//    s_idMainThread = ::GetCurrentThreadId();
+
+    return TRUE;
+}
+
+void wxThreadModule::OnExit()
+{
+// TODO:
+/*
+    if ( !::TlsFree(s_tlsThisThread) )
+    {
+        wxLogLastError("TlsFree failed.");
+    }
+*/
+    if ( s_critsectGui )
+    {
+        s_critsectGui->Leave();
+        delete s_critsectGui;
+        s_critsectGui = NULL;
+    }
+
+    wxDELETE(s_critsectWaitingForGui);
+}
+
+// ----------------------------------------------------------------------------
+// under Windows, these functions are implemented usign a critical section and
+// not a mutex, so the names are a bit confusing
+// ----------------------------------------------------------------------------
+
+void WXDLLEXPORT wxMutexGuiEnter()
+{
+    // this would dead lock everything...
+    wxASSERT_MSG( !wxThread::IsMain(),
+                  wxT("main thread doesn't want to block in wxMutexGuiEnter()!") );
+
+    // the order in which we enter the critical sections here is crucial!!
+
+    // set the flag telling to the main thread that we want to do some GUI
+    {
+        wxCriticalSectionLocker enter(*s_critsectWaitingForGui);
+
+        s_nWaitingForGui++;
+    }
+
+    wxWakeUpMainThread();
+
+    // now we may block here because the main thread will soon let us in
+    // (during the next iteration of OnIdle())
+    s_critsectGui->Enter();
+}
+
+void WXDLLEXPORT wxMutexGuiLeave()
+{
+    wxCriticalSectionLocker enter(*s_critsectWaitingForGui);
+
+    if ( wxThread::IsMain() )
+    {
+        s_bGuiOwnedByMainThread = FALSE;
+    }
+    else
+    {
+        // decrement the number of waiters now
+        wxASSERT_MSG( s_nWaitingForGui > 0,
+                      wxT("calling wxMutexGuiLeave() without entering it first?") );
+
+        s_nWaitingForGui--;
+
+        wxWakeUpMainThread();
+    }
+
+    s_critsectGui->Leave();
+}
+
+void WXDLLEXPORT wxMutexGuiLeaveOrEnter()
+{
+    wxASSERT_MSG( wxThread::IsMain(),
+                  wxT("only main thread may call wxMutexGuiLeaveOrEnter()!") );
+
+    wxCriticalSectionLocker enter(*s_critsectWaitingForGui);
+
+    if ( s_nWaitingForGui == 0 )
+    {
+        // no threads are waiting for GUI - so we may acquire the lock without
+        // any danger (but only if we don't already have it)
+        if ( !wxGuiOwnedByMainThread() )
+        {
+            s_critsectGui->Enter();
+
+            s_bGuiOwnedByMainThread = TRUE;
+        }
+        //else: already have it, nothing to do
+    }
+    else
+    {
+        // some threads are waiting, release the GUI lock if we have it
+        if ( wxGuiOwnedByMainThread() )
+        {
+            wxMutexGuiLeave();
+        }
+        //else: some other worker thread is doing GUI
+    }
+}
+
+bool WXDLLEXPORT wxGuiOwnedByMainThread()
+{
+    return s_bGuiOwnedByMainThread;
+}
+
+// wake up the main thread if it's in ::GetMessage()
+void WXDLLEXPORT wxWakeUpMainThread()
+{
+    // sending any message would do - hopefully WM_NULL is harmless enough
+// TODO:
+/*
+    if ( !::PostThreadMessage(s_idMainThread, WM_NULL, 0, 0) )
+    {
+        // should never happen
+        wxLogLastError("PostThreadMessage(WM_NULL)");
+    }
+*/
+}
+
+bool WXDLLEXPORT wxIsWaitingForThread()
+{
+    return s_waitingForThread;
+}
+
+
 #endif
   // wxUSE_THREADS
index 5262040cf6dc4e5fb091ed200b32b5a9f385164b..bca6302c871e4e2c489ca245c641766aaa929fb2 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
 // Name:        timer.cpp
 // Purpose:     wxTimer implementation
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "timer.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#include "wx/window.h"
+#include "wx/os2/private.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/setup.h"
+    #include "wx/list.h"
+    #include "wx/event.h"
+    #include "wx/app.h"
 #endif
 
+#include "wx/intl.h"
+#include "wx/log.h"
+
 #include "wx/timer.h"
 
+#include <time.h>
+#include <sys/types.h>
+
+#include <sys/timeb.h>
+
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+wxList wxTimerList(wxKEY_INTEGER);
+UINT wxTimerProc(HWND hwnd, WORD, int idTimer, DWORD);
+
+// ----------------------------------------------------------------------------
+// macros
+// ----------------------------------------------------------------------------
+
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_ABSTRACT_CLASS(wxTimer, wxObject)
 #endif
 
 wxTimer::wxTimer()
 {
-    m_milli = 0 ;
-    m_id = 0;
-    m_oneShot = FALSE;
+    milli = 0 ;
+    id = 0;
+    oneShot = FALSE;
 }
 
 wxTimer::~wxTimer()
 {
     Stop();
+
+    wxTimerList.DeleteObject(this);
 }
 
 bool wxTimer::Start(int milliseconds,bool mode)
 {
-    m_oneShot = mode ;
-    if (milliseconds <= 0)
-        return FALSE;
+    oneShot = mode;
+    if (milliseconds < 0)
+        milliseconds = lastMilli;
+
+    wxCHECK_MSG( milliseconds > 0, FALSE, wxT("invalid value for timer timeour") );
+
+    lastMilli = milli = milliseconds;
+
+    wxTimerList.DeleteObject(this);
+// TODO:
+/*
+    TIMERPROC wxTimerProcInst = (TIMERPROC)
+        MakeProcInstance((FARPROC)wxTimerProc, wxGetInstance());
 
-    m_milli = milliseconds;
+    id = SetTimer(NULL, (UINT)(id ? id : 1),
+                  (UINT)milliseconds, wxTimerProcInst);
+*/
+    if (id > 0)
+    {
+        wxTimerList.Append(id, this);
 
-    // TODO: set the timer going.
-    return FALSE;
+        return TRUE;
+    }
+    else
+    {
+        wxLogSysError(_("Couldn't create a timer"));
+
+        return FALSE;
+    }
 }
 
 void wxTimer::Stop()
 {
-    m_id = 0 ;
-    m_milli = 0 ;
+    if ( id )
+    {
+//        KillTimer(NULL, (UINT)id);
+        wxTimerList.DeleteObject(this);
+    }
+    id = 0;
+    milli = 0;
 }
 
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+void wxProcessTimer(wxTimer& timer)
+{
+    // Avoid to process spurious timer events
+    if ( timer.id == 0)
+        return;
+
+    if ( timer.oneShot )
+        timer.Stop();
+
+    timer.Notify();
+}
+
+UINT wxTimerProc(HWND WXUNUSED(hwnd), WORD, int idTimer, DWORD)
+{
+    wxNode *node = wxTimerList.Find((long)idTimer);
+
+    wxCHECK_MSG( node, 0, wxT("bogus timer id in wxTimerProc") );
+
+    wxProcessTimer(*(wxTimer *)node->Data());
+
+    return 0;
+}
 
index 3cb859e3663f8890c53ac03a83946a4211578515..922a55e99845c8450372cc1f28f8476c33d2ff7a 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
 // Name:        toolbar.cpp
 // Purpose:     wxToolBar
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     04/01/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "toolbar.h"
-#endif
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
 
+#ifndef WX_PRECOMP
 #include "wx/wx.h"
+#endif
+
+#if wxUSE_BUTTONBAR && wxUSE_TOOLBAR && defined(__WIN95__)
+
+#include "malloc.h"
+#define INCL_PM
+#include <os2.h>
+
 #include "wx/toolbar.h"
+#include "wx/app.h"
+#include "wx/os2/private.h"
+
+// Styles
+#ifndef TBSTYLE_FLAT
+#define TBSTYLE_LIST            0x1000
+#define TBSTYLE_FLAT            0x0800
+#define TBSTYLE_TRANSPARENT     0x8000
+#endif
+ // use TBSTYLE_TRANSPARENT if you use TBSTYLE_FLAT
+
+// Messages
+#ifndef TB_GETSTYLE
+#define TB_GETSTYLE             (WM_USER + 57)
+#define TB_SETSTYLE             (WM_USER + 56)
+#endif
+
+/* Hint from a newsgroup for custom flatbar drawing:
+Set the TBSTYLE_CUSTOMERASE style, then handle the
+NM_CUSTOMDRAW message and do your custom drawing.
+*/
+
+#define DEFAULTBITMAPX   16
+#define DEFAULTBITMAPY   15
+#define DEFAULTBUTTONX   24
+#define DEFAULTBUTTONY   24
+#define DEFAULTBARHEIGHT 27
 
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
+#endif
 
 BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
+    EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent)
+    EVT_SYS_COLOUR_CHANGED(wxToolBar::OnSysColourChanged)
 END_EVENT_TABLE()
-#endif
+
+static void wxMapBitmap(HBITMAP hBitmap, int width, int height);
 
 wxToolBar::wxToolBar()
 {
   m_maxWidth = -1;
   m_maxHeight = -1;
-  m_defaultWidth = 24;
-  m_defaultHeight = 22;
-  // TODO
+  m_hBitmap = 0;
+  m_defaultWidth = DEFAULTBITMAPX;
+  m_defaultHeight = DEFAULTBITMAPY;
 }
 
-bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
-            long style, const wxString& name)
+bool wxToolBar::Create(wxWindow *parent,
+                         wxWindowID id,
+                         const wxPoint& pos,
+                         const wxSize& size,
+                         long style,
+                         const wxString& name)
 {
-    m_maxWidth = -1;
-    m_maxHeight = -1;
-  
-    m_defaultWidth = 24;
-    m_defaultHeight = 22;
-    SetName(name);
+  m_hWnd = 0;
+  m_backgroundColour = *wxWHITE; //TODO: wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
+//                                GetGValue(GetSysColor(COLOR_BTNFACE)),
+//                                GetBValue(GetSysColor(COLOR_BTNFACE)));
+  m_foregroundColour = *wxBLACK ;
 
-    m_windowStyle = style;
+  wxASSERT_MSG( (style & wxTB_VERTICAL) == 0,
+                wxT("Sorry, wxToolBar under Windows 95 only "
+                   "supports horizontal orientation.") );
 
-    SetParent(parent);
+  m_maxWidth = -1;
+  m_maxHeight = -1;
 
-    if (parent) parent->AddChild(this);
+  m_hBitmap = 0;
 
-    // TODO create toolbar
-  
-    return FALSE;
+  m_defaultWidth = DEFAULTBITMAPX;
+  m_defaultHeight = DEFAULTBITMAPY;
+  SetName(name);
+
+  m_windowStyle = style;
+
+  SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
+  SetParent(parent);
+
+  int x = pos.x;
+  int y = pos.y;
+  int width = size.x;
+  int height = size.y;
+
+  if (width <= 0)
+    width = 100;
+  if (height <= 0)
+    height = 30;
+  if (x < 0)
+    x = 0;
+  if (y < 0)
+    y = 0;
+
+  m_windowId = (id < 0 ? NewControlId() : id);
+  DWORD msflags = 0;
+// TODO:
+/*
+  if (style & wxBORDER)
+    msflags |= WS_BORDER;
+  msflags |= WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS;
+
+  if (style & wxTB_FLAT)
+  {
+    if (wxTheApp->GetComCtl32Version() > 400)
+        msflags |= TBSTYLE_FLAT;
+  }
+
+  bool want3D;
+  WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
+
+  // Even with extended styles, need to combine with WS_BORDER
+  // for them to look right.
+  if ( want3D || wxStyleHasBorder(m_windowStyle) )
+      msflags |= WS_BORDER;
+
+  // Create the toolbar control.
+  HWND hWndToolbar = CreateWindowEx
+                     (
+                      exStyle,                  // Extended styles.
+                      TOOLBARCLASSNAME,         // Class name for the toolbar.
+                      wxT(""),                   // No default text.
+                      msflags,                  // Styles
+                      x, y, width, height,      // Standard toolbar size and position.
+                      (HWND) parent->GetHWND(), // Parent window of the toolbar.
+                      (HMENU)m_windowId,        // Toolbar ID.
+                      wxGetInstance(),          // Current instance.
+                      NULL                      // No class data.
+                     );
+
+  wxCHECK_MSG( hWndToolbar, FALSE, wxT("Toolbar creation failed") );
+
+  // Toolbar-specific initialisation
+  ::SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE,
+                (WPARAM)sizeof(TBBUTTON), (LPARAM)0);
+*/
+  m_hWnd = (WXHWND) hWndToolbar;
+  if (parent)
+      parent->AddChild(this);
+
+  SubclassWin((WXHWND)hWndToolbar);
+
+  return TRUE;
 }
 
 wxToolBar::~wxToolBar()
 {
-    // TODO
+  UnsubclassWin();
+
+  if (m_hBitmap)
+  {
+//    ::DeleteObject((HBITMAP) m_hBitmap);
+    m_hBitmap = 0;
+  }
 }
 
 bool wxToolBar::CreateTools()
 {
-    if (m_tools.Number() == 0)
+  if (m_tools.Number() == 0)
+    return FALSE;
+
+  HBITMAP oldToolBarBitmap = (HBITMAP) m_hBitmap;
+
+  int totalBitmapWidth = (int)(m_defaultWidth * m_tools.Number());
+  int totalBitmapHeight = (int)m_defaultHeight;
+
+// TODO:
+/*
+  // Create a bitmap for all the tool bitmaps
+  HDC dc = ::GetDC(NULL);
+  m_hBitmap = (WXHBITMAP) ::CreateCompatibleBitmap(dc, totalBitmapWidth, totalBitmapHeight);
+  ::ReleaseDC(NULL, dc);
+
+  // Now blit all the tools onto this bitmap
+  HDC memoryDC = ::CreateCompatibleDC(NULL);
+  HBITMAP oldBitmap = (HBITMAP) ::SelectObject(memoryDC, (HBITMAP) m_hBitmap);
+
+  HDC memoryDC2 = ::CreateCompatibleDC(NULL);
+  int x = 0;
+  wxNode *node = m_tools.First();
+  int noButtons = 0;
+  while (node)
+  {
+    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
+    if ((tool->m_toolStyle != wxTOOL_STYLE_SEPARATOR) && tool->m_bitmap1.Ok() && tool->m_bitmap1.GetHBITMAP())
+    {
+//      wxPalette *palette = tool->m_bitmap1->GetPalette();
+
+      HBITMAP oldBitmap2 = (HBITMAP) ::SelectObject(memoryDC2, (HBITMAP) tool->m_bitmap1.GetHBITMAP());
+      // int bltResult =
+      BitBlt(memoryDC, x, 0, (int) m_defaultWidth, (int) m_defaultHeight, memoryDC2,
+                        0, 0, SRCCOPY);
+      ::SelectObject(memoryDC2, oldBitmap2);
+      x += (int)m_defaultWidth;
+      noButtons ++;
+    }
+    node = node->Next();
+  }
+  ::SelectObject(memoryDC, oldBitmap);
+  ::DeleteDC(memoryDC);
+  ::DeleteDC(memoryDC2);
+
+  // Map to system colours
+  wxMapBitmap((HBITMAP) m_hBitmap, totalBitmapWidth, totalBitmapHeight);
+
+  if ( oldToolBarBitmap )
+  {
+    TBREPLACEBITMAP replaceBitmap;
+    replaceBitmap.hInstOld = NULL;
+    replaceBitmap.hInstNew = NULL;
+    replaceBitmap.nIDOld = (UINT) oldToolBarBitmap;
+    replaceBitmap.nIDNew = (UINT) (HBITMAP) m_hBitmap;
+    replaceBitmap.nButtons = noButtons;
+    if (::SendMessage((HWND) GetHWND(), TB_REPLACEBITMAP, (WPARAM) 0, (LPARAM) &replaceBitmap) == -1)
+    {
+      wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
+    }
+
+    ::DeleteObject((HBITMAP) oldToolBarBitmap);
+
+    // Now delete all the buttons
+    int i = 0;
+    while ( TRUE )
+    {
+        // TODO: What about separators???? They don't have an id!
+        if ( ! ::SendMessage( (HWND) GetHWND(), TB_DELETEBUTTON, i, 0 ) )
+            break;
+    }
+  }
+  else
+  {
+    TBADDBITMAP addBitmap;
+    addBitmap.hInst = 0;
+    addBitmap.nID = (UINT)m_hBitmap;
+    if (::SendMessage((HWND) GetHWND(), TB_ADDBITMAP, (WPARAM) noButtons, (LPARAM) &addBitmap) == -1)
+    {
+      wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
+    }
+  }
+
+  // Now add the buttons.
+  TBBUTTON buttons[50];
+
+  node = m_tools.First();
+  int i = 0;
+  int bitmapId = 0;
+  while (node)
+  {
+    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
+    if (tool->m_toolStyle == wxTOOL_STYLE_SEPARATOR)
+    {
+      buttons[i].iBitmap = 0;
+      buttons[i].idCommand = 0;
+
+      buttons[i].fsState = TBSTATE_ENABLED;
+      buttons[i].fsStyle = TBSTYLE_SEP;
+      buttons[i].dwData = 0L;
+      buttons[i].iString = 0;
+    }
+    else
+    {
+      buttons[i].iBitmap = bitmapId;
+      buttons[i].idCommand = tool->m_index;
+
+      buttons[i].fsState = 0;
+      if (tool->m_enabled)
+        buttons[i].fsState |= TBSTATE_ENABLED;
+      if (tool->m_toggleState)
+        buttons[i].fsState |= TBSTATE_CHECKED;
+      buttons[i].fsStyle = tool->m_isToggle ? TBSTYLE_CHECK : TBSTYLE_BUTTON;
+      buttons[i].dwData = 0L;
+      buttons[i].iString = 0;
+
+      bitmapId ++;
+    }
+
+    i ++;
+    node = node->Next();
+  }
+
+  long rc = ::SendMessage((HWND) GetHWND(), TB_ADDBUTTONS, (WPARAM)i, (LPARAM)& buttons);
+
+  wxCHECK_MSG( rc, FALSE, wxT("failed to add buttons to the toolbar") );
+
+  (void)::SendMessage((HWND) GetHWND(), TB_AUTOSIZE, (WPARAM)0, (LPARAM) 0);
+
+  SetRows(m_maxRows);
+*/
+  return TRUE;
+}
+
+bool wxToolBar::OS2Command(WXUINT cmd, WXWORD id)
+{
+  wxNode *node = m_tools.Find((long)id);
+  if (!node)
+    return FALSE;
+  wxToolBarTool *tool = (wxToolBarTool *)node->Data();
+// TODO:
+/*
+ if (tool->m_isToggle)
+    tool->m_toggleState = (1 == (1 & (int)::SendMessage((HWND) GetHWND(), TB_GETSTATE, (WPARAM) id, (LPARAM) 0)));
+
+  BOOL ret = OnLeftClick((int)id, tool->m_toggleState);
+  if (ret == FALSE && tool->m_isToggle)
+  {
+    tool->m_toggleState = !tool->m_toggleState;
+    ::SendMessage((HWND) GetHWND(), TB_CHECKBUTTON, (WPARAM)id, (LPARAM)MAKELONG(tool->m_toggleState, 0));
+  }
+  return TRUE;
+*/
+  return FALSE;
+}
+
+bool wxToolBar::OS2OnNotify(int WXUNUSED(idCtrl),
+                            WXLPARAM lParam,
+                            WXLPARAM *result)
+{
+// TODO:
+/*
+    // 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
+    int code = (int)hdr->code;
+    if ( (code != TTN_NEEDTEXTA) && (code != TTN_NEEDTEXTW) )
+        return FALSE;
+
+    HWND toolTipWnd = (HWND)::SendMessage((HWND)GetHWND(), TB_GETTOOLTIPS, 0, 0);
+    if ( toolTipWnd != hdr->hwndFrom )
         return FALSE;
 
-    // TODO
+    LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam;
+    int id = (int)ttText->hdr.idFrom;
+    wxNode *node = m_tools.Find((long)id);
+    if (!node)
+        return FALSE;
+
+    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
+
+    const wxString& help = tool->m_shortHelpString;
+
+    if ( !help.IsEmpty() )
+    {
+        if ( code == TTN_NEEDTEXTA )
+        {
+            ttText->lpszText = (wxChar *)help.c_str();
+        }
+#if (_WIN32_IE >= 0x0300)
+        else
+        {
+            // FIXME this is a temp hack only until I understand better what
+            //       must be done in both ANSI and Unicode builds
+
+            size_t lenAnsi = help.Len();
+            #ifdef __MWERKS__
+                // MetroWerks doesn't like calling mbstowcs with NULL argument
+                size_t lenUnicode = 2*lenAnsi;
+            #else
+                size_t lenUnicode = mbstowcs(NULL, help, lenAnsi);
+            #endif
+
+            // using the pointer of right type avoids us doing all sorts of
+            // pointer arithmetics ourselves
+            wchar_t *dst = (wchar_t *)ttText->szText,
+                    *pwz = new wchar_t[lenUnicode + 1];
+            mbstowcs(pwz, help, lenAnsi + 1);
+            memcpy(dst, pwz, lenUnicode*sizeof(wchar_t));
+
+            // put the terminating _wide_ NUL
+            dst[lenUnicode] = 0;
+
+            delete [] pwz;
+        }
+#endif // _WIN32_IE >= 0x0300
+    }
+
+    // For backward compatibility...
+    OnMouseEnter(tool->m_index);
+
+    return TRUE;
+*/
     return FALSE;
 }
 
 void wxToolBar::SetToolBitmapSize(const wxSize& size)
 {
-    m_defaultWidth = size.x; m_defaultHeight = size.y;
-    // TODO
+  m_defaultWidth = size.x;
+  m_defaultHeight = size.y;
+//  ::SendMessage((HWND) GetHWND(), TB_SETBITMAPSIZE, 0, (LPARAM) MAKELONG ((int)size.x, (int)size.y));
+}
+
+void wxToolBar::SetRows(int nRows)
+{
+// TODO:
+/*
+  RECT rect;
+  ::SendMessage((HWND) GetHWND(), TB_SETROWS, MAKEWPARAM(nRows, TRUE), (LPARAM) & rect);
+  m_maxWidth = (rect.right - rect.left + 2);
+  m_maxHeight = (rect.bottom - rect.top + 2);
+*/
 }
 
 wxSize wxToolBar::GetMaxSize() const
 {
-    // TODO
-    return wxSize(0, 0);
+// TODO:
+/*
+  if ((m_maxWidth == -1) || (m_maxHeight == -1))
+  {
+    RECT rect;
+    ::SendMessage((HWND) GetHWND(), TB_SETROWS, MAKEWPARAM(m_maxRows, TRUE), (LPARAM) & rect);
+    ((wxToolBar *)this)->m_maxWidth = (rect.right - rect.left + 2); // ???
+    ((wxToolBar *)this)->m_maxHeight = (rect.bottom - rect.top + 2); // ???
+  }
+*/
+  return wxSize(m_maxWidth, m_maxHeight);
 }
 
 // The button size is bigger than the bitmap size
 wxSize wxToolBar::GetToolSize() const
 {
-    // TODO
-    return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
+  return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
 }
 
 void wxToolBar::EnableTool(int toolIndex, bool enable)
 {
-    wxNode *node = m_tools.Find((long)toolIndex);
-    if (node)
-    {
-        wxToolBarTool *tool = (wxToolBarTool *)node->Data();
-        tool->m_enabled = enable;
-        // TODO enable button
-    }
+  wxNode *node = m_tools.Find((long)toolIndex);
+  if (node)
+  {
+    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
+    tool->m_enabled = enable;
+//    ::SendMessage((HWND) GetHWND(), TB_ENABLEBUTTON, (WPARAM)toolIndex, (LPARAM)MAKELONG(enable, 0));
+  }
 }
 
 void wxToolBar::ToggleTool(int toolIndex, bool toggle)
 {
-    wxNode *node = m_tools.Find((long)toolIndex);
-    if (node)
+  wxNode *node = m_tools.Find((long)toolIndex);
+  if (node)
+  {
+    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
+    if (tool->m_isToggle)
     {
-        wxToolBarTool *tool = (wxToolBarTool *)node->Data();
-        if (tool->m_isToggle)
-        {
-            tool->m_toggleState = toggle;
-            // TODO: set toggle state
-        }
+      tool->m_toggleState = toggle;
+//      ::SendMessage((HWND) GetHWND(), TB_CHECKBUTTON, (WPARAM)toolIndex, (LPARAM)MAKELONG(toggle, 0));
     }
+  }
+}
+
+bool wxToolBar::GetToolState(int toolIndex) const
+{
+//    return (::SendMessage((HWND) GetHWND(), TB_ISBUTTONCHECKED, (WPARAM)toolIndex, (LPARAM)0) != 0);
+    return FALSE;
 }
 
 void wxToolBar::ClearTools()
 {
-    // TODO
-    wxToolBarBase::ClearTools();
+  // TODO: Don't know how to reset the toolbar bitmap, as yet.
+  // But adding tools and calling CreateTools should probably
+  // recreate a buttonbar OK.
+  wxToolBarBase::ClearTools();
 }
 
 // If pushedBitmap is NULL, a reversed version of bitmap is
 // created and used as the pushed/toggled image.
 // If toggle is TRUE, the button toggles between the two states.
-
 wxToolBarTool *wxToolBar::AddTool(int index, const wxBitmap& bitmap, const wxBitmap& pushedBitmap,
              bool toggle, long xPos, long yPos, wxObject *clientData, const wxString& helpString1, const wxString& helpString2)
 {
@@ -137,9 +504,137 @@ wxToolBarTool *wxToolBar::AddTool(int index, const wxBitmap& bitmap, const wxBit
   else
     tool->m_y = m_yMargin;
 
-  tool->SetSize(GetDefaultButtonWidth(), GetDefaultButtonHeight());
+  tool->SetSize(GetToolSize().x, GetToolSize().y);
 
   m_tools.Append((long)index, tool);
   return tool;
 }
 
+// Responds to colour changes, and passes event on to children.
+void wxToolBar::OnSysColourChanged(wxSysColourChangedEvent& event)
+{
+// TODO:
+/*
+    m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
+          GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
+*/
+    // Remap the buttons
+    CreateTools();
+
+    Refresh();
+
+    // Propagate the event to the non-top-level children
+    wxWindow::OnSysColourChanged(event);
+}
+
+void wxToolBar::OnMouseEvent(wxMouseEvent& event)
+{
+    if (event.RightDown())
+    {
+        // For now, we don't have an id. Later we could
+        // try finding the tool.
+        OnRightClick((int)-1, event.GetX(), event.GetY());
+    }
+    else
+    {
+        event.Skip();
+    }
+}
+
+// These are the default colors used to map the bitmap colors
+// to the current system colors
+
+#define BGR_BUTTONTEXT      (RGB(000,000,000))  // black
+#define BGR_BUTTONSHADOW    (RGB(128,128,128))  // dark grey
+#define BGR_BUTTONFACE      (RGB(192,192,192))  // bright grey
+#define BGR_BUTTONHILIGHT   (RGB(255,255,255))  // white
+#define BGR_BACKGROUNDSEL   (RGB(255,000,000))  // blue
+#define BGR_BACKGROUND      (RGB(255,000,255))  // magenta
+
+void wxMapBitmap(HBITMAP hBitmap, int width, int height)
+{
+  COLORMAP ColorMap[] = {
+    {BGR_BUTTONTEXT,    COLOR_BTNTEXT},     // black
+    {BGR_BUTTONSHADOW,  COLOR_BTNSHADOW},   // dark grey
+    {BGR_BUTTONFACE,    COLOR_BTNFACE},     // bright grey
+    {BGR_BUTTONHILIGHT, COLOR_BTNHIGHLIGHT},// white
+    {BGR_BACKGROUNDSEL, COLOR_HIGHLIGHT},   // blue
+    {BGR_BACKGROUND,    COLOR_WINDOW}       // magenta
+  };
+
+  int NUM_MAPS = (sizeof(ColorMap)/sizeof(COLORMAP));
+  int n;
+  for ( n = 0; n < NUM_MAPS; n++)
+  {
+    ColorMap[n].to = ::GetSysColor(ColorMap[n].to);
+  }
+
+  HBITMAP hbmOld;
+  HDC hdcMem = CreateCompatibleDC(NULL);
+
+  if (hdcMem)
+  {
+    hbmOld = (HBITMAP) SelectObject(hdcMem, hBitmap);
+
+    int i, j, k;
+    for ( i = 0; i < width; i++)
+    {
+        for ( j = 0; j < height; j++)
+        {
+//            COLORREF pixel = ::GetPixel(hdcMem, i, j);
+/*
+            BYTE red = GetRValue(pixel);
+            BYTE green = GetGValue(pixel);
+            BYTE blue = GetBValue(pixel);
+*/
+
+            for ( k = 0; k < NUM_MAPS; k ++)
+            {
+                if ( ColorMap[k].from == pixel )
+                {
+//                    /* COLORREF actualPixel = */ ::SetPixel(hdcMem, i, j, ColorMap[k].to);
+                    break;
+                }
+            }
+        }
+    }
+
+
+//    SelectObject(hdcMem, hbmOld);
+//    DeleteObject(hdcMem);
+  }
+
+}
+
+// Some experiments...
+#if 0
+  // What we want to do is create another bitmap which has a depth of 4,
+  // and set the bits. So probably we want to convert this HBITMAP into a
+  // DIB, then call SetDIBits.
+  // AAAGH. The stupid thing is that if newBitmap has a depth of 4 (less than that of
+  // the screen), then SetDIBits fails.
+  HBITMAP newBitmap = ::CreateBitmap(totalBitmapWidth, totalBitmapHeight, 1, 4, NULL);
+  HANDLE newDIB = ::BitmapToDIB((HBITMAP) m_hBitmap, NULL);
+  LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER) GlobalLock(newDIB);
+
+  dc = ::GetDC(NULL);
+//  LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER) newDIB;
+
+  int result = ::SetDIBits(dc, newBitmap, 0, lpbmi->biHeight, FindDIBBits((LPSTR)lpbmi), (LPBITMAPINFO)lpbmi,
+    DIB_PAL_COLORS);
+  DWORD err = GetLastError();
+
+  ::ReleaseDC(NULL, dc);
+
+  // Delete the DIB
+  GlobalUnlock (newDIB);
+  GlobalFree (newDIB);
+
+//  WXHBITMAP hBitmap2 = wxCreateMappedBitmap((WXHINSTANCE) wxGetInstance(), (WXHBITMAP) m_hBitmap);
+  // Substitute our new bitmap for the old one
+  ::DeleteObject((HBITMAP) m_hBitmap);
+  m_hBitmap = (WXHBITMAP) newBitmap;
+#endif
+
+
+#endif
diff --git a/src/os2/tooltip.cpp b/src/os2/tooltip.cpp
new file mode 100644 (file)
index 0000000..224f1b3
--- /dev/null
@@ -0,0 +1,214 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        msw/tooltip.cpp
+// Purpose:     wxToolTip class implementation for MSW
+// Author:      David Webster
+// Modified by:
+// Created:     10/17/99
+// RCS-ID:      $Id$
+// Copyright:   (c) David Webster
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/wx.h"
+#endif
+
+#if wxUSE_TOOLTIPS
+
+#include "wx/tooltip.h"
+#include "wx/os2/private.h"
+
+// ----------------------------------------------------------------------------
+// global variables
+// ----------------------------------------------------------------------------
+
+// the tooltip parent window
+WXHWND wxToolTip::hwndTT = (WXHWND)NULL;
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+
+// a simple wrapper around TOOLINFO Win32 structure
+class wxToolInfo // define a TOOLINFO for OS/2 here : public TOOLINFO
+{
+public:
+    wxToolInfo(wxWindow *win)
+    {
+        // initialize all members
+//        ::ZeroMemory(this, sizeof(TOOLINFO));
+
+        cbSize = sizeof(this);
+        uFlags = 0; // TTF_IDISHWND;
+        uId = (UINT)win->GetHWND();
+    }
+    size_t        cbSize;
+    ULONG         uFlags;
+    UINT          uId;
+    HWND          hwnd;
+    char*         lpszText;
+};
+
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+// send a message to the tooltip control
+inline MRESULT SendTooltipMessage(WXHWND hwnd,
+                                  UINT msg,
+                                  MPARAM wParam,
+                                  MPARAM lParam)
+{
+//    return hwnd ? ::SendMessage((HWND)hwnd, msg, wParam, (MPARAM)lParam)
+//                : 0;
+    return (MRESULT)0;
+}
+
+// send a message to all existing tooltip controls
+static void SendTooltipMessageToAll(WXHWND hwnd,
+                                    UINT msg,
+                                    MPARAM wParam,
+                                    MPARAM lParam)
+{
+   if ( hwnd )
+     (void)SendTooltipMessage((WXHWND)hwnd, msg, wParam, lParam);
+}
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// static functions
+// ----------------------------------------------------------------------------
+
+void wxToolTip::Enable(bool flag)
+{
+//    SendTooltipMessageToAll((WXHWND)hwndTT,TTM_ACTIVATE, flag, 0);
+}
+
+void wxToolTip::SetDelay(long milliseconds)
+{
+//    SendTooltipMessageToAll((WXHWND)hwndTT,TTM_SETDELAYTIME, TTDT_INITIAL, milliseconds);
+}
+
+// ---------------------------------------------------------------------------
+// implementation helpers
+// ---------------------------------------------------------------------------
+
+// create the tooltip ctrl for our parent frame if it doesn't exist yet
+WXHWND wxToolTip::GetToolTipCtrl()
+{
+// TODO:
+/*
+    if ( !hwndTT )
+    {
+        hwndTT = (WXHWND)::CreateWindow(TOOLTIPS_CLASS,
+                                (LPSTR)NULL,
+                                TTS_ALWAYSTIP,
+                                CW_USEDEFAULT, CW_USEDEFAULT,
+                                CW_USEDEFAULT, CW_USEDEFAULT,
+                                NULL, (HMENU)NULL,
+                                wxGetInstance(),
+                                NULL);
+       if ( hwndTT )
+       {
+           SetWindowPos((HWND)hwndTT, HWND_TOPMOST, 0, 0, 0, 0,
+                        SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+       }
+
+    }
+    return (WXHWND)hwndTT;
+*/
+    return (WXHWND)0;
+}
+
+void wxToolTip::RelayEvent(WXMSG *msg)
+{
+//  (void)SendTooltipMessage(GetToolTipCtrl(), TTM_RELAYEVENT, 0, msg);
+}
+
+// ----------------------------------------------------------------------------
+// ctor & dtor
+// ----------------------------------------------------------------------------
+
+wxToolTip::wxToolTip(const wxString &tip)
+         : m_text(tip)
+{
+    m_window = NULL;
+}
+
+wxToolTip::~wxToolTip()
+{
+    // there is no need to Remove() this tool - it will be done automatically
+    // anyhow
+}
+
+// ----------------------------------------------------------------------------
+// others
+// ----------------------------------------------------------------------------
+
+void wxToolTip::Remove()
+{
+    // remove this tool from the tooltip control
+    if ( m_window )
+    {
+        wxToolInfo ti(m_window);
+//      (void)SendTooltipMessage(GetToolTipCtrl(), TTM_DELTOOL, 0, &ti);
+    }
+}
+
+void wxToolTip::SetWindow(wxWindow *win)
+{
+    Remove();
+
+    m_window = win;
+
+    if ( m_window )
+    {
+        wxToolInfo ti(m_window);
+
+        // as we store our text anyhow, it seems useless to waste system memory
+        // by asking the tooltip ctrl to remember it too - instead it will send
+        // us TTN_NEEDTEXT (via WM_NOTIFY) when it is about to be shown
+        ti.hwnd = (HWND)m_window->GetHWND();
+//        ti.lpszText = LPSTR_TEXTCALLBACK;
+        // instead of: ti.lpszText = (char *)m_text.c_str();
+
+// TODO:
+/*
+        if ( !SendTooltipMessage(GetToolTipCtrl(), TTM_ADDTOOL, 0, &ti) )
+        {
+            wxLogSysError(_("Failed to create the tooltip '%s'"),
+                          m_text.c_str());
+        }
+*/
+    }
+}
+
+void wxToolTip::SetTip(const wxString& tip)
+{
+    m_text = tip;
+
+    if ( m_window )
+    {
+        // update it immediately
+        wxToolInfo ti(m_window);
+        ti.lpszText = (wxChar *)m_text.c_str();
+
+//      (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, 0, &ti);
+    }
+}
+
+#endif // wxUSE_TOOLTIPS
index 137a885dbfa7e32c9096f78376146fda7cffaf68..8671b38c71030beedf1894bdeef675da04f76c82 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
 // Name:        treectrl.cpp
 // Purpose:     wxTreeCtrl. See also Robert's generic wxTreeCtrl.
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "treectrl.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#include "wx/window.h"
+#include "wx/os2/private.h"
+
+#include "wx/log.h"
+#include "wx/dynarray.h"
+#include "wx/imaglist.h"
+#include "wx/treectrl.h"
+#include "wx/settings.h"
+
+// Bug in headers, sometimes
+#ifndef TVIS_FOCUSED
+    #define TVIS_FOCUSED            0x0001
 #endif
 
-#include "wx/stubs/textctrl.h"
-#include "wx/stubs/treectrl.h"
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
 
-#if !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxControl)
-IMPLEMENT_DYNAMIC_CLASS(wxTreeItem, wxObject)
+struct wxTreeViewItem// ??? : public TV_ITEM
+{
+    wxTreeViewItem(const wxTreeItemId& item,    // the item handle
+                   UINT mask_,                  // fields which are valid
+                   UINT stateMask_ = 0)         // for TVIF_STATE only
+    {
+        // hItem member is always valid
+        mask = mask_; // | TVIF_HANDLE;
+        stateMask = stateMask_;
+        hItem = /*(HTREEITEM)*/ (WXHTREEITEM) item;
+    }
+    // OS/2 subs
+    UINT          mask;
+    UINT          stateMask;
+    WXHTREEITEM   hItem;
+};
+
+// a class which encapsulates the tree traversal logic: it vists all (unless
+// OnVisit() returns FALSE) items under the given one
+class wxTreeTraversal
+{
+public:
+    wxTreeTraversal(const wxTreeCtrl *tree)
+    {
+        m_tree = tree;
+    }
+
+    // do traverse the tree: visit all items (recursively by default) under the
+    // given one; return TRUE if all items were traversed or FALSE if the
+    // traversal was aborted because OnVisit returned FALSE
+    bool DoTraverse(const wxTreeItemId& root, bool recursively = TRUE);
+
+    // override this function to do whatever is needed for each item, return
+    // FALSE to stop traversing
+    virtual bool OnVisit(const wxTreeItemId& item) = 0;
+
+protected:
+    const wxTreeCtrl *GetTree() const { return m_tree; }
+
+private:
+    bool Traverse(const wxTreeItemId& root, bool recursively);
+
+    const wxTreeCtrl *m_tree;
+};
+
+// internal class for getting the selected items
+class TraverseSelections : public wxTreeTraversal
+{
+public:
+    TraverseSelections(const wxTreeCtrl *tree,
+                       wxArrayTreeItemIds& selections)
+        : wxTreeTraversal(tree), m_selections(selections)
+        {
+            m_selections.Empty();
+
+            DoTraverse(tree->GetRootItem());
+        }
+
+    virtual bool OnVisit(const wxTreeItemId& item)
+    {
+        if ( GetTree()->IsItemChecked(item) )
+        {
+            m_selections.Add(item);
+        }
+
+        return TRUE;
+    }
 
+private:
+    wxArrayTreeItemIds& m_selections;
+};
+
+// internal class for counting tree items
+class TraverseCounter : public wxTreeTraversal
+{
+public:
+    TraverseCounter(const wxTreeCtrl *tree,
+                    const wxTreeItemId& root,
+                    bool recursively)
+        : wxTreeTraversal(tree)
+        {
+            m_count = 0;
+
+            DoTraverse(root, recursively);
+        }
+
+    virtual bool OnVisit(const wxTreeItemId& item)
+    {
+        m_count++;
+
+        return TRUE;
+    }
+
+    size_t GetCount() const { return m_count; }
+
+private:
+    size_t m_count;
+};
+
+// ----------------------------------------------------------------------------
+// This class is needed for support of different images: the Win32 common
+// control natively supports only 2 images (the normal one and another for the
+// selected state). We wish to provide support for 2 more of them for folder
+// items (i.e. those which have children): for expanded state and for expanded
+// selected state. For this we use this structure to store the additional items
+// images.
+//
+// There is only one problem with this: when we retrieve the item's data, we
+// don't know whether we get a pointer to wxTreeItemData or
+// wxTreeItemIndirectData. So we have to maintain a list of all items which
+// have indirect data inside the listctrl itself.
+// ----------------------------------------------------------------------------
+class wxTreeItemIndirectData
+{
+public:
+    // ctor associates this data with the item and the real item data becomes
+    // available through our GetData() method
+    wxTreeItemIndirectData(wxTreeCtrl *tree, const wxTreeItemId& item)
+    {
+        for ( size_t n = 0; n < WXSIZEOF(m_images); n++ )
+        {
+            m_images[n] = -1;
+        }
+
+        // save the old data
+        m_data = tree->GetItemData(item);
+
+        // and set ourselves as the new one
+        tree->SetIndirectItemData(item, this);
+    }
+
+    // dtor deletes the associated data as well
+    ~wxTreeItemIndirectData() { delete m_data; }
+
+    // accessors
+        // get the real data associated with the item
+    wxTreeItemData *GetData() const { return m_data; }
+        // change it
+    void SetData(wxTreeItemData *data) { m_data = data; }
+
+        // do we have such image?
+    bool HasImage(wxTreeItemIcon which) const { return m_images[which] != -1; }
+        // get image
+    int GetImage(wxTreeItemIcon which) const { return m_images[which]; }
+        // change it
+    void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; }
+
+private:
+    // all the images associated with the item
+    int m_images[wxTreeItemIcon_Max];
+
+    wxTreeItemData *m_data;
+};
+
+// ----------------------------------------------------------------------------
+// macros
+// ----------------------------------------------------------------------------
+
+#if !USE_SHARED_LIBRARY
+    IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxControl)
 #endif
 
-wxTreeCtrl::wxTreeCtrl()
+// ----------------------------------------------------------------------------
+// variables
+// ----------------------------------------------------------------------------
+
+// handy table for sending events
+static const wxEventType g_events[2][2] =
 {
-    m_imageListNormal = NULL;
-    m_imageListState = NULL;
-    m_textCtrl = NULL;
+    { wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxEVT_COMMAND_TREE_ITEM_COLLAPSING },
+    { wxEVT_COMMAND_TREE_ITEM_EXPANDED,  wxEVT_COMMAND_TREE_ITEM_EXPANDING  }
+};
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// tree traversal
+// ----------------------------------------------------------------------------
+
+bool wxTreeTraversal::DoTraverse(const wxTreeItemId& root, bool recursively)
+{
+    if ( !OnVisit(root) )
+        return FALSE;
+
+    return Traverse(root, recursively);
 }
 
-bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
-            long style, const wxValidator& validator, const wxString& name)
+bool wxTreeTraversal::Traverse(const wxTreeItemId& root, bool recursively)
 {
-    SetName(name);
-    SetValidator(validator);
+    long cookie;
+    wxTreeItemId child = m_tree->GetFirstChild(root, cookie);
+    while ( child.IsOk() )
+    {
+        // depth first traversal
+        if ( recursively && !Traverse(child, TRUE) )
+            return FALSE;
+
+        if ( !OnVisit(child) )
+            return FALSE;
+
+        child = m_tree->GetNextChild(root, cookie);
+    }
 
+    return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// construction and destruction
+// ----------------------------------------------------------------------------
+
+void wxTreeCtrl::Init()
+{
     m_imageListNormal = NULL;
     m_imageListState = NULL;
     m_textCtrl = NULL;
+}
 
-    m_windowStyle = style;
+bool wxTreeCtrl::Create(wxWindow *parent,
+                        wxWindowID id,
+                        const wxPoint& pos,
+                        const wxSize& size,
+                        long style,
+                        const wxValidator& validator,
+                        const wxString& name)
+{
+    Init();
+
+    if ( !CreateControl(parent, id, pos, size, style, validator, name) )
+        return FALSE;
+// TODO:
+/*
+    DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP |
+                   TVS_HASLINES | TVS_SHOWSELALWAYS;
+
+    if ( m_windowStyle & wxTR_HAS_BUTTONS )
+        wstyle |= TVS_HASBUTTONS;
+
+    if ( m_windowStyle & wxTR_EDIT_LABELS )
+        wstyle |= TVS_EDITLABELS;
+
+    if ( m_windowStyle & wxTR_LINES_AT_ROOT )
+        wstyle |= TVS_LINESATROOT;
+
+    if ( m_windowStyle & wxTR_MULTIPLE )
+        wstyle |= TVS_CHECKBOXES;
+
+    // Create the tree control.
+    if ( !OS2CreateControl(WC_TREEVIEW, wstyle) )
+        return FALSE;
+*/
+    SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
+    SetForegroundColour(wxWindow::GetParent()->GetForegroundColour());
+
+    // VZ: this is some experimental code which may be used to get the
+    //     TVS_CHECKBOXES style functionality for comctl32.dll < 4.71.
+    //     AFAIK, the standard DLL does about the same thing anyhow.
+#if 0
+    if ( m_windowStyle & wxTR_MULTIPLE )
+    {
+        wxBitmap bmp;
+
+        // create the DC compatible with the current screen
+        HDC hdcMem = CreateCompatibleDC(NULL);
+
+        // create a mono bitmap of the standard size
+        int x = GetSystemMetrics(SM_CXMENUCHECK);
+        int y = GetSystemMetrics(SM_CYMENUCHECK);
+        wxImageList imagelistCheckboxes(x, y, FALSE, 2);
+        HBITMAP hbmpCheck = CreateBitmap(x, y,   // bitmap size
+                                         1,      // # of color planes
+                                         1,      // # bits needed for one pixel
+                                         0);     // array containing colour data
+        SelectObject(hdcMem, hbmpCheck);
+
+        // then draw a check mark into it
+        RECT rect = { 0, 0, x, y };
+        if ( !::DrawFrameControl(hdcMem, &rect,
+                                 DFC_BUTTON,
+                                 DFCS_BUTTONCHECK | DFCS_CHECKED) )
+        {
+            wxLogLastError(wxT("DrawFrameControl(check)"));
+        }
+
+        bmp.SetHBITMAP((WXHBITMAP)hbmpCheck);
+        imagelistCheckboxes.Add(bmp);
+
+        if ( !::DrawFrameControl(hdcMem, &rect,
+                                 DFC_BUTTON,
+                                 DFCS_BUTTONCHECK) )
+        {
+            wxLogLastError(wxT("DrawFrameControl(uncheck)"));
+        }
+
+        bmp.SetHBITMAP((WXHBITMAP)hbmpCheck);
+        imagelistCheckboxes.Add(bmp);
+
+        // clean up
+        ::DeleteDC(hdcMem);
+
+        // set the imagelist
+        SetStateImageList(&imagelistCheckboxes);
+    }
+#endif // 0
 
-    SetParent(parent);
+    SetSize(pos.x, pos.y, size.x, size.y);
 
-    m_windowId = (id == -1) ? NewControlId() : id;
+    return TRUE;
+}
 
-    if (parent) parent->AddChild(this);
+wxTreeCtrl::~wxTreeCtrl()
+{
+    DeleteTextCtrl();
 
-    // TODO create tree control
+    // delete user data to prevent memory leaks
+//    DeleteAllItems();
+}
 
-    return FALSE;
+// ----------------------------------------------------------------------------
+// accessors
+// ----------------------------------------------------------------------------
+
+// simple wrappers which add error checking in debug mode
+
+bool wxTreeCtrl::DoGetItem(wxTreeViewItem* tvItem) const
+{
+// TODO:
+/*
+    if ( !TreeView_GetItem(GetHwnd(), tvItem) )
+    {
+        wxLogLastError("TreeView_GetItem");
+
+        return FALSE;
+    }
+*/
+    return TRUE;
 }
 
-wxTreeCtrl::~wxTreeCtrl()
+void wxTreeCtrl::DoSetItem(wxTreeViewItem* tvItem)
 {
-    if (m_textCtrl)
+// TODO:
+/*
+    if ( TreeView_SetItem(GetHwnd(), tvItem) == -1 )
     {
-        delete m_textCtrl;
+        wxLogLastError("TreeView_SetItem");
     }
+*/
 }
 
-// Attributes
-int wxTreeCtrl::GetCount() const
+size_t wxTreeCtrl::GetCount() const
 {
-    // TODO
+//    return (size_t)TreeView_GetCount(GetHwnd());
     return 0;
 }
 
-int wxTreeCtrl::GetIndent() const
+unsigned int wxTreeCtrl::GetIndent() const
 {
-    // TODO
+//    return TreeView_GetIndent(GetHwnd());
     return 0;
 }
 
-void wxTreeCtrl::SetIndent(int indent)
+void wxTreeCtrl::SetIndent(unsigned int indent)
 {
-    // TODO
+//    TreeView_SetIndent(GetHwnd(), indent);
 }
 
-wxImageList *wxTreeCtrl::GetImageList(int which) const
+wxImageList *wxTreeCtrl::GetImageList() const
 {
-  if ( which == wxIMAGE_LIST_NORMAL )
-    {
     return m_imageListNormal;
-  }
-  else if ( which == wxIMAGE_LIST_STATE )
+}
+
+wxImageList *wxTreeCtrl::GetStateImageList() const
+{
+    return m_imageListNormal;
+}
+
+void wxTreeCtrl::SetAnyImageList(wxImageList *imageList, int which)
+{
+    // no error return
+// TODO:
+/*
+    TreeView_SetImageList(GetHwnd(),
+                          imageList ? imageList->GetHIMAGELIST() : 0,
+                          which);
+*/
+}
+
+void wxTreeCtrl::SetImageList(wxImageList *imageList)
+{
+//    SetAnyImageList(m_imageListNormal = imageList, TVSIL_NORMAL);
+}
+
+void wxTreeCtrl::SetStateImageList(wxImageList *imageList)
+{
+//    SetAnyImageList(m_imageListState = imageList, TVSIL_STATE);
+}
+
+size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item,
+                                    bool recursively) const
+{
+    TraverseCounter counter(this, item, recursively);
+
+    return counter.GetCount() - 1;
+}
+
+// ----------------------------------------------------------------------------
+// Item access
+// ----------------------------------------------------------------------------
+
+wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const
+{
+    wxChar buf[512];  // the size is arbitrary...
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_TEXT);
+    tvItem.pszText = buf;
+    tvItem.cchTextMax = WXSIZEOF(buf);
+    if ( !DoGetItem(&tvItem) )
     {
-    return m_imageListState;
-  }
-  return NULL;
+        // don't return some garbage which was on stack, but an empty string
+        buf[0] = wxT('\0');
+    }
+*/
+    return wxString(buf);
+}
+
+void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text)
+{
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_TEXT);
+    tvItem.pszText = (wxChar *)text.c_str();  // conversion is ok
+    DoSetItem(&tvItem);
+*/
 }
 
-void wxTreeCtrl::SetImageList(wxImageList *imageList, int which)
+int wxTreeCtrl::DoGetItemImageFromData(const wxTreeItemId& item,
+                                       wxTreeItemIcon which) const
 {
-    if ( which == wxIMAGE_LIST_NORMAL )
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_PARAM);
+    if ( !DoGetItem(&tvItem) )
     {
-        m_imageListNormal = imageList;
+        return -1;
     }
-    else if ( which == wxIMAGE_LIST_STATE )
+    return ((wxTreeItemIndirectData *)tvItem.lParam)->GetImage(which);
+*/
+    return -1;
+}
+
+void wxTreeCtrl::DoSetItemImageFromData(const wxTreeItemId& item,
+                                        int image,
+                                        wxTreeItemIcon which) const
+{
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_PARAM);
+    if ( !DoGetItem(&tvItem) )
     {
-        m_imageListState = imageList;
+        return;
     }
-    // TODO
+
+    wxTreeItemIndirectData *data = ((wxTreeItemIndirectData *)tvItem.lParam);
+
+    data->SetImage(image, which);
+
+    // make sure that we have selected images as well
+    if ( which == wxTreeItemIcon_Normal &&
+         !data->HasImage(wxTreeItemIcon_Selected) )
+    {
+        data->SetImage(image, wxTreeItemIcon_Selected);
+    }
+
+    if ( which == wxTreeItemIcon_Expanded &&
+         !data->HasImage(wxTreeItemIcon_SelectedExpanded) )
+    {
+        data->SetImage(image, wxTreeItemIcon_SelectedExpanded);
+    }
+*/
 }
 
-long wxTreeCtrl::GetNextItem(long item, int code) const
+void wxTreeCtrl::DoSetItemImages(const wxTreeItemId& item,
+                                 int image,
+                                 int imageSel)
 {
-    // TODO
-    return 0;
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_IMAGE | TVIF_SELECTEDIMAGE);
+    tvItem.iSelectedImage = imageSel;
+    tvItem.iImage = image;
+    DoSetItem(&tvItem);
+*/
 }
 
-bool wxTreeCtrl::ItemHasChildren(long item) const
+int wxTreeCtrl::GetItemImage(const wxTreeItemId& item,
+                             wxTreeItemIcon which) const
 {
-    // TODO
+    if ( HasIndirectData(item) )
+    {
+        return DoGetItemImageFromData(item, which);
+    }
+
+    UINT mask;
+    switch ( which )
+    {
+        default:
+            wxFAIL_MSG( wxT("unknown tree item image type") );
+
+        case wxTreeItemIcon_Normal:
+//            mask = TVIF_IMAGE;
+            break;
+
+        case wxTreeItemIcon_Selected:
+//            mask = TVIF_SELECTEDIMAGE;
+            break;
+
+        case wxTreeItemIcon_Expanded:
+        case wxTreeItemIcon_SelectedExpanded:
+            return -1;
+    }
+
+    wxTreeViewItem tvItem(item, mask);
+    DoGetItem(&tvItem);
+
+//    return mask == TVIF_IMAGE ? tvItem.iImage : tvItem.iSelectedImage;
     return FALSE;
 }
 
-long wxTreeCtrl::GetChild(long item) const
+void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image,
+                              wxTreeItemIcon which)
 {
-    // TODO
-    return 0;
+    int imageNormal, imageSel;
+    switch ( which )
+    {
+        default:
+            wxFAIL_MSG( wxT("unknown tree item image type") );
+
+        case wxTreeItemIcon_Normal:
+            imageNormal = image;
+            imageSel = GetItemSelectedImage(item);
+            break;
+
+        case wxTreeItemIcon_Selected:
+            imageNormal = GetItemImage(item);
+            imageSel = image;
+            break;
+
+        case wxTreeItemIcon_Expanded:
+        case wxTreeItemIcon_SelectedExpanded:
+            if ( !HasIndirectData(item) )
+            {
+                // we need to get the old images first, because after we create
+                // the wxTreeItemIndirectData GetItemXXXImage() will use it to
+                // get the images
+                imageNormal = GetItemImage(item);
+                imageSel = GetItemSelectedImage(item);
+
+                // if it doesn't have it yet, add it
+                wxTreeItemIndirectData *data = new
+                    wxTreeItemIndirectData(this, item);
+
+                // copy the data to the new location
+                data->SetImage(imageNormal, wxTreeItemIcon_Normal);
+                data->SetImage(imageSel, wxTreeItemIcon_Selected);
+            }
+
+            DoSetItemImageFromData(item, image, which);
+
+            // reset the normal/selected images because we won't use them any
+            // more - now they're stored inside the indirect data
+//            imageSel = I_IMAGECALLBACK;
+            break;
+    }
+
+    // NB: at least in version 5.00.0518.9 of comctl32.dll we need to always
+    //     change both normal and selected image - otherwise the change simply
+    //     doesn't take place!
+    DoSetItemImages(item, imageNormal, imageSel);
 }
 
-long wxTreeCtrl::GetParent(long item) const
+wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
 {
-    // TODO
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_PARAM);
+    if ( !DoGetItem(&tvItem) )
+    {
+        return NULL;
+    }
+
+    if ( HasIndirectData(item) )
+    {
+        return ((wxTreeItemIndirectData *)tvItem.lParam)->GetData();
+    }
+    else
+    {
+        return (wxTreeItemData *)tvItem.lParam;
+    }
+*/
     return 0;
 }
 
-long wxTreeCtrl::GetFirstVisibleItem() const
+void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
 {
-    // TODO
-    return 0;
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_PARAM);
+
+    if ( HasIndirectData(item) )
+    {
+        if ( DoGetItem(&tvItem) )
+        {
+            ((wxTreeItemIndirectData *)tvItem.lParam)->SetData(data);
+        }
+        else
+        {
+            wxFAIL_MSG( wxT("failed to change tree items data") );
+        }
+    }
+    else
+    {
+        tvItem.lParam = (MPARAM)data;
+        DoSetItem(&tvItem);
+    }
+*/
 }
 
-long wxTreeCtrl::GetNextVisibleItem(long item) const
+void wxTreeCtrl::SetIndirectItemData(const wxTreeItemId& item,
+                                     wxTreeItemIndirectData *data)
 {
-    // TODO
-    return 0;
+    // this should never happen because it's unnecessary and will probably lead
+    // to crash too because the code elsewhere supposes that the pointer the
+    // wxTreeItemIndirectData has is a real wxItemData and not
+    // wxTreeItemIndirectData as well
+    wxASSERT_MSG( !HasIndirectData(item), wxT("setting indirect data twice?") );
+
+    SetItemData(item, (wxTreeItemData *)data);
+
+    m_itemsWithIndirectData.Add(item);
 }
 
-long wxTreeCtrl::GetSelection() const
+bool wxTreeCtrl::HasIndirectData(const wxTreeItemId& item) const
 {
-    // TODO
-    return 0;
+    return m_itemsWithIndirectData.Index(item) != wxNOT_FOUND;
 }
 
-long wxTreeCtrl::GetRootItem() const
+void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
 {
-    // TODO
-    return 0;
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_CHILDREN);
+    tvItem.cChildren = (int)has;
+    DoSetItem(&tvItem);
+*/
+}
+
+void wxTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold)
+{
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_BOLD);
+    tvItem.state = bold ? TVIS_BOLD : 0;
+    DoSetItem(&tvItem);
+*/
+}
+
+void wxTreeCtrl::SetItemDropHighlight(const wxTreeItemId& item, bool highlight)
+{
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_DROPHILITED);
+    tvItem.state = highlight ? TVIS_DROPHILITED : 0;
+    DoSetItem(&tvItem);
+*/
 }
 
-bool wxTreeCtrl::GetItem(wxTreeItem& info) const
+// ----------------------------------------------------------------------------
+// Item status
+// ----------------------------------------------------------------------------
+
+bool wxTreeCtrl::IsVisible(const wxTreeItemId& item) const
 {
-    // TODO
+    // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect
+// TODO:
+/*
+    RECT rect;
+    return SendMessage(GetHwnd(), TVM_GETITEMRECT, FALSE, (LPARAM)&rect) != 0;
+*/
     return FALSE;
 }
 
-bool wxTreeCtrl::SetItem(wxTreeItem& info)
+bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const
 {
-    // TODO
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_CHILDREN);
+    DoGetItem(&tvItem);
+
+    return tvItem.cChildren != 0;
+*/
     return FALSE;
 }
 
-int wxTreeCtrl::GetItemState(long item, long stateMask) const
+bool wxTreeCtrl::IsExpanded(const wxTreeItemId& item) const
 {
-    wxTreeItem info;
+    // probably not a good idea to put it here
+    //wxASSERT( ItemHasChildren(item) );
 
-    info.m_mask = wxTREE_MASK_STATE ;
-    info.m_stateMask = stateMask;
-    info.m_itemId = item;
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_EXPANDED);
+    DoGetItem(&tvItem);
 
-    if (!GetItem(info))
-        return 0;
+    return (tvItem.state & TVIS_EXPANDED) != 0;
+*/
+    return FALSE;
+}
 
-    return info.m_state;
+bool wxTreeCtrl::IsSelected(const wxTreeItemId& item) const
+{
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_SELECTED);
+    DoGetItem(&tvItem);
+
+    return (tvItem.state & TVIS_SELECTED) != 0;
+*/
+    return FALSE;
 }
 
-bool wxTreeCtrl::SetItemState(long item, long state, long stateMask)
+bool wxTreeCtrl::IsBold(const wxTreeItemId& item) const
 {
-    wxTreeItem info;
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_BOLD);
+    DoGetItem(&tvItem);
 
-    info.m_mask = wxTREE_MASK_STATE ;
-    info.m_state = state;
-    info.m_stateMask = stateMask;
-    info.m_itemId = item;
+    return (tvItem.state & TVIS_BOLD) != 0;
+*/
+    return FALSE;
+}
 
-    return SetItem(info);
+// ----------------------------------------------------------------------------
+// navigation
+// ----------------------------------------------------------------------------
+
+wxTreeItemId wxTreeCtrl::GetRootItem() const
+{
+//    return wxTreeItemId((WXHTREEITEM) TreeView_GetRoot(GetHwnd()));
+    return 0;
 }
 
-bool wxTreeCtrl::SetItemImage(long item, int image, int selImage)
+wxTreeItemId wxTreeCtrl::GetSelection() const
 {
-    wxTreeItem info;
+    wxCHECK_MSG( !(m_windowStyle & wxTR_MULTIPLE), (WXHTREEITEM)0,
+                 wxT("this only works with single selection controls") );
 
-    info.m_mask = wxTREE_MASK_IMAGE ;
-    info.m_image = image;
-    if ( selImage > -1)
-    {
-        info.m_selectedImage = selImage;
-        info.m_mask |= wxTREE_MASK_SELECTED_IMAGE;
-    }
-    info.m_itemId = item;
+//    return wxTreeItemId((WXHTREEITEM) TreeView_GetSelection(GetHwnd()));
+    return 0;
+}
 
-    return SetItem(info);
+wxTreeItemId wxTreeCtrl::GetParent(const wxTreeItemId& item) const
+{
+//    return wxTreeItemId((WXHTREEITEM) TreeView_GetParent(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
+    return 0;
 }
 
-wxString wxTreeCtrl::GetItemText(long item) const
+wxTreeItemId wxTreeCtrl::GetFirstChild(const wxTreeItemId& item,
+                                       long& _cookie) const
 {
-    wxTreeItem info;
+// TODO:
+/*
+    // remember the last child returned in 'cookie'
+    _cookie = (long)TreeView_GetChild(GetHwnd(), (HTREEITEM) (WXHTREEITEM)item);
+
+    return wxTreeItemId((WXHTREEITEM)_cookie);
+*/
+    return 0;
+}
 
-    info.m_mask = wxTREE_MASK_TEXT ;
-    info.m_itemId = item;
+wxTreeItemId wxTreeCtrl::GetNextChild(const wxTreeItemId& WXUNUSED(item),
+                                      long& _cookie) const
+{
+    wxTreeItemId l = 0; //wxTreeItemId((WXHTREEITEM)TreeView_GetNextSibling(GetHwnd(),
+//                                   (HTREEITEM)(WXHTREEITEM)_cookie));
+    _cookie = (long)l;
 
-    if (!GetItem(info))
-        return wxString("");
-    return info.m_text;
+    return l;
 }
 
-void wxTreeCtrl::SetItemText(long item, const wxString& str)
+wxTreeItemId wxTreeCtrl::GetLastChild(const wxTreeItemId& item) const
 {
-    wxTreeItem info;
+    // can this be done more efficiently?
+    long cookie;
 
-    info.m_mask = wxTREE_MASK_TEXT ;
-    info.m_itemId = item;
-    info.m_text = str;
+    wxTreeItemId childLast,
+    child = GetFirstChild(item, cookie);
+    while ( child.IsOk() )
+    {
+        childLast = child;
+        child = GetNextChild(item, cookie);
+    }
 
-    SetItem(info);
+    return childLast;
 }
 
-long wxTreeCtrl::GetItemData(long item) const
+wxTreeItemId wxTreeCtrl::GetNextSibling(const wxTreeItemId& item) const
 {
-    wxTreeItem info;
+//    return wxTreeItemId((WXHTREEITEM) TreeView_GetNextSibling(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
+    return 0;
+}
 
-    info.m_mask = wxTREE_MASK_DATA ;
-    info.m_itemId = item;
+wxTreeItemId wxTreeCtrl::GetPrevSibling(const wxTreeItemId& item) const
+{
+//    return wxTreeItemId((WXHTREEITEM) TreeView_GetPrevSibling(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
+    return 0;
+}
 
-    if (!GetItem(info))
-        return 0;
-    return info.m_data;
+wxTreeItemId wxTreeCtrl::GetFirstVisibleItem() const
+{
+//     return wxTreeItemId((WXHTREEITEM) TreeView_GetFirstVisible(GetHwnd()));
+    return 0;
 }
 
-bool wxTreeCtrl::SetItemData(long item, long data)
+wxTreeItemId wxTreeCtrl::GetNextVisible(const wxTreeItemId& item) const
 {
-    wxTreeItem info;
+    wxASSERT_MSG( IsVisible(item), wxT("The item you call GetNextVisible() "
+                                      "for must be visible itself!"));
+
+//    return wxTreeItemId((WXHTREEITEM) TreeView_GetNextVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
+    return 0;
+}
 
-    info.m_mask = wxTREE_MASK_DATA ;
-    info.m_itemId = item;
-    info.m_data = data;
+wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const
+{
+    wxASSERT_MSG( IsVisible(item), wxT("The item you call GetPrevVisible() "
+                                      "for must be visible itself!"));
 
-    return SetItem(info);
+//    return wxTreeItemId((WXHTREEITEM) TreeView_GetPrevVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
+     return 0;
 }
 
-bool wxTreeCtrl::GetItemRect(long item, wxRect& rect, bool textOnly) const
+// ----------------------------------------------------------------------------
+// multiple selections emulation
+// ----------------------------------------------------------------------------
+
+bool wxTreeCtrl::IsItemChecked(const wxTreeItemId& item) const
 {
-    // TODO
+    // receive the desired information.
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
+    DoGetItem(&tvItem);
+
+    // state image indices are 1 based
+    return ((tvItem.state >> 12) - 1) == 1;
+*/
     return FALSE;
 }
 
-wxTextCtrl* wxTreeCtrl::GetEditControl() const
+void wxTreeCtrl::SetItemCheck(const wxTreeItemId& item, bool check)
 {
-    return m_textCtrl;
+    // receive the desired information.
+// TODO:
+/*
+    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
+
+    // state images are one-based
+    tvItem.state = (check ? 2 : 1) << 12;
+
+    DoSetItem(&tvItem);
+*/
 }
 
-// Operations
-bool wxTreeCtrl::DeleteItem(long item)
+size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const
 {
-    // TODO
-    return FALSE;
+    TraverseSelections selector(this, selections);
+
+    return selections.GetCount();
 }
 
-bool wxTreeCtrl::ExpandItem(long item, int action)
+// ----------------------------------------------------------------------------
+// Usual operations
+// ----------------------------------------------------------------------------
+
+wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent,
+                                      wxTreeItemId hInsertAfter,
+                                      const wxString& text,
+                                      int image, int selectedImage,
+                                      wxTreeItemData *data)
 {
-    // TODO
-  switch ( action )
-  {
-    case wxTREE_EXPAND_EXPAND:
-      break;
+// TODO:
+/*
+    TV_INSERTSTRUCT tvIns;
+    tvIns.hParent = (HTREEITEM) (WXHTREEITEM)parent;
+    tvIns.hInsertAfter = (HTREEITEM) (WXHTREEITEM) hInsertAfter;
+
+    // this is how we insert the item as the first child: supply a NULL
+    // hInsertAfter
+    if ( !tvIns.hInsertAfter )
+    {
+        tvIns.hInsertAfter = TVI_FIRST;
+    }
 
-    case wxTREE_EXPAND_COLLAPSE:
-      break;
+    UINT mask = 0;
+    if ( !text.IsEmpty() )
+    {
+        mask |= TVIF_TEXT;
+        tvIns.item.pszText = (wxChar *)text.c_str();  // cast is ok
+    }
 
-    case wxTREE_EXPAND_COLLAPSE_RESET:
-      break;
+    if ( image != -1 )
+    {
+        mask |= TVIF_IMAGE;
+        tvIns.item.iImage = image;
+
+        if ( selectedImage == -1 )
+        {
+            // take the same image for selected icon if not specified
+            selectedImage = image;
+        }
+    }
 
-    case wxTREE_EXPAND_TOGGLE:
-      break;
+    if ( selectedImage != -1 )
+    {
+        mask |= TVIF_SELECTEDIMAGE;
+        tvIns.item.iSelectedImage = selectedImage;
+    }
 
-    default:
-      wxFAIL_MSG("unknown action in wxTreeCtrl::ExpandItem");
-  }
+    if ( data != NULL )
+    {
+        mask |= TVIF_PARAM;
+        tvIns.item.lParam = (LPARAM)data;
+    }
 
-  bool bOk = FALSE; // TODO expand item
+    tvIns.item.mask = mask;
 
-  // May not send messages, so emulate them
-  if ( bOk ) {
-    wxTreeEvent event(wxEVT_NULL, m_windowId);
-    event.m_item.m_itemId  = item;
-    event.m_item.m_mask      =
-    event.m_item.m_stateMask = 0xffff; // get all
-    GetItem(event.m_item);
+    HTREEITEM id = (HTREEITEM) TreeView_InsertItem(GetHwnd(), &tvIns);
+    if ( id == 0 )
+    {
+        wxLogLastError("TreeView_InsertItem");
+    }
+
+    if ( data != NULL )
+    {
+        // associate the application tree item with Win32 tree item handle
+        data->SetId((WXHTREEITEM)id);
+    }
 
-    bool bIsExpanded = (event.m_item.m_state & wxTREE_STATE_EXPANDED) != 0;
+    return wxTreeItemId((WXHTREEITEM)id);
+*/
+    return 0;
+}
 
-    event.m_code = action;
-    event.SetEventObject(this);
+// for compatibility only
+wxTreeItemId wxTreeCtrl::InsertItem(const wxTreeItemId& parent,
+                                    const wxString& text,
+                                    int image, int selImage,
+                                    long insertAfter)
+{
+    return DoInsertItem(parent, (WXHTREEITEM)insertAfter, text,
+                        image, selImage, NULL);
+}
 
-    // @@@ return values of {EXPAND|COLLAPS}ING event handler is discarded
-    event.SetEventType(bIsExpanded ? wxEVT_COMMAND_TREE_ITEM_EXPANDING
-                                   : wxEVT_COMMAND_TREE_ITEM_COLLAPSING);
-    GetEventHandler()->ProcessEvent(event);
+wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text,
+                                 int image, int selectedImage,
+                                 wxTreeItemData *data)
+{
+    return DoInsertItem(wxTreeItemId((WXHTREEITEM) 0), (WXHTREEITEM) 0,
+                        text, image, selectedImage, data);
+}
 
-    event.SetEventType(bIsExpanded ? wxEVT_COMMAND_TREE_ITEM_EXPANDED
-                                   : wxEVT_COMMAND_TREE_ITEM_COLLAPSED);
-    GetEventHandler()->ProcessEvent(event);
-  }
+wxTreeItemId wxTreeCtrl::PrependItem(const wxTreeItemId& parent,
+                                     const wxString& text,
+                                     int image, int selectedImage,
+                                     wxTreeItemData *data)
+{
+// TODO:
+/*
+    return DoInsertItem(parent, (WXHTREEITEM) TVI_FIRST,
+                        text, image, selectedImage, data);
+*/
+    return 0;
+}
 
-  return bOk;
+wxTreeItemId wxTreeCtrl::InsertItem(const wxTreeItemId& parent,
+                                    const wxTreeItemId& idPrevious,
+                                    const wxString& text,
+                                    int image, int selectedImage,
+                                    wxTreeItemData *data)
+{
+    return DoInsertItem(parent, idPrevious, text, image, selectedImage, data);
 }
 
-long wxTreeCtrl::InsertItem(long parent, wxTreeItem& info, long insertAfter)
+wxTreeItemId wxTreeCtrl::AppendItem(const wxTreeItemId& parent,
+                                    const wxString& text,
+                                    int image, int selectedImage,
+                                    wxTreeItemData *data)
 {
-    // TODO
+// TODO:
+/*
+    return DoInsertItem(parent, (WXHTREEITEM) TVI_LAST,
+                        text, image, selectedImage, data);
+*/
     return 0;
 }
 
-long wxTreeCtrl::InsertItem(long parent, const wxString& label, int image, int selImage,
-  long insertAfter)
+void wxTreeCtrl::Delete(const wxTreeItemId& item)
 {
-    wxTreeItem info;
-    info.m_text = label;
-    info.m_mask = wxTREE_MASK_TEXT;
-    if ( image > -1 )
+// TODO:
+/*
+    if ( !TreeView_DeleteItem(GetHwnd(), (HTREEITEM)(WXHTREEITEM)item) )
     {
-        info.m_mask |= wxTREE_MASK_IMAGE | wxTREE_MASK_SELECTED_IMAGE;
-        info.m_image = image;
-        if ( selImage == -1 )
-            info.m_selectedImage = image;
-        else
-            info.m_selectedImage = selImage;
+        wxLogLastError("TreeView_DeleteItem");
+    }
+*/
+}
+
+// delete all children (but don't delete the item itself)
+void wxTreeCtrl::DeleteChildren(const wxTreeItemId& item)
+{
+    long cookie;
+
+    wxArrayLong children;
+    wxTreeItemId child = GetFirstChild(item, cookie);
+    while ( child.IsOk() )
+    {
+        children.Add((long)(WXHTREEITEM)child);
+
+        child = GetNextChild(item, cookie);
     }
 
-    return InsertItem(parent, info, insertAfter);
+    size_t nCount = children.Count();
+// TODO:
+/*
+    for ( size_t n = 0; n < nCount; n++ )
+    {
+        if ( !TreeView_DeleteItem(GetHwnd(), (HTREEITEM)children[n]) )
+        {
+            wxLogLastError("TreeView_DeleteItem");
+        }
+    }
+*/
 }
 
-bool wxTreeCtrl::SelectItem(long item)
+void wxTreeCtrl::DeleteAllItems()
 {
-    // TODO
-    return FALSE;
+// TODO:
+/*
+    if ( !TreeView_DeleteAllItems(GetHwnd()) )
+    {
+        wxLogLastError("TreeView_DeleteAllItems");
+    }
+*/
 }
 
-bool wxTreeCtrl::ScrollTo(long item)
+void wxTreeCtrl::DoExpand(const wxTreeItemId& item, int flag)
 {
-    // TODO
-    return FALSE;
+// TODO:
+/*
+    wxASSERT_MSG( flag == TVE_COLLAPSE ||
+                  flag == (TVE_COLLAPSE | TVE_COLLAPSERESET) ||
+                  flag == TVE_EXPAND   ||
+                  flag == TVE_TOGGLE,
+                  wxT("Unknown flag in wxTreeCtrl::DoExpand") );
+
+    // TreeView_Expand doesn't send TVN_ITEMEXPAND(ING) messages, so we must
+    // emulate them. This behaviour has changed slightly with comctl32.dll
+    // v 4.70 - now it does send them but only the first time. To maintain
+    // compatible behaviour and also in order to not have surprises with the
+    // future versions, don't rely on this and still do everything ourselves.
+    // To avoid that the messages be sent twice when the item is expanded for
+    // the first time we must clear TVIS_EXPANDEDONCE style manually.
+
+    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_EXPANDEDONCE);
+    tvItem.state = 0;
+    DoSetItem(&tvItem);
+
+    if ( TreeView_Expand(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item, flag) != 0 )
+    {
+        wxTreeEvent event(wxEVT_NULL, m_windowId);
+        event.m_item = item;
+
+        bool isExpanded = IsExpanded(item);
+
+        event.SetEventObject(this);
+
+        // FIXME return value of {EXPAND|COLLAPS}ING event handler is discarded
+        event.SetEventType(g_events[isExpanded][TRUE]);
+        GetEventHandler()->ProcessEvent(event);
+
+        event.SetEventType(g_events[isExpanded][FALSE]);
+        GetEventHandler()->ProcessEvent(event);
+    }
+    //else: change didn't took place, so do nothing at all
+*/
 }
 
-bool wxTreeCtrl::DeleteAllItems()
+void wxTreeCtrl::Expand(const wxTreeItemId& item)
 {
-    // TODO
-    return FALSE;
+//    DoExpand(item, TVE_EXPAND);
 }
 
-wxTextCtrl* wxTreeCtrl::EditLabel(long item, wxClassInfo* textControlClass)
+void wxTreeCtrl::Collapse(const wxTreeItemId& item)
 {
-    // TODO
-    return NULL;
+//    DoExpand(item, TVE_COLLAPSE);
+}
+
+void wxTreeCtrl::CollapseAndReset(const wxTreeItemId& item)
+{
+//    DoExpand(item, TVE_COLLAPSE | TVE_COLLAPSERESET);
+}
+
+void wxTreeCtrl::Toggle(const wxTreeItemId& item)
+{
+//    DoExpand(item, TVE_TOGGLE);
+}
+
+void wxTreeCtrl::ExpandItem(const wxTreeItemId& item, int action)
+{
+//    DoExpand(item, action);
+}
+
+void wxTreeCtrl::Unselect()
+{
+    wxASSERT_MSG( !(m_windowStyle & wxTR_MULTIPLE), wxT("doesn't make sense") );
+
+    // just remove the selection
+//    SelectItem(wxTreeItemId((WXHTREEITEM) 0));
+}
+
+void wxTreeCtrl::UnselectAll()
+{
+    if ( m_windowStyle & wxTR_MULTIPLE )
+    {
+        wxArrayTreeItemIds selections;
+        size_t count = GetSelections(selections);
+        for ( size_t n = 0; n < count; n++ )
+        {
+            SetItemCheck(selections[n], FALSE);
+        }
+    }
+    else
+    {
+        // just remove the selection
+        Unselect();
+    }
+}
+
+void wxTreeCtrl::SelectItem(const wxTreeItemId& item)
+{
+    if ( m_windowStyle & wxTR_MULTIPLE )
+    {
+        // selecting the item means checking it
+        SetItemCheck(item);
+    }
+    else
+    {
+        // inspite of the docs (MSDN Jan 99 edition), we don't seem to receive
+        // the notification from the control (i.e. TVN_SELCHANG{ED|ING}), so
+        // send them ourselves
+
+        wxTreeEvent event(wxEVT_NULL, m_windowId);
+        event.m_item = item;
+        event.SetEventObject(this);
+
+        event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGING);
+// TODO:
+/*
+        if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
+        {
+            if ( !TreeView_SelectItem(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item) )
+            {
+                wxLogLastError("TreeView_SelectItem");
+            }
+            else
+            {
+                event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED);
+                (void)GetEventHandler()->ProcessEvent(event);
+            }
+        }
+        //else: program vetoed the change
+*/
+    }
+}
+
+void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item)
+{
+    // no error return
+//    TreeView_EnsureVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item);
+}
+
+void wxTreeCtrl::ScrollTo(const wxTreeItemId& item)
+{
+// TODO:
+/*
+    if ( !TreeView_SelectSetFirstVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item) )
+    {
+        wxLogLastError("TreeView_SelectSetFirstVisible");
+    }
+*/
+}
+
+wxTextCtrl* wxTreeCtrl::GetEditControl() const
+{
+    return m_textCtrl;
+}
+
+void wxTreeCtrl::DeleteTextCtrl()
+{
+    if ( m_textCtrl )
+    {
+        m_textCtrl->UnsubclassWin();
+        m_textCtrl->SetHWND(0);
+        delete m_textCtrl;
+        m_textCtrl = NULL;
+    }
+}
+
+wxTextCtrl* wxTreeCtrl::EditLabel(const wxTreeItemId& item,
+                                  wxClassInfo* textControlClass)
+{
+    wxASSERT( textControlClass->IsKindOf(CLASSINFO(wxTextCtrl)) );
+
+// TODO:
+/*
+    HWND hWnd = (HWND) TreeView_EditLabel(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item);
+
+    // this is not an error - the TVN_BEGINLABELEDIT handler might have
+    // returned FALSE
+    if ( !hWnd )
+    {
+        return NULL;
+    }
+
+    DeleteTextCtrl();
+
+    m_textCtrl = (wxTextCtrl *)textControlClass->CreateObject();
+    m_textCtrl->SetHWND((WXHWND)hWnd);
+    m_textCtrl->SubclassWin((WXHWND)hWnd);
+*/
+    return m_textCtrl;
 }
 
 // End label editing, optionally cancelling the edit
-bool wxTreeCtrl::EndEditLabel(bool cancel)
+void wxTreeCtrl::EndEditLabel(const wxTreeItemId& item, bool discardChanges)
 {
-    // TODO
-    return FALSE;
+//    TreeView_EndEditLabelNow(GetHwnd(), discardChanges);
+
+    DeleteTextCtrl();
 }
 
-long wxTreeCtrl::HitTest(const wxPoint& point, int& flags)
+wxTreeItemId wxTreeCtrl::HitTest(const wxPoint& point, int& flags)
 {
-    // TODO
+// TODO:
+/*
+    TV_HITTESTINFO hitTestInfo;
+    hitTestInfo.pt.x = (int)point.x;
+    hitTestInfo.pt.y = (int)point.y;
+
+    TreeView_HitTest(GetHwnd(), &hitTestInfo);
+
+    flags = 0;
+
+    // avoid repetition
+    #define TRANSLATE_FLAG(flag) if ( hitTestInfo.flags & TVHT_##flag ) \
+                                    flags |= wxTREE_HITTEST_##flag
+
+    TRANSLATE_FLAG(ABOVE);
+    TRANSLATE_FLAG(BELOW);
+    TRANSLATE_FLAG(NOWHERE);
+    TRANSLATE_FLAG(ONITEMBUTTON);
+    TRANSLATE_FLAG(ONITEMICON);
+    TRANSLATE_FLAG(ONITEMINDENT);
+    TRANSLATE_FLAG(ONITEMLABEL);
+    TRANSLATE_FLAG(ONITEMRIGHT);
+    TRANSLATE_FLAG(ONITEMSTATEICON);
+    TRANSLATE_FLAG(TOLEFT);
+    TRANSLATE_FLAG(TORIGHT);
+
+    #undef TRANSLATE_FLAG
+
+    return wxTreeItemId((WXHTREEITEM) hitTestInfo.hItem);
+*/
     return 0;
 }
 
-bool wxTreeCtrl::SortChildren(long item)
+bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item,
+                                 wxRect& rect,
+                                 bool textOnly) const
 {
-    // TODO
+// TODO:
+/*
+    RECT rc;
+    if ( TreeView_GetItemRect(GetHwnd(), (HTREEITEM)(WXHTREEITEM)item,
+                              &rc, textOnly) )
+    {
+        rect = wxRect(wxPoint(rc.left, rc.top), wxPoint(rc.right, rc.bottom));
+
+        return TRUE;
+    }
+    else
+    {
+        // couldn't retrieve rect: for example, item isn't visible
+        return FALSE;
+    }
+*/
     return FALSE;
 }
 
-bool wxTreeCtrl::EnsureVisible(long item)
+// ----------------------------------------------------------------------------
+// sorting stuff
+// ----------------------------------------------------------------------------
+
+static int TreeView_CompareCallback(wxTreeItemData *pItem1,
+                                    wxTreeItemData *pItem2,
+                                    wxTreeCtrl *tree)
+{
+    wxCHECK_MSG( pItem1 && pItem2, 0,
+                 wxT("sorting tree without data doesn't make sense") );
+
+    return tree->OnCompareItems(pItem1->GetId(), pItem2->GetId());
+}
+
+int wxTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
+                               const wxTreeItemId& item2)
+{
+    return wxStrcmp(GetItemText(item1), GetItemText(item2));
+}
+
+void wxTreeCtrl::SortChildren(const wxTreeItemId& item)
+{
+    // rely on the fact that TreeView_SortChildren does the same thing as our
+    // default behaviour, i.e. sorts items alphabetically and so call it
+    // directly if we're not in derived class (much more efficient!)
+// TODO:
+/*
+    if ( GetClassInfo() == CLASSINFO(wxTreeCtrl) )
+    {
+        TreeView_SortChildren(GetHwnd(), (HTREEITEM)(WXHTREEITEM)item, 0);
+    }
+    else
+    {
+        TV_SORTCB tvSort;
+        tvSort.hParent = (HTREEITEM)(WXHTREEITEM)item;
+        tvSort.lpfnCompare = (PFNTVCOMPARE)TreeView_CompareCallback;
+        tvSort.lParam = (LPARAM)this;
+        TreeView_SortChildrenCB(GetHwnd(), &tvSort, 0);
+    }
+*/
+}
+
+// ----------------------------------------------------------------------------
+// implementation
+// ----------------------------------------------------------------------------
+
+bool wxTreeCtrl::OS2Command(WXUINT cmd, WXWORD id)
 {
-    // TODO
+// TODO:
+/*
+    if ( cmd == EN_UPDATE )
+    {
+        wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, id);
+        event.SetEventObject( this );
+        ProcessCommand(event);
+    }
+    else if ( cmd == EN_KILLFOCUS )
+    {
+        wxCommandEvent event(wxEVT_KILL_FOCUS, id);
+        event.SetEventObject( this );
+        ProcessCommand(event);
+    }
+    else
+    {
+        // nothing done
+        return FALSE;
+    }
+
+    // command processed
+    return TRUE;
+*/
     return FALSE;
 }
 
-// Tree item structure
-wxTreeItem::wxTreeItem()
+// process WM_NOTIFY Windows message
+bool wxTreeCtrl::OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
-    m_mask = 0;
-    m_itemId = 0;
-    m_state = 0;
-    m_stateMask = 0;
-    m_image = -1;
-    m_selectedImage = -1;
-    m_children = 0;
-    m_data = 0;
+// TODO:
+/*
+    wxTreeEvent event(wxEVT_NULL, m_windowId);
+    wxEventType eventType = wxEVT_NULL;
+    NMHDR *hdr = (NMHDR *)lParam;
+
+    switch ( hdr->code )
+    {
+        case NM_RCLICK:
+        {
+            if ( wxControl::MSWOnNotify(idCtrl, lParam, result) )
+                return TRUE;
+
+            TV_HITTESTINFO tvhti;
+            ::GetCursorPos(&(tvhti.pt));
+            ::ScreenToClient(GetHwnd(),&(tvhti.pt));
+            if ( TreeView_HitTest(GetHwnd(),&tvhti) )
+            {
+                if( tvhti.flags & TVHT_ONITEM )
+                {
+                    event.m_item = (WXHTREEITEM) tvhti.hItem;
+                    eventType=wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK;
+                }
+            }
+            break;
+        }
+
+        case TVN_BEGINDRAG:
+            eventType = wxEVT_COMMAND_TREE_BEGIN_DRAG;
+            // fall through
+
+        case TVN_BEGINRDRAG:
+            {
+                if ( eventType == wxEVT_NULL )
+                    eventType = wxEVT_COMMAND_TREE_BEGIN_RDRAG;
+                //else: left drag, already set above
+
+                NM_TREEVIEW *tv = (NM_TREEVIEW *)lParam;
+
+                event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
+                event.m_pointDrag = wxPoint(tv->ptDrag.x, tv->ptDrag.y);
+                break;
+            }
+
+        case TVN_BEGINLABELEDIT:
+            {
+                eventType = wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT;
+                TV_DISPINFO *info = (TV_DISPINFO *)lParam;
+
+                event.m_item = (WXHTREEITEM) info->item.hItem;
+                event.m_label = info->item.pszText;
+                break;
+            }
+
+        case TVN_DELETEITEM:
+            {
+                eventType = wxEVT_COMMAND_TREE_DELETE_ITEM;
+                NM_TREEVIEW *tv = (NM_TREEVIEW *)lParam;
+
+                event.m_item = (WXHTREEITEM) tv->itemOld.hItem;
+                break;
+            }
+
+        case TVN_ENDLABELEDIT:
+            {
+                eventType = wxEVT_COMMAND_TREE_END_LABEL_EDIT;
+                TV_DISPINFO *info = (TV_DISPINFO *)lParam;
+
+                event.m_item = (WXHTREEITEM)info->item.hItem;
+                event.m_label = info->item.pszText;
+                break;
+            }
+
+        case TVN_GETDISPINFO:
+            eventType = wxEVT_COMMAND_TREE_GET_INFO;
+            // fall through
+
+        case TVN_SETDISPINFO:
+            {
+                if ( eventType == wxEVT_NULL )
+                    eventType = wxEVT_COMMAND_TREE_SET_INFO;
+                //else: get, already set above
+
+                TV_DISPINFO *info = (TV_DISPINFO *)lParam;
+
+                event.m_item = (WXHTREEITEM) info->item.hItem;
+                break;
+            }
+
+        case TVN_ITEMEXPANDING:
+            event.m_code = FALSE;
+            // fall through
+
+        case TVN_ITEMEXPANDED:
+            {
+                NM_TREEVIEW* tv = (NM_TREEVIEW*)lParam;
+
+                bool expand = FALSE;
+                switch ( tv->action )
+                {
+                    case TVE_EXPAND:
+                        expand = TRUE;
+                        break;
+
+                    case TVE_COLLAPSE:
+                        expand = FALSE;
+                        break;
+
+                    default:
+                        wxLogDebug(wxT("unexpected code %d in TVN_ITEMEXPAND "
+                                      "message"), tv->action);
+                }
+
+                bool ing = ((int)hdr->code == TVN_ITEMEXPANDING);
+                eventType = g_events[expand][ing];
+
+                event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
+                break;
+            }
+
+        case TVN_KEYDOWN:
+            {
+                eventType = wxEVT_COMMAND_TREE_KEY_DOWN;
+                TV_KEYDOWN *info = (TV_KEYDOWN *)lParam;
+
+                event.m_code = wxCharCodeMSWToWX(info->wVKey);
+
+                // a separate event for this case
+                if ( info->wVKey == VK_SPACE || info->wVKey == VK_RETURN )
+                {
+                    wxTreeEvent event2(wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
+                                       m_windowId);
+                    event2.SetEventObject(this);
+
+                    GetEventHandler()->ProcessEvent(event2);
+                }
+                break;
+            }
+
+        case TVN_SELCHANGED:
+            eventType = wxEVT_COMMAND_TREE_SEL_CHANGED;
+            // fall through
+
+        case TVN_SELCHANGING:
+            {
+                if ( eventType == wxEVT_NULL )
+                    eventType = wxEVT_COMMAND_TREE_SEL_CHANGING;
+                //else: already set above
+
+                NM_TREEVIEW* tv = (NM_TREEVIEW *)lParam;
+
+                event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
+                event.m_itemOld = (WXHTREEITEM) tv->itemOld.hItem;
+                break;
+            }
+
+        default:
+            return wxControl::MSWOnNotify(idCtrl, lParam, result);
+    }
+
+    event.SetEventObject(this);
+    event.SetEventType(eventType);
+
+    bool processed = GetEventHandler()->ProcessEvent(event);
+
+    // post processing
+    switch ( hdr->code )
+    {
+        case TVN_DELETEITEM:
+            {
+                // NB: we might process this message using wxWindows event
+                //     tables, but due to overhead of wxWin event system we
+                //     prefer to do it here ourself (otherwise deleting a tree
+                //     with many items is just too slow)
+                NM_TREEVIEW* tv = (NM_TREEVIEW *)lParam;
+
+                wxTreeItemId item = event.m_item;
+                if ( HasIndirectData(item) )
+                {
+                    wxTreeItemIndirectData *data = (wxTreeItemIndirectData *)
+                                                        tv->itemOld.lParam;
+                    delete data; // can't be NULL here
+
+                    m_itemsWithIndirectData.Remove(item);
+                }
+                else
+                {
+                    wxTreeItemData *data = (wxTreeItemData *)tv->itemOld.lParam;
+                    delete data; // may be NULL, ok
+                }
+
+                processed = TRUE; // Make sure we don't get called twice
+            }
+            break;
+
+        case TVN_BEGINLABELEDIT:
+            // return TRUE to cancel label editing
+            *result = !event.IsAllowed();
+            break;
+
+        case TVN_ENDLABELEDIT:
+            // return TRUE to set the label to the new string
+            *result = event.IsAllowed();
+
+            // ensure that we don't have the text ctrl which is going to be
+            // deleted any more
+            DeleteTextCtrl();
+            break;
+
+        case TVN_SELCHANGING:
+        case TVN_ITEMEXPANDING:
+            // return TRUE to prevent the action from happening
+            *result = !event.IsAllowed();
+            break;
+
+        case TVN_GETDISPINFO:
+            // NB: so far the user can't set the image himself anyhow, so do it
+            //     anyway - but this may change later
+            if ( 1 // !processed && )
+            {
+                wxTreeItemId item = event.m_item;
+                TV_DISPINFO *info = (TV_DISPINFO *)lParam;
+                if ( info->item.mask & TVIF_IMAGE )
+                {
+                    info->item.iImage =
+                        DoGetItemImageFromData
+                        (
+                         item,
+                         IsExpanded(item) ? wxTreeItemIcon_Expanded
+                                          : wxTreeItemIcon_Normal
+                        );
+                }
+                if ( info->item.mask & TVIF_SELECTEDIMAGE )
+                {
+                    info->item.iSelectedImage =
+                        DoGetItemImageFromData
+                        (
+                         item,
+                         IsExpanded(item) ? wxTreeItemIcon_SelectedExpanded
+                                          : wxTreeItemIcon_Selected
+                        );
+                }
+            }
+            break;
+
+        //default:
+            // for the other messages the return value is ignored and there is
+            // nothing special to do
+    }
+
+    return processed;
+*/
+    return FALSE;
 }
 
+// ----------------------------------------------------------------------------
 // Tree event
-IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxCommandEvent)
+// ----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxNotifyEvent)
 
-wxTreeEvent::wxTreeEvent(wxEventType commandType, int id):
-  wxCommandEvent(commandType, id)
+wxTreeEvent::wxTreeEvent(wxEventType commandType, int id)
+           : wxNotifyEvent(commandType, id)
 {
     m_code = 0;
-    m_oldItem = 0;
+    m_itemOld = 0;
 }
 
index 10100cb58ae40cd742873087dd5bfa565ac4bd27..d494fca7a47aefc4530ed681d68325d6041938f4 100644 (file)
@@ -9,10 +9,6 @@
 // Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-// #pragma implementation "utils.h"   // Note: this is done in utilscmn.cpp now.
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #include <errno.h>
 #include <stdarg.h>
 
-#define INCL_OS2
+#define INCL_DOS
 #define INCL_PM
+#define INCL_GPI
 #include <os2.h>
 #include<netdb.h>
+#define PURE_32
 #include<upm.h>
 
 // In the WIN.INI file
@@ -60,7 +58,7 @@ static const wxChar eUSERNAME[]  = _T("UserName");
 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
 bool wxGetHostName(wxChar *buf, int maxSize)
 {
-#ifdef USE_NET_API
+#if wxUSE_NET_API
   char                               server[256];
   char                               computer[256];
   unsigned long                      ulLevel;
@@ -80,10 +78,12 @@ bool wxGetHostName(wxChar *buf, int maxSize)
   wxChar *sysname;
   const wxChar *default_host = _T("noname");
 
-  if ((sysname = wxGetenv(_T("SYSTEM_NAME"))) == NULL) {
-     GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1);
-  } else
-    wxStrncpy(buf, sysname, maxSize - 1);
+  if ((sysname = wxGetenv(_T("SYSTEM_NAME"))) == NULL)
+  {
+      // GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1);
+  }
+  else
+      wxStrncpy(buf, sysname, maxSize - 1);
   buf[maxSize] = _T('\0');
 #endif
   return *buf ? TRUE : FALSE;
@@ -92,7 +92,7 @@ bool wxGetHostName(wxChar *buf, int maxSize)
 // Get user ID e.g. jacs
 bool wxGetUserId(wxChar *buf, int maxSize)
 {
-  return(U32ELOCL(bub, maxSize));
+  return(U32ELOCL((unsigned char*)buf, (unsigned long *)&maxSize));
 }
 
 bool wxGetUserName(wxChar *buf, int maxSize)
@@ -100,16 +100,7 @@ bool wxGetUserName(wxChar *buf, int maxSize)
 #ifdef USE_NET_API
     wxGetUserId(buf, maxSize);
 #else
-    bool ok = GetProfileString(WX_SECTION, eUSERNAME, _T(""), buf, maxSize - 1) != 0;
-    if ( !ok )
-    {
-        ok = wxGetUserId(buf, maxSize);
-    }
-
-    if ( !ok )
-    {
-        wxStrncpy(buf, _T("Unknown User"), maxSize);
-    }
+    wxStrncpy(buf, _T("Unknown User"), maxSize);
 #endif
   return TRUE;
 }
@@ -140,7 +131,8 @@ bool wxShell(const wxString& command)
 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
 long wxGetFreeMemory()
 {
-  return (long)GetFreeSpace(0);
+    // return (long)GetFreeSpace(0);
+    return 0L;
 }
 
 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
@@ -198,7 +190,6 @@ void wxDebugMsg(const wxChar *fmt ...)
   va_start(ap, fmt);
 
    sprintf(buffer,fmt,ap) ;
-   fflush(buffer) ;
 
   va_end(ap);
 }
@@ -211,24 +202,24 @@ void wxError(const wxString& msg, const wxString& title)
                       ,NULL
                       ,(PSZ)wxBuffer
                       ,(PSZ)WXSTRINGCAST title
+                      ,0
                       ,MB_ICONEXCLAMATION | MB_YESNO
-                     ) == IDNO)
+                     ) == MBID_YES)
     wxExit();
 }
 
 // Fatal error: pop up message box and abort
-void wxFatalError(const wxString& msg, const wxString& title)
-{
-    YUint32                         rc;
-    HWND                            hWnd;
-
-    WinMessageBox( HWND_DESKTOP
-                  ,hWnd
-                  ,rMsg.Data()
-                  ,rTitle.Data()
-                  ,0
-                  ,MB_NOICON | MB_OK
-                 );
+void wxFatalError(const wxString& rMsg, const wxString& rTitle)
+{
+    unsigned long                   rc;
+
+    rc = ::WinMessageBox( HWND_DESKTOP
+                         ,NULL
+                         ,WXSTRINGCAST rMsg
+                         ,WXSTRINGCAST rTitle
+                         ,0
+                         ,MB_NOICON | MB_OK
+                        );
     DosExit(EXIT_PROCESS, rc);
 }
 
@@ -258,13 +249,19 @@ int wxGetOsVersion(int *majorVsn, int *minorVsn)
 }
 
 // Reading and writing resources (eg WIN.INI, .Xdefaults)
+// TODO: Ability to read and write to an INI file
+
 #if wxUSE_RESOURCES
 bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
 {
+// TODO:
+/*
   if (file != "")
     return (WritePrivateProfileString((PCSZ)WXSTRINGCAST section, (PCSZ)WXSTRINGCAST entry, (PCSZ)value, (PCSZ)WXSTRINGCAST file) != 0);
   else
     return (WriteProfileString((PCSZ)WXSTRINGCAST section, (PCSZ)WXSTRINGCAST entry, (PCSZ)WXSTRINGCAST value) != 0);
+*/
+    return FALSE;
 }
 
 bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
@@ -291,6 +288,8 @@ bool wxWriteResource(const wxString& section, const wxString& entry, int value,
 bool wxGetResource(const wxString& section, const wxString& entry, wxChar **value, const wxString& file)
 {
   static const wxChar defunkt[] = _T("$$default");
+// TODO:
+/*
   if (file != "")
   {
     int n = GetPrivateProfileString((PCSZ)WXSTRINGCAST section, (PCSZ)WXSTRINGCAST entry, (PCSZ)defunkt,
@@ -308,7 +307,9 @@ bool wxGetResource(const wxString& section, const wxString& entry, wxChar **valu
   if (*value) delete[] (*value);
       *value = copystring(wxBuffer);
       return TRUE;
-    }
+*/
+    return FALSE;
+}
 
 bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
 {
@@ -452,7 +453,7 @@ bool wxCheckForInterrupt(wxWindow *wnd)
     HWND win= (HWND) wnd->GetHWND();
     while(::WinPeekMsg(hab,&msg,hwndFilter,0,0,PM_REMOVE))
     {
-      ::WinDispatchMsg( hab, &qmsg );
+      ::WinDispatchMsg( hab, &msg );
     }
     return TRUE;//*** temporary?
   }
@@ -488,16 +489,16 @@ wxChar *wxLoadUserResource(const wxString& resourceName, const wxString& resourc
 *   wxChar *theText = (wxChar *)LockResource(hData);
 *   if (!theText)
 *     return NULL;
+*
+* s = copystring(theText);
 */
-  s = copystring(theText);
-
   return s;
 }
 
 void wxGetMousePosition( int* x, int* y )
 {
-  POINT pt;
-  GetCursorPos( & pt );
+  POINTL pt;
+  ::WinQueryPointerPos( HWND_DESKTOP, & pt );
   *x = pt.x;
   *y = pt.y;
 };
@@ -530,7 +531,7 @@ int wxDisplayDepth()
         nDepth = nPlanes * nBitsPerPixel;
     }
     DevCloseDC(hDc);
-    return (depth);
+    return (nDepth);
 }
 
 // Get size of display
@@ -545,8 +546,8 @@ void wxDisplaySize(int *width, int *height)
                     ,lArray
                    ))
     {
-        *pWidth  = (int)lArray[CAPS_WIDTH];
-        *pHeight = (int)lArray[CAPS_HEIGHT];
+        *width  = (int)lArray[CAPS_WIDTH];
+        *height = (int)lArray[CAPS_HEIGHT];
     }
     DevCloseDC(hDc);
 }
@@ -565,7 +566,7 @@ wxString WXDLLEXPORT wxGetWindowText(WXHWND hWnd)
 {
     wxString str;
     long len = ::WinQueryWindowTextLength((HWND)hWnd) + 1;
-    ::WinQueryWindowText((HWND)hWnd, str.GetWriteBuf((int)len), len);
+    ::WinQueryWindowText((HWND)hWnd, len, str.GetWriteBuf((int)len));
     str.UngetWriteBuf();
 
     return str;
@@ -579,7 +580,7 @@ wxString WXDLLEXPORT wxGetWindowClass(WXHWND hWnd)
 
     for ( ;; )
     {
-        int count = ::WinQueryClassName((HWND)hWnd, str.GetWriteBuf(len), len);
+        int count = ::WinQueryClassName((HWND)hWnd, len, str.GetWriteBuf(len));
 
         str.UngetWriteBuf();
         if ( count == len )
index b842d08e90f5d6c57449dea938df4c6a321f68c0..4c6c00399ea55831871991e54fc1ed06d4c15c60 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
 // Name:        utilsexec.cpp
-// Purpose:     Execution-related utilities
-// Author:      AUTHOR
+// Purpose:     Various utilities
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
 
+#ifndef WX_PRECOMP
+#include "wx/setup.h"
 #include "wx/utils.h"
+#include "wx/app.h"
+#include "wx/intl.h"
+#endif
+
+#include "wx/log.h"
+
+#include "wx/process.h"
+
+#include "wx/os2/private.h"
+
+#define INCL_DOS
+#include <os2.h>
+
+#include <ctype.h>
+#include <direct.h>
+
+#include <sys/stat.h>
+#include <io.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+
+// this message is sent when the process we're waiting for terminates
+#define wxWM_PROC_TERMINATED (WM_USER + 10000)
+
+// structure describing the process we're being waiting for
+struct wxExecuteData
+{
+public:
+    ~wxExecuteData()
+    {
+// TODO:
+/*
+        if ( !::CloseHandle(hProcess) )
+        {
+            wxLogLastError("CloseHandle(hProcess)");
+        }
+*/
+    }
+
+    HWND       hWnd;          // window to send wxWM_PROC_TERMINATED to
+    HANDLE     hProcess;      // handle of the process
+    DWORD      dwProcessId;   // pid of the process
+    wxProcess *handler;
+    DWORD      dwExitCode;    // the exit code of the process
+    bool       state;         // set to FALSE when the process finishes
+};
+
+
+static DWORD wxExecuteThread(wxExecuteData *data)
+{
+// TODO:
+/*
+    WaitForSingleObject(data->hProcess, INFINITE);
 
-#define wxEXECUTE_WIN_MESSAGE 10000
+    // get the exit code
+    if ( !GetExitCodeProcess(data->hProcess, &data->dwExitCode) )
+    {
+        wxLogLastError("GetExitCodeProcess");
+    }
+
+    wxASSERT_MSG( data->dwExitCode != STILL_ACTIVE,
+                  wxT("process should have terminated") );
+
+    // send a message indicating process termination to the window
+    SendMessage(data->hWnd, wxWM_PROC_TERMINATED, 0, (LPARAM)data);
+*/
+    return 0;
+}
+
+// window procedure of a hidden window which is created just to receive
+// the notification message when a process exits
+MRESULT APIENTRY wxExecuteWindowCbk(HWND hWnd, UINT message,
+                                    MPARAM wParam, MPARAM lParam)
+{
+    if ( message == wxWM_PROC_TERMINATED )
+    {
+//        DestroyWindow(hWnd);    // we don't need it any more
+
+        wxExecuteData *data = (wxExecuteData *)lParam;
+        if ( data->handler )
+        {
+            data->handler->OnTerminate((int)data->dwProcessId,
+                                       (int)data->dwExitCode);
+        }
+
+        if ( data->state )
+        {
+            // we're executing synchronously, tell the waiting thread
+            // that the process finished
+            data->state = 0;
+        }
+        else
+        {
+            // asynchronous execution - we should do the clean up
+            delete data;
+        }
+    }
+
+    return 0;
+}
+
+extern wxChar wxPanelClassName[];
 
 long wxExecute(const wxString& command, bool sync, wxProcess *handler)
 {
-    // TODO
+    wxCHECK_MSG( !!command, 0, wxT("empty command in wxExecute") );
+
+    // the old code is disabled because we really need a process handle
+    // if we want to execute it asynchronously or even just get its
+    // return code and for this we must use CreateProcess() and not
+    // ShellExecute()
+
+    // create the process
+// TODO:
+/*
+    STARTUPINFO si;
+    memset(&si, 0, sizeof(si));
+    si.cb = sizeof(si);
+
+    PROCESS_INFORMATION pi;
+
+    if ( ::CreateProcess(
+                         NULL,       // application name (use only cmd line)
+                         (wxChar *)command.c_str(),  // full command line
+                         NULL,       // security attributes: defaults for both
+                         NULL,       //   the process and its main thread
+                         FALSE,      // don't inherit handles
+                         CREATE_DEFAULT_ERROR_MODE,  // flags
+                         NULL,       // environment (use the same)
+                         NULL,       // current directory (use the same)
+                         &si,        // startup info (unused here)
+                         &pi         // process info
+                        ) == 0 )
+    {
+        wxLogSysError(_("Execution of command '%s' failed"), command.c_str());
+
+        return 0;
+    }
+
+    // close unneeded handle
+    if ( !::CloseHandle(pi.hThread) )
+        wxLogLastError("CloseHandle(hThread)");
+
+    // create a hidden window to receive notification about process
+    // termination
+    HWND hwnd = ::CreateWindow(wxPanelClassName, NULL, 0, 0, 0, 0, 0, NULL,
+                               (HMENU)NULL, wxGetInstance(), 0);
+    wxASSERT_MSG( hwnd, wxT("can't create a hidden window for wxExecute") );
+
+    FARPROC ExecuteWindowInstance = MakeProcInstance((FARPROC)wxExecuteWindowCbk,
+                                                     wxGetInstance());
+
+    ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG) ExecuteWindowInstance);
+
+    // Alloc data
+    wxExecuteData *data = new wxExecuteData;
+    data->hProcess    = pi.hProcess;
+    data->dwProcessId = pi.dwProcessId;
+    data->hWnd        = hwnd;
+    data->state       = sync;
+    if ( sync )
+    {
+        wxASSERT_MSG( !handler, wxT("wxProcess param ignored for sync execution") );
+
+        data->handler = NULL;
+    }
+    else
+    {
+        // may be NULL or not
+        data->handler = handler;
+    }
+
+    DWORD tid;
+    HANDLE hThread = ::CreateThread(NULL,
+                                    0,
+                                    (LPTHREAD_START_ROUTINE)wxExecuteThread,
+                                    (void *)data,
+                                    0,
+                                    &tid);
+
+    if ( !hThread )
+    {
+        wxLogLastError("CreateThread in wxExecute");
+
+        DestroyWindow(hwnd);
+        delete data;
+
+        // the process still started up successfully...
+        return pi.dwProcessId;
+    }
+
+    if ( !sync )
+    {
+        // clean up will be done when the process terminates
+
+        // return the pid
+        return pi.dwProcessId;
+    }
+
+    // waiting until command executed
+    while ( data->state )
+        wxYield();
+
+    DWORD dwExitCode = data->dwExitCode;
+    delete data;
+
+    // return the exit code
+    return dwExitCode;
+*/
     return 0;
 }
+
+long wxExecute(char **argv, bool sync, wxProcess *handler)
+{
+    wxString command;
+
+    while ( *argv != NULL )
+    {
+        command << *argv++ << ' ';
+    }
+
+    command.RemoveLast();
+
+    return wxExecute(command, sync, handler);
+}
+
+bool wxGetFullHostName(wxChar *buf, int maxSize)
+{
+    DWORD nSize = maxSize ;
+// TODO:
+/*
+    if ( !::GetComputerName(buf, &nSize) )
+    {
+        wxLogLastError("GetComputerName");
+
+        return FALSE;
+    }
+*/
+    return TRUE;
+}
+
index c25681858c1ff36786d670c8a5d2366a617c25a2..bf21d3730360aa89627ca46513b03491b9ecd662 100644 (file)
@@ -1,21 +1,33 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        wave.cpp
 // Purpose:     wxWave class implementation: optional
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/17/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "wave.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
 #endif
 
-#include "wx/object.h"
-#include "wx/string.h"
-#include "wx/stubs/wave.h"
+#include "wx/file.h"
+#include "wx/os2/wave.h"
+#include "wx/os2/private.h"
+
+#define INCL_DOS
+#define INCL_PM
+#include <os2.h>
+#ifdef RECT
+    #undef RECT
+#endif
+#include <mmio.h>
+#include <mmsystem.h>
 
 wxWave::wxWave()
   : m_waveData(NULL), m_waveLength(0), m_isResource(FALSE)
@@ -23,39 +35,122 @@ wxWave::wxWave()
 }
 
 wxWave::wxWave(const wxString& sFileName, bool isResource)
-  : m_waveData(NULL), m_waveLength(0), m_isResource(FALSE)
+  : m_waveData(NULL), m_waveLength(0), m_isResource(isResource)
 {
-    Create(sFileName, isResource);
+  Create(sFileName, isResource);
 }
 
+wxWave::wxWave(int size, const wxByte* data)
+  : m_waveData(NULL), m_waveLength(0), m_isResource(FALSE)
+{
+  Create(size, data);
+}
 
 wxWave::~wxWave()
 {
-    Free();
+  Free();
 }
 
 bool wxWave::Create(const wxString& fileName, bool isResource)
 {
-    Free();
+  Free();
 
-    // TODO
+  if (isResource)
+  {
+    m_isResource = TRUE;
+// TODO:
+/*
+    HRSRC hresInfo;
+#ifdef _UNICODE
+    hresInfo = ::FindResourceW((HMODULE) wxhInstance, fileName, wxT("WAVE"));
+#else
+    hresInfo = ::FindResourceA((HMODULE) wxhInstance, fileName, wxT("WAVE"));
+#endif
+    if (!hresInfo)
+        return FALSE;
+
+    HGLOBAL waveData = ::LoadResource((HMODULE) wxhInstance, hresInfo);
+
+    if (waveData)
+    {
+      m_waveData= (wxByte*)::LockResource(waveData);
+      m_waveLength = (int) ::SizeofResource((HMODULE) wxhInstance, hresInfo);
+    }
 
+    return (m_waveData ? TRUE : FALSE);
+*/
     return FALSE;
+  }
+  else
+  {
+    m_isResource = FALSE;
+
+    wxFile fileWave;
+    if (!fileWave.Open(fileName, wxFile::read))
+        return FALSE;
+
+    m_waveLength = (int) fileWave.Length();
+// TODO:
+/*
+    m_waveData = (wxByte*)::GlobalLock(::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, m_waveLength));
+    if (!m_waveData)
+        return FALSE;
+
+    fileWave.Read(m_waveData, m_waveLength);
+*/
+    return TRUE;
+  }
 }
 
-bool wxWave::Play(bool async, bool looped) const
+bool wxWave::Create(int size, const wxByte* data)
 {
-    if (!IsOk())
-        return FALSE;
+  Free();
+  m_isResource = FALSE;
+  m_waveLength=size;
+  m_waveData = NULL; // (wxByte*)::GlobalLock(::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, m_waveLength));
+  if (!m_waveData)
+     return FALSE;
 
-    // TODO
-    return FALSE;
+  for (int i=0; i<size; i++) m_waveData[i] = data[i];
+  return TRUE;
 }
 
-bool wxWave::Free()
+bool wxWave::Play(bool async, bool looped) const
 {
-    // TODO
+  if (!IsOk())
+    return FALSE;
+// TODO:
+/*
+  return ( ::PlaySound((LPCTSTR)m_waveData, NULL, SND_MEMORY |
+    SND_NODEFAULT | (async ? SND_ASYNC : SND_SYNC) | (looped ? (SND_LOOP | SND_ASYNC) : 0)) != 0 );
+*/
     return FALSE;
 }
 
+bool wxWave::Free()
+{
+  if (m_waveData)
+  {
+//  HGLOBAL waveData = ::GlobalHandle(m_waveData);
+
+// TODO:
+/*
+    if (waveData)
+    {
+      if (m_isResource)
+        ::FreeResource(waveData);
+      else
+      {
+        ::GlobalUnlock(waveData);
+        ::GlobalFree(waveData);
+      }
+
+      m_waveData = NULL;
+      m_waveLength = 0;
+      return TRUE;
+    }
+*/
+  }
+  return FALSE;
+}