From 43b5058d590c7acf58e5f75ec015e717d03830a2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 14 Mar 2000 00:45:54 +0000 Subject: [PATCH] 1. status bar can now be positioned on top (and anywhere, in fact) 2. status bar without wxST_SIZEGRIP style won't have the size grip (wow) 3. scrollbars don't get the cursor of the main window any more 4. introduced wxSetCursorEvent and use it in wxSplitterWindow git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6665 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 2 ++ include/wx/event.h | 41 +++++++++++++++++++++++-- include/wx/generic/splitter.h | 1 + include/wx/statusbr.h | 2 +- src/generic/splitter.cpp | 23 ++++++++++++-- src/msw/statbr95.cpp | 35 ++++++++++++++++++---- src/msw/window.cpp | 56 ++++++++++++++++++++++++++++------- 7 files changed, 140 insertions(+), 20 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index cae98ae030..5e2203e7e6 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -54,6 +54,8 @@ wxMSW: - support for enhanced metafiles added, support for copying/pasting metafiles (WMF and enhanced ones) fixed/added. - implemented setting colours for push buttons +- wxStatusBar95 may be now used in dialogs, panels (not only frames) and can be + positioned along the top of the screen and not only at the bottom - wxTreeCtrl::IsVisible() bug fixed (thanks to Gary Chessun) - loading/saving big (> 32K) files in wxTextCtrl works - tooltips work with wxRadioBox diff --git a/include/wx/event.h b/include/wx/event.h index 98cdf33d11..a9303f12ad 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -21,6 +21,7 @@ #if wxUSE_GUI #include "wx/gdicmn.h" + #include "wx/cursor.h" #endif #include "wx/thread.h" @@ -118,6 +119,9 @@ enum wxEVT_KEY_DOWN = wxEVT_FIRST + 215, wxEVT_KEY_UP = wxEVT_FIRST + 216, + /* Set cursor event */ + wxEVT_SET_CURSOR = wxEVT_FIRST + 230, + /* * wxScrollbar and wxSlider event identifiers */ @@ -714,6 +718,35 @@ public: bool m_metaDown; }; +// Cursor set event + +/* + wxEVT_SET_CURSOR + */ + +class WXDLLEXPORT wxSetCursorEvent : public wxEvent +{ +public: + wxSetCursorEvent(wxCoord x, wxCoord y) + { + m_eventType = wxEVT_SET_CURSOR; + + m_x = x; + m_y = y; + } + + wxCoord GetX() const { return m_x; } + wxCoord GetY() const { return m_y; } + + void SetCursor(const wxCursor& cursor) { m_cursor = cursor; } + const wxCursor& GetCursor() const { return m_cursor; } + bool HasCursor() const { return m_cursor.Ok(); } + +private: + wxCoord m_x, m_y; + wxCursor m_cursor; +}; + // Keyboard input event class /* @@ -1555,6 +1588,9 @@ typedef void (wxEvtHandler::*wxMaximizeEventFunction)(wxShowEvent&); typedef void (wxEvtHandler::*wxNavigationKeyEventFunction)(wxNavigationKeyEvent&); typedef void (wxEvtHandler::*wxPaletteChangedEventFunction)(wxPaletteChangedEvent&); typedef void (wxEvtHandler::*wxQueryNewPaletteEventFunction)(wxQueryNewPaletteEvent&); +typedef void (wxEvtHandler::*wxWindowCreateEventFunction)(wxWindowCreateEvent&); +typedef void (wxEvtHandler::*wxWindowDestroyEventFunction)(wxWindowDestroyEvent&); +typedef void (wxEvtHandler::*wxSetCursorEventFunction)(wxSetCursorEvent&); #endif // wxUSE_GUI // N.B. In GNU-WIN32, you *have* to take the address of a member function @@ -1613,8 +1649,9 @@ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \ #define EVT_NAVIGATION_KEY(func) { wxEVT_NAVIGATION_KEY, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNavigationKeyEventFunction) & func, (wxObject *) NULL }, #define EVT_PALETTE_CHANGED(func) { wxEVT_PALETTE_CHANGED, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxPaletteChangedEventFunction) & func, (wxObject *) NULL }, #define EVT_QUERY_NEW_PALETTE(func) { wxEVT_QUERY_NEW_PALETTE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL }, -#define EVT_WINDOW_CREATE(func) { wxEVT_CREATE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL }, -#define EVT_WINDOW_DESTROY(func) { wxEVT_DESTROY, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL }, +#define EVT_WINDOW_CREATE(func) { wxEVT_CREATE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxWindowCreateEventFunction) & func, (wxObject *) NULL }, +#define EVT_WINDOW_DESTROY(func) { wxEVT_DESTROY, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxWindowDestroyEventFunction) & func, (wxObject *) NULL }, +#define EVT_SET_CURSOR(func) { wxEVT_SET_CURSOR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxSetCursorEventFunction) & func, (wxObject *) NULL }, // Mouse events #define EVT_LEFT_DOWN(func) { wxEVT_LEFT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func, (wxObject *) NULL }, diff --git a/include/wx/generic/splitter.h b/include/wx/generic/splitter.h index d74fc68403..4bdd5ace6a 100644 --- a/include/wx/generic/splitter.h +++ b/include/wx/generic/splitter.h @@ -187,6 +187,7 @@ protected: void OnSashPosChanging(wxSplitterEvent& event); void OnDoubleClick(wxSplitterEvent& event); void OnUnsplitEvent(wxSplitterEvent& event); + void OnSetCursor(wxSetCursorEvent& event); void SendUnsplitEvent(wxWindow *winRemoved); diff --git a/include/wx/statusbr.h b/include/wx/statusbr.h index 4a0345ec52..029c7cb621 100644 --- a/include/wx/statusbr.h +++ b/include/wx/statusbr.h @@ -71,7 +71,7 @@ public: wxWindowID id, const wxPoint& WXUNUSED(pos) = wxDefaultPosition, const wxSize& WXUNUSED(size) = wxDefaultSize, - long style = 0, + long style = wxST_SIZEGRIP, const wxString& name = wxPanelNameStr) { Create(parent, id, style, name); diff --git a/src/generic/splitter.cpp b/src/generic/splitter.cpp index e6a00ded5e..6f45254813 100644 --- a/src/generic/splitter.cpp +++ b/src/generic/splitter.cpp @@ -42,6 +42,8 @@ BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow) EVT_IDLE(wxSplitterWindow::OnIdle) EVT_MOUSE_EVENTS(wxSplitterWindow::OnMouseEvent) + EVT_SET_CURSOR(wxSplitterWindow::OnSetCursor) + EVT_SPLITTER_SASH_POS_CHANGED(-1, wxSplitterWindow::OnSashPosChanged) // NB: we borrow OnSashPosChanged for purposes of // EVT_SPLITTER_SASH_POS_CHANGING since default implementation is identical @@ -234,8 +236,7 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event) } } - if ( m_permitUnsplitAlways - || m_minimumPaneSize == 0 ) + if ( m_permitUnsplitAlways || m_minimumPaneSize == 0 ) { // Deal with possible unsplit scenarios if ( new_sash_position == 0 ) @@ -930,3 +931,21 @@ void wxSplitterWindow::OnUnsplitEvent(wxSplitterEvent& event) // for compatibility, call the virtual function OnUnsplit(win); } + +void wxSplitterWindow::OnSetCursor(wxSetCursorEvent& event) +{ + // this is currently called (and needed) under MSW only... +#ifdef __WXMSW__ + + // if we don't do it, the resizing cursor might be set for child window: + // and like this we explicitly say that our cursor should not be used for + // children windows which overlap us + + if ( SashHitTest(event.GetX(), event.GetY()) ) + { + // default processing is ok + event.Skip(); + } + //else: do nothing, in particular, don't call Skip() +#endif // wxMSW +} diff --git a/src/msw/statbr95.cpp b/src/msw/statbr95.cpp index 86937ad4a9..c3cf3960bf 100644 --- a/src/msw/statbr95.cpp +++ b/src/msw/statbr95.cpp @@ -109,8 +109,22 @@ bool wxStatusBar95::Create(wxWindow *parent, m_windowId = id == -1 ? NewControlId() : id; DWORD wstyle = WS_CHILD | WS_VISIBLE; - if ( style & wxST_SIZEGRIP ) + + // 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, @@ -303,10 +317,21 @@ bool wxStatusBar95::GetFieldRect(int i, wxRect& rect) const void wxStatusBar95::DoMoveWindow(int x, int y, int width, int height) { - FORWARD_WM_SIZE(GetHwnd(), SIZE_RESTORED, x, 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 diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 9e92ac4db2..b8533b3dfb 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -2667,29 +2667,65 @@ bool wxWindow::HandleSetCursor(WXHWND hWnd, int WXUNUSED(mouseMsg)) { // the logic is as follows: + // -1. don't set cursor for non client area, including but not limited to + // the title bar, scrollbars, &c + // 0. allow the user to override default behaviour by using EVT_SET_CURSOR // 1. if we have the cursor set it unless wxIsBusy() // 2. if we're a top level window, set some cursor anyhow // 3. if wxIsBusy(), set the busy cursor, otherwise the global one + if ( nHitTest != HTCLIENT ) + { + return FALSE; + } + HCURSOR hcursor = 0; - bool isBusy = wxIsBusy(); - if ( m_cursor.Ok() ) + + // first ask the user code - it may wish to set the cursor in some very + // specific way (for example, depending on the current position) + POINT pt; + if ( !::GetCursorPos(&pt) ) + { + wxLogLastError("GetCursorPos"); + } + + int x = pt.x, + y = pt.y; + ScreenToClient(&x, &y); + wxSetCursorEvent event(x, y); + + bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event); + if ( processedEvtSetCursor && event.HasCursor() ) { - hcursor = GetHcursorOf(m_cursor); + hcursor = GetHcursorOf(event.GetCursor()); } - if ( !GetParent() ) + if ( !hcursor ) { - if ( isBusy ) + bool isBusy = wxIsBusy(); + + // the test for processedEvtSetCursor is here to prevent using m_cursor + // if the user code caught EVT_SET_CURSOR() and returned nothing from + // it - this is a way to say that our cursor shouldn't be used for this + // point + if ( !processedEvtSetCursor && m_cursor.Ok() ) { - hcursor = wxGetCurrentBusyCursor(); + hcursor = GetHcursorOf(m_cursor); } - else if ( !hcursor ) + + if ( !GetParent() ) { - const wxCursor *cursor = wxGetGlobalCursor(); - if ( cursor && cursor->Ok() ) + if ( isBusy ) { - hcursor = GetHcursorOf(*cursor); + hcursor = wxGetCurrentBusyCursor(); + } + else if ( !hcursor ) + { + const wxCursor *cursor = wxGetGlobalCursor(); + if ( cursor && cursor->Ok() ) + { + hcursor = GetHcursorOf(*cursor); + } } } } -- 2.47.2