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); + // "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; + // 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); + int w, h; + GetClientSize(&w, &h); + int sw, sh; + m_frameStatusBar->GetSize(&sw, &sh); - 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); - } + // 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; }