]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/statbr95.cpp
OS/2 updates for statusbar processing
[wxWidgets.git] / src / msw / statbr95.cpp
index c628c89235c4f932b9b4b984513c210f09e33c26..4843ea05a67650e535da4baa2bd10113aae199ad 100644 (file)
 
 #if defined(__WIN95__) && wxUSE_NATIVE_STATUSBAR
 
+#include "wx/intl.h"
 #include "wx/log.h"
 #include "wx/statusbr.h"
 
 #include "wx/msw/private.h"
 #include <windowsx.h>
 
-#if !defined(__GNUWIN32__) || defined(__TWIN32__) || defined(wxUSE_NORLANDER_HEADERS)
-#include <commctrl.h>
+#if !(defined(__GNUWIN32_OLD__) || defined(__TWIN32__))
+    #include <commctrl.h>
 #endif
 
 // ----------------------------------------------------------------------------
 IMPLEMENT_DYNAMIC_CLASS(wxStatusBar95, wxWindow);
 IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxStatusBar95)
 
-BEGIN_EVENT_TABLE(wxStatusBar95, wxWindow)
-    EVT_SIZE(wxStatusBar95::OnSize)
-END_EVENT_TABLE()
-
 // ----------------------------------------------------------------------------
 // macros
 // ----------------------------------------------------------------------------
@@ -64,20 +61,35 @@ END_EVENT_TABLE()
 //
 // ----------------------------------------------------------------------------
 
-static WNDPROC gs_wndprocStatBar = NULL;
+// static WNDPROC gs_wndprocStatBar = NULL;
+static WXFARPROC gs_wndprocStatBar = (WXFARPROC) NULL;
 
 LRESULT APIENTRY wxStatusBarProc(HWND hwnd,
                                  UINT message,
                                  WPARAM wParam,
                                  LPARAM lParam)
 {
-    if ( message == WM_COMMAND )
-    {
-        wxStatusBar95 *sb = (wxStatusBar95 *)GetWindowLong(hwnd, GWL_USERDATA);
-        sb->MSWWindowProc(message, wParam, lParam);
+    switch (message) {
+        case WM_COMMAND:
+        case WM_DRAWITEM:
+        case WM_MEASUREITEM:
+        case WM_SIZE:
+        case WM_MOVE:
+        case WM_MOUSEMOVE:
+        case WM_LBUTTONUP:
+        case WM_LBUTTONDBLCLK:
+        case WM_RBUTTONDOWN:
+        case WM_RBUTTONUP:
+        case WM_RBUTTONDBLCLK:
+        case WM_MBUTTONDOWN:
+        case WM_MBUTTONUP:
+        case WM_MBUTTONDBLCLK:
+            wxStatusBar95 *sb = (wxStatusBar95 *)GetWindowLong(hwnd, GWL_USERDATA);
+            sb->MSWWindowProc(message, wParam, lParam);
+            break;
     }
 
-    return ::CallWindowProc(gs_wndprocStatBar, hwnd, message, wParam, lParam);
+    return ::CallWindowProc(CASTWNDPROC gs_wndprocStatBar, hwnd, message, wParam, lParam);
 }
 
 // ============================================================================
@@ -100,17 +112,33 @@ bool wxStatusBar95::Create(wxWindow *parent,
                            long style,
                            const wxString& name)
 {
+    wxCHECK_MSG( parent, FALSE, wxT("status bar must have a parent") );
+
     SetName(name);
+    SetWindowStyleFlag(style);
     SetParent(parent);
 
-    if (id == -1)
-        m_windowId = NewControlId();
-    else
-        m_windowId = id;
+    parent->AddChild(this);
 
-    DWORD wstyle = WS_CHILD | WS_VISIBLE;
-    if ( style & wxST_SIZEGRIP )
+    m_windowId = id == -1 ? NewControlId() : id;
+
+    DWORD wstyle = WS_CHILD | WS_VISIBLE /* | WS_CLIPSIBLINGS */ ;
+
+    // setting SBARS_SIZEGRIP is perfectly useless: it's always on by default
+    // (at least in the version of comctl32.dll I'm using), and the only way to
+    // turn it off is to use CCS_TOP style - as we position the status bar
+    // manually anyhow (see DoMoveWindow), use CCS_TOP style if wxST_SIZEGRIP
+    // is not given
+    if ( !(style & wxST_SIZEGRIP) )
+    {
+        wstyle |= CCS_TOP;
+    }
+    else
+    {
+        // may be some versions of comctl32.dll do need it - anyhow, it won't
+        // do any harm
         wstyle |= SBARS_SIZEGRIP;
+    }
 
     m_hWnd = (WXHWND)CreateStatusWindow(wstyle,
                                         wxEmptyString,
@@ -123,13 +151,15 @@ bool wxStatusBar95::Create(wxWindow *parent,
         return FALSE;
     }
 
-    // for some reason, subclassing in the usual way doesn't work at all - many
-    // strange things start happening (status bar is not positioned correctly,
-    // all methods fail...)
+    SetFieldsCount(1);
+
+    // we can't subclass this window as usual because the status bar window
+    // proc processes WM_SIZE and WM_PAINT specially
     //  SubclassWin(m_hWnd);
 
-    // but we want to process the messages from it still, so must subclass it
-    gs_wndprocStatBar = (WNDPROC)GetWindowLong(GetHwnd(), GWL_WNDPROC);
+    // but we want to process the messages from it still, so do custom
+    // subclassing here
+    gs_wndprocStatBar = (WXFARPROC)GetWindowLong(GetHwnd(), GWL_WNDPROC);
     SetWindowLong(GetHwnd(), GWL_WNDPROC, (LONG)wxStatusBarProc);
     SetWindowLong(GetHwnd(), GWL_USERDATA, (LONG)this);
 
@@ -156,23 +186,23 @@ void wxStatusBar95::CopyFieldsWidth(const int widths[])
   }
 }
 
-void wxStatusBar95::SetFieldsCount(int nFields, const int widths[])
+void wxStatusBar95::SetFieldsCount(int nFields, const int *widths)
 {
-  // this is Windows limitation
-  wxASSERT_MSG( (nFields > 0) && (nFields < 255), _T("too many fields") );
+    // this is a Windows limitation
+    wxASSERT_MSG( (nFields > 0) && (nFields < 255), _T("too many fields") );
 
-  m_nFields = nFields;
+    m_nFields = nFields;
 
-  CopyFieldsWidth(widths);
-  SetFieldsWidth();
+    CopyFieldsWidth(widths);
+    SetFieldsWidth();
 }
 
 void wxStatusBar95::SetStatusWidths(int n, const int widths[])
 {
-  wxASSERT_MSG( n == m_nFields, _T("field number mismatch") );
+    wxASSERT_MSG( n == m_nFields, _T("field number mismatch") );
 
-  CopyFieldsWidth(widths);
-  SetFieldsWidth();
+    CopyFieldsWidth(widths);
+    SetFieldsWidth();
 }
 
 void wxStatusBar95::SetFieldsWidth()
@@ -291,7 +321,7 @@ bool wxStatusBar95::GetFieldRect(int i, wxRect& rect) const
     RECT r;
     if ( !::SendMessage(GetHwnd(), SB_GETRECT, i, (LPARAM)&r) )
     {
-        wxLogLastError("SendMessage(SB_GETRECT)");
+        wxLogLastError(wxT("SendMessage(SB_GETRECT)"));
     }
 
     wxCopyRECTToRect(r, rect);
@@ -299,14 +329,23 @@ bool wxStatusBar95::GetFieldRect(int i, wxRect& rect) const
     return TRUE;
 }
 
-void wxStatusBar95::OnSize(wxSizeEvent& event)
+void wxStatusBar95::DoMoveWindow(int x, int y, int width, int height)
 {
-  FORWARD_WM_SIZE(GetHwnd(), SIZE_RESTORED,
-                  event.GetSize().x, event.GetSize().y,
-                  SendMessage);
-
-  // adjust fields widths to the new size
-  SetFieldsWidth();
+    // the status bar wnd proc must be forwarded the WM_SIZE message whenever
+    // the stat bar position/size is changed because it normally positions the
+    // control itself along bottom or top side of the parent window - failing
+    // to do so will result in nasty visual effects
+    FORWARD_WM_SIZE(GetHwnd(), SIZE_RESTORED, x, y, SendMessage);
+
+    // but now, when the standard status bar wnd proc did all it wanted to do,
+    // move the status bar to its correct location - usually this call may be
+    // omitted because for normal status bars (positioned along the bottom
+    // edge) the position is already set correctly, but if the user wants to
+    // position them in some exotic location, this is really needed
+    wxWindow::DoMoveWindow(x, y, width, height);
+
+    // adjust fields widths to the new size
+    SetFieldsWidth();
 }
 
 #endif // __WIN95__ && wxUSE_NATIVE_STATUSBAR