From cbc66a27047635e86fbba08043da831666d74f4a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 12 Mar 2000 00:26:21 +0000 Subject: [PATCH] 1. wxProgressDialog uses wxWindowDisabler, not (dumb) wxEnableTopLevelWindows 2. some more wxWindowDisabler bugs fixed (updated dialogs sample to test them) 3. Esc won't close the dialogs without cancel button under MSW 4. status bar can be child of windows of clases other than wxFrame (updated statbar sample to show it) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6630 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/progdlgg.h | 5 ++++ include/wx/msw/statbr95.h | 6 ++--- samples/dialogs/dialogs.cpp | 17 ++++++++++--- samples/statbar/statbar.cpp | 46 ++++++++++++++++++++++++++++++++--- src/common/utilscmn.cpp | 26 +++++++++++--------- src/generic/progdlgg.cpp | 24 +++++++----------- src/msw/dialog.cpp | 34 ++++++++++++++------------ src/msw/frame.cpp | 31 ++++++----------------- src/msw/statbr95.cpp | 28 +++++++++------------ src/msw/window.cpp | 5 ++++ 10 files changed, 130 insertions(+), 92 deletions(-) diff --git a/include/wx/generic/progdlgg.h b/include/wx/generic/progdlgg.h index 8979d2f003..b02ba1ef28 100644 --- a/include/wx/generic/progdlgg.h +++ b/include/wx/generic/progdlgg.h @@ -97,11 +97,16 @@ private: Continue, // can be cancelled but wasn't Finished // finished, waiting to be removed from screen } m_state; + // the abort button (or NULL if none) wxButton *m_btnAbort; + // the maximum value int m_maximum; + // for wxPD_APP_MODAL case + class WXDLLEXPORT wxWindowDisabler *m_winDisabler; + DECLARE_EVENT_TABLE() }; #endif diff --git a/include/wx/msw/statbr95.h b/include/wx/msw/statbr95.h index b84a016a6a..f6f56cfe1d 100644 --- a/include/wx/msw/statbr95.h +++ b/include/wx/msw/statbr95.h @@ -58,14 +58,14 @@ public: virtual int GetBorderX() const; virtual int GetBorderY() const; - void OnSize(wxSizeEvent& event); - protected: void CopyFieldsWidth(const int widths[]); void SetFieldsWidth(); + // override base class virtual + void DoMoveWindow(int x, int y, int width, int height); + private: - DECLARE_EVENT_TABLE() DECLARE_DYNAMIC_CLASS(wxStatusBar95); }; diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index 432115cd90..2f194b38be 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -537,9 +537,20 @@ void MyCanvas::OnPaint(wxPaintEvent& WXUNUSED(event) ) MyModelessDialog::MyModelessDialog(wxWindow *parent) : wxDialog(parent, -1, wxString("Modeless dialog")) { - (void)new wxButton(this, DIALOGS_MODELESS_BTN, "Press me"); - Fit(); - Centre(); + wxBoxSizer *sizerTop = new wxBoxSizer(wxVERTICAL); + + wxButton *btn = new wxButton(this, DIALOGS_MODELESS_BTN, "Press me"); + wxCheckBox *check = new wxCheckBox(this, -1, "Should be disabled"); + check->Disable(); + + sizerTop->Add(btn, 1, wxEXPAND | wxALL, 5); + sizerTop->Add(check, 1, wxEXPAND | wxALL, 5); + + SetAutoLayout(TRUE); + SetSizer(sizerTop); + + sizerTop->SetSizeHints(this); + sizerTop->Fit(this); } void MyModelessDialog::OnClose(wxCloseEvent& event) diff --git a/samples/statbar/statbar.cpp b/samples/statbar/statbar.cpp index 96b55de7b8..6ff9fa9533 100644 --- a/samples/statbar/statbar.cpp +++ b/samples/statbar/statbar.cpp @@ -33,8 +33,7 @@ #error "You need to set wxUSE_STATUSBAR to 1 to compile this sample" #endif // wxUSE_STATUSBAR -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWindows headers +// for all others, include the necessary headers #ifndef WX_PRECOMP #include "wx/app.h" #include "wx/frame.h" @@ -45,6 +44,7 @@ #include "wx/menu.h" #include "wx/msgdlg.h" #include "wx/textdlg.h" + #include "wx/sizer.h" #endif #include "wx/datetime.h" @@ -137,6 +137,13 @@ private: DECLARE_EVENT_TABLE() }; +// Our about dialog ith its status bar +class MyAboutDialog : public wxDialog +{ +public: + MyAboutDialog(wxWindow *parent); +}; + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -346,8 +353,39 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { - wxMessageBox("wxStatusBar sample\n(c) 2000 Vadim Zeitlin", - "About statbar", wxOK | wxICON_INFORMATION, this); + MyAboutDialog dlg(this); + dlg.ShowModal(); +} + +// ---------------------------------------------------------------------------- +// MyAboutDialog +// ---------------------------------------------------------------------------- + +MyAboutDialog::MyAboutDialog(wxWindow *parent) + : wxDialog(parent, -1, wxString("About statbar"), + wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ + wxStaticText *text = new wxStaticText(this, -1, + "wxStatusBar sample\n" + "(c) 2000 Vadim Zeitlin"); + + wxStatusBar *statbar = new wxStatusBar(this, -1); + statbar->SetFieldsCount(2); + statbar->SetStatusText("This is a status bar", 0); + statbar->SetStatusText("in a dialog", 1); + + wxBoxSizer *sizerTop = new wxBoxSizer(wxVERTICAL); + sizerTop->Add(-1, 10, 1, wxGROW); + sizerTop->Add(text, 0, wxCENTRE); + sizerTop->Add(-1, 10, 1, wxGROW); + sizerTop->Add(statbar, 0, wxGROW); + + SetAutoLayout(TRUE); + SetSizer(sizerTop); + + sizerTop->Fit(this); + sizerTop->SetSizeHints(this); } // ---------------------------------------------------------------------------- diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index 7a971cb5ac..13270f231b 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -952,7 +952,7 @@ int isascii( int c ) #endif // __MWERKS__ // ---------------------------------------------------------------------------- -// misc functions +// wxSafeYield and supporting functions // ---------------------------------------------------------------------------- void wxEnableTopLevelWindows(bool enable) @@ -962,13 +962,18 @@ void wxEnableTopLevelWindows(bool enable) node->GetData()->Enable(enable); } -static void wxFindDisabledWindows(wxWindowList& winDisabled, wxWindow *win) +static void wxFindDisabledWindows(wxWindowList& winDisabled, + wxWindow *win, + wxWindow *winToSkip) { wxWindowList::Node *node; for ( node = win->GetChildren().GetFirst(); node; node = node->GetNext() ) { wxWindow *child = node->GetData(); - wxFindDisabledWindows(winDisabled, child); + if ( child == winToSkip ) + continue; + + wxFindDisabledWindows(winDisabled, child, winToSkip); if ( child->IsEnabled() ) { @@ -998,21 +1003,14 @@ wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip) for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) { wxWindow *winTop = node->GetData(); - if ( winTop->IsEnabled() ) + if ( winTop != winToSkip && winTop->IsEnabled() ) { - wxFindDisabledWindows(*m_winDisabled, winTop); + wxFindDisabledWindows(*m_winDisabled, winTop, winToSkip); m_winDisabled->Append(winTop); winTop->Disable(); } } - - if ( winToSkip && m_winDisabled->Find(winToSkip) ) - { - // always enable ourselves - m_winDisabled->DeleteObject(winToSkip); - winToSkip->Enable(); - } } wxWindowDisabler::~wxWindowDisabler() @@ -1060,6 +1058,10 @@ bool wxSafeYield(wxWindow *win) return rc; } +// ---------------------------------------------------------------------------- +// misc functions +// ---------------------------------------------------------------------------- + // Don't synthesize KeyUp events holding down a key and producing KeyDown // events with autorepeat. On by default and always on in wxMSW. wxGTK version // in utilsgtk.cpp. diff --git a/src/generic/progdlgg.cpp b/src/generic/progdlgg.cpp index b8a6a17e00..90436f9340 100644 --- a/src/generic/progdlgg.cpp +++ b/src/generic/progdlgg.cpp @@ -103,14 +103,7 @@ wxProgressDialog::wxProgressDialog(wxString const &title, wxClientDC dc(this); dc.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); long widthText; -#if defined(__VISAGECPP__) -// have two versions of this in wxWindowDC tp avoid function hiding -// since there are two of these in wxDCBase, and in turn in wxDC. -// VA cannot resolve this so: dc.GetTextExtent(message, &widthText, NULL, NULL, NULL, NULL); -#else - dc.GetTextExtent(message, &widthText, (long*)NULL); -#endif m_msg = new wxStaticText(this, -1, message); c = new wxLayoutConstraints; @@ -218,14 +211,15 @@ wxProgressDialog::wxProgressDialog(wxString const &title, Centre(wxCENTER_FRAME | wxBOTH); - if ( !(style & wxPD_APP_MODAL) ) + if ( style & wxPD_APP_MODAL ) { - if ( m_parentTop ) - m_parentTop->Enable(FALSE); + m_winDisabler = new wxWindowDisabler(this); } else { - wxEnableTopLevelWindows(FALSE); + if ( m_parentTop ) + m_parentTop->Enable(FALSE); + m_winDisabler = NULL; } Show(TRUE); @@ -389,14 +383,14 @@ void wxProgressDialog::OnClose(wxCloseEvent& event) wxProgressDialog::~wxProgressDialog() { - if ( !(GetWindowStyle() & wxPD_APP_MODAL) ) + if ( GetWindowStyle() & wxPD_APP_MODAL ) { - if ( m_parentTop ) - m_parentTop->Enable(TRUE); + delete m_winDisabler; } else { - wxEnableTopLevelWindows(TRUE); + if ( m_parentTop ) + m_parentTop->Enable(TRUE); } } diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index bbd4c9f334..4a0102db14 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -235,24 +235,26 @@ wxDialog::~wxDialog() // By default, pressing escape cancels the dialog void wxDialog::OnCharHook(wxKeyEvent& event) { - if (GetHWND()) - { - if (event.m_keyCode == WXK_ESCAPE) + if (GetHWND()) { - // Behaviour changed in 2.0: we'll send a Cancel message - // to the dialog instead of Close. - wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); - cancelEvent.SetEventObject( this ); - GetEventHandler()->ProcessEvent(cancelEvent); - - // ensure that there is another message for this window so the - // ShowModal loop will exit and won't get stuck in GetMessage(). - ::PostMessage(GetHwnd(), WM_NULL, 0, 0); - return; + // "Esc" works as an accelerator for the "Cancel" button, but it + // shouldn't close the dialog which doesn't have any cancel button + if ( (event.m_keyCode == WXK_ESCAPE) && FindWindow(wxID_CANCEL) ) + { + wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); + cancelEvent.SetEventObject( this ); + GetEventHandler()->ProcessEvent(cancelEvent); + + // ensure that there is another message for this window so the + // ShowModal loop will exit and won't get stuck in GetMessage(). + ::PostMessage(GetHwnd(), WM_NULL, 0, 0); + + return; + } } - } - // We didn't process this event. - event.Skip(); + + // We didn't process this event. + event.Skip(); } // ---------------------------------------------------------------------------- diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index 08d33b8b77..4e528223ee 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -393,29 +393,14 @@ void wxFrame::PositionStatusBar() if ( !m_frameStatusBar ) return; - // native status bar positions itself, but we must forward the WM_SIZE - // messages to it -#if wxUSE_NATIVE_STATUSBAR - wxStatusBar95 *sb = wxDynamicCast(m_frameStatusBar, wxStatusBar95); - if ( sb ) - { - wxSizeEvent event(GetSize(), sb->GetId()); - event.SetEventObject(sb); - - sb->GetEventHandler()->ProcessEvent(event); - } - else -#endif // wxUSE_NATIVE_STATUSBAR - { - int w, h; - GetClientSize(&w, &h); - int sw, sh; - m_frameStatusBar->GetSize(&sw, &sh); - - // Since we wish the status bar to be directly under the client area, - // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS. - m_frameStatusBar->SetSize(0, h, w, sh); - } + int w, h; + GetClientSize(&w, &h); + int sw, sh; + m_frameStatusBar->GetSize(&sw, &sh); + + // Since we wish the status bar to be directly under the client area, + // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS. + m_frameStatusBar->SetSize(0, h, w, sh); } #endif // wxUSE_STATUSBAR diff --git a/src/msw/statbr95.cpp b/src/msw/statbr95.cpp index a3c3bdb670..2820bef97c 100644 --- a/src/msw/statbr95.cpp +++ b/src/msw/statbr95.cpp @@ -47,10 +47,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxStatusBar95, wxWindow); IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxStatusBar95) -BEGIN_EVENT_TABLE(wxStatusBar95, wxWindow) - EVT_SIZE(wxStatusBar95::OnSize) -END_EVENT_TABLE() - // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -102,13 +98,15 @@ 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); + + m_windowId = id == -1 ? NewControlId() : id; DWORD wstyle = WS_CHILD | WS_VISIBLE; if ( style & wxST_SIZEGRIP ) @@ -125,12 +123,12 @@ 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...) + // 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 + // 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); @@ -301,11 +299,9 @@ 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); + FORWARD_WM_SIZE(GetHwnd(), SIZE_RESTORED, x, y, SendMessage); // adjust fields widths to the new size SetFieldsWidth(); diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 3f8c4085f7..9e92ac4db2 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -365,6 +365,10 @@ bool wxWindow::Enable(bool enable) if ( hWnd ) ::EnableWindow(hWnd, (BOOL)enable); + // VZ: no, this is a bad idea: imagine that you have a dialog with some + // disabled controls and disable it - you really wouldn't like the + // disabled controls eb reenabled too when you reenable the dialog! +#if 0 wxWindowList::Node *node = GetChildren().GetFirst(); while ( node ) { @@ -373,6 +377,7 @@ bool wxWindow::Enable(bool enable) node = node->GetNext(); } +#endif // 0 return TRUE; } -- 2.45.2