#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
// ----------------------------------------------------------------------------
//
// ----------------------------------------------------------------------------
-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(CASTWNDPROC gs_wndprocStatBar, hwnd, message, wParam, lParam);
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,
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);
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[])
+void wxStatusBar95::SetStatusWidths(int WXUNUSED_UNLESS_DEBUG(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()
RECT r;
if ( !::SendMessage(GetHwnd(), SB_GETRECT, i, (LPARAM)&r) )
{
- wxLogLastError("SendMessage(SB_GETRECT)");
+ wxLogLastError(wxT("SendMessage(SB_GETRECT)"));
}
wxCopyRECTToRect(r, rect);
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