X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3180bc0e63fc0feea1fcdb756752b700c27b9773..96b2cbe8b39292fed91654ff0d1f4b1c16561acb:/src/msw/dialog.cpp diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index 32678cc578..1b66274cc1 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -17,10 +17,6 @@ // headers // ---------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "dialog.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -28,25 +24,24 @@ #pragma hdrstop #endif +#include "wx/dialog.h" + #ifndef WX_PRECOMP - #include "wx/dialog.h" + #include "wx/msw/wrapcdlg.h" #include "wx/utils.h" #include "wx/frame.h" #include "wx/app.h" + #include "wx/button.h" #include "wx/settings.h" #include "wx/intl.h" #include "wx/log.h" + #include "wx/toolbar.h" #endif #include "wx/msw/private.h" -#include "wx/log.h" #include "wx/evtloop.h" #include "wx/ptr_scpd.h" -#if wxUSE_COMMON_DIALOGS && !defined(__WXMICROWIN__) - #include -#endif - #if defined(__SMARTPHONE__) && defined(__WXWINCE__) #include "wx/msw/wince/resources.h" #endif // __SMARTPHONE__ && __WXWINCE__ @@ -84,10 +79,14 @@ wxBEGIN_FLAGS( wxDialogStyle ) wxFLAGS_MEMBER(wxWS_EX_VALIDATE_RECURSIVELY) wxFLAGS_MEMBER(wxSTAY_ON_TOP) wxFLAGS_MEMBER(wxCAPTION) +#if WXWIN_COMPATIBILITY_2_6 wxFLAGS_MEMBER(wxTHICK_FRAME) +#endif // WXWIN_COMPATIBILITY_2_6 wxFLAGS_MEMBER(wxSYSTEM_MENU) wxFLAGS_MEMBER(wxRESIZE_BORDER) +#if WXWIN_COMPATIBILITY_2_6 wxFLAGS_MEMBER(wxRESIZE_BOX) +#endif // WXWIN_COMPATIBILITY_2_6 wxFLAGS_MEMBER(wxCLOSE_BOX) wxFLAGS_MEMBER(wxMAXIMIZE_BOX) wxFLAGS_MEMBER(wxMINIMIZE_BOX) @@ -109,16 +108,6 @@ wxCONSTRUCTOR_6( wxDialog , wxWindow* , Parent , wxWindowID , Id , wxString , Ti IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxTopLevelWindow) #endif -BEGIN_EVENT_TABLE(wxDialog, wxDialogBase) - EVT_BUTTON(wxID_OK, wxDialog::OnOK) - EVT_BUTTON(wxID_APPLY, wxDialog::OnApply) - EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel) - - EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged) - - EVT_CLOSE(wxDialog::OnCloseWindow) -END_EVENT_TABLE() - // ---------------------------------------------------------------------------- // wxDialogModalData // ---------------------------------------------------------------------------- @@ -144,7 +133,7 @@ private: wxModalEventLoop m_evtLoop; }; -wxDEFINE_TIED_SCOPED_PTR_TYPE(wxDialogModalData); +wxDEFINE_TIED_SCOPED_PTR_TYPE(wxDialogModalData) // ============================================================================ // implementation @@ -160,6 +149,10 @@ void wxDialog::Init() m_isShown = false; m_modalData = NULL; m_endModalCalled = false; +#if wxUSE_TOOLBAR && defined(__POCKETPC__) + m_dialogToolBar = NULL; +#endif + m_hGripper = 0; } bool wxDialog::Create(wxWindow *parent, @@ -184,34 +177,22 @@ bool wxDialog::Create(wxWindow *parent, if ( !m_hasFont ) SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); - #if defined(__SMARTPHONE__) && defined(__WXWINCE__) SetLeftMenu(wxID_OK, _("OK")); #endif +#if wxUSE_TOOLBAR && defined(__POCKETPC__) + CreateToolBar(); +#endif - return true; -} - -// deprecated ctor -wxDialog::wxDialog(wxWindow *parent, - const wxString& title, - bool WXUNUSED(modal), - int x, - int y, - int w, - int h, - long style, - const wxString& name) -{ - Init(); + if ( HasFlag(wxRESIZE_BORDER) ) + { + CreateGripper(); - Create(parent, wxID_ANY, title, wxPoint(x, y), wxSize(w, h), style, name); -} + Connect(wxEVT_CREATE, + wxWindowCreateEventHandler(wxDialog::OnWindowCreate)); + } -void wxDialog::SetModal(bool WXUNUSED(flag)) -{ - // nothing to do, obsolete method + return true; } wxDialog::~wxDialog() @@ -220,17 +201,14 @@ wxDialog::~wxDialog() // this will also reenable all the other windows for a modal dialog Show(false); + + DestroyGripper(); } // ---------------------------------------------------------------------------- // showing the dialogs // ---------------------------------------------------------------------------- -bool wxDialog::IsModalShowing() const -{ - return IsModal(); -} - wxWindow *wxDialog::FindSuitableParent() const { // first try to use the currently active window @@ -270,6 +248,9 @@ bool wxDialog::Show(bool show) if ( show ) { + if (CanDoLayoutAdaptation()) + DoLayoutAdaptation(); + // this usually will result in TransferDataToWindow() being called // which will change the controls values so do it before showing as // otherwise we could have some flicker @@ -280,13 +261,15 @@ bool wxDialog::Show(bool show) if ( show ) { - // dialogs don't get WM_SIZE message after creation unlike most (all?) - // other windows and so could start their life non laid out correctly - // if we didn't call Layout() from here + // dialogs don't get WM_SIZE message from ::ShowWindow() for some + // reason so generate it ourselves for consistency with frames and + // dialogs in other ports // // NB: normally we should call it just the first time but doing it // every time is simpler than keeping a flag - Layout(); + const wxSize size = GetClientSize(); + ::SendMessage(GetHwnd(), WM_SIZE, + SIZE_RESTORED, MAKELPARAM(size.x, size.y)); } return true; @@ -300,7 +283,7 @@ void wxDialog::Raise() // show dialog modally int wxDialog::ShowModal() { - wxASSERT_MSG( !IsModal(), _T("wxDialog::ShowModal() reentered?") ); + wxASSERT_MSG( !IsModal(), _T("ShowModal() can't be called twice") ); m_endModalCalled = false; @@ -365,82 +348,138 @@ void wxDialog::EndModal(int retCode) Hide(); } -void wxDialog::EndDialog(int rc) +// ---------------------------------------------------------------------------- +// wxDialog gripper handling +// ---------------------------------------------------------------------------- + +void wxDialog::SetWindowStyleFlag(long style) { - if ( IsModal() ) - EndModal(rc); + wxDialogBase::SetWindowStyleFlag(style); + + if ( HasFlag(wxRESIZE_BORDER) ) + CreateGripper(); else - Hide(); + DestroyGripper(); } -// ---------------------------------------------------------------------------- -// wxWin event handlers -// ---------------------------------------------------------------------------- +void wxDialog::CreateGripper() +{ + if ( !m_hGripper ) + { + // just create it here, it will be positioned and shown later + m_hGripper = (WXHWND)::CreateWindow + ( + wxT("SCROLLBAR"), + wxT(""), + WS_CHILD | + WS_CLIPSIBLINGS | + SBS_SIZEGRIP | + SBS_SIZEBOX | + SBS_SIZEBOXBOTTOMRIGHTALIGN, + 0, 0, 0, 0, + GetHwnd(), + 0, + wxGetInstance(), + NULL + ); + } +} -// Standard buttons -void wxDialog::OnOK(wxCommandEvent& WXUNUSED(event)) +void wxDialog::DestroyGripper() { - if ( Validate() && TransferDataFromWindow() ) - { - EndDialog(wxID_OK); - } + if ( m_hGripper ) + { + // we used to have trouble with gripper appearing on top (and hence + // overdrawing) the other, real, dialog children -- check that this + // isn't the case automatically + wxASSERT_MSG( ::GetNextWindow((HWND)m_hGripper, GW_HWNDNEXT) == 0, + _T("Bug in wxWidgets: gripper should be at the bottom of Z-order") ); + ::DestroyWindow((HWND) m_hGripper); + m_hGripper = 0; + } } -void wxDialog::OnApply(wxCommandEvent& WXUNUSED(event)) +void wxDialog::ShowGripper(bool show) { - if ( Validate() ) - TransferDataFromWindow(); + wxASSERT_MSG( m_hGripper, _T("shouldn't be called if we have no gripper") ); + + if ( show ) + ResizeGripper(); - // TODO probably need to disable the Apply button until things change again + ::ShowWindow((HWND)m_hGripper, show ? SW_SHOW : SW_HIDE); } -void wxDialog::OnCancel(wxCommandEvent& WXUNUSED(event)) +void wxDialog::ResizeGripper() { - EndDialog(wxID_CANCEL); + wxASSERT_MSG( m_hGripper, _T("shouldn't be called if we have no gripper") ); + + HWND hwndGripper = (HWND)m_hGripper; + + const wxRect rectGripper = wxRectFromRECT(wxGetWindowRect(hwndGripper)); + const wxSize size = GetClientSize() - rectGripper.GetSize(); + + ::SetWindowPos(hwndGripper, HWND_BOTTOM, + size.x, size.y, + rectGripper.width, rectGripper.height, + SWP_NOACTIVATE); } -void wxDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) +void wxDialog::OnWindowCreate(wxWindowCreateEvent& event) { - // We'll send a Cancel message by default, which may close the dialog. - // Check for looping if the Cancel event handler calls Close(). + if ( m_hGripper && IsShown() && + event.GetWindow() && event.GetWindow()->GetParent() == this ) + { + // Put gripper below the newly created child window + ::SetWindowPos((HWND)m_hGripper, HWND_BOTTOM, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); + } + + event.Skip(); +} - // Note that if a cancel button and handler aren't present in the dialog, - // nothing will happen when you close the dialog via the window manager, or - // via Close(). We wouldn't want to destroy the dialog by default, since - // the dialog may have been created on the stack. However, this does mean - // that calling dialog->Close() won't delete the dialog unless the handler - // for wxID_CANCEL does so. So use Destroy() if you want to be sure to - // destroy the dialog. The default OnCancel (above) simply ends a modal - // dialog, and hides a modeless dialog. +// ---------------------------------------------------------------------------- +// wxWin event handlers +// ---------------------------------------------------------------------------- - // VZ: this is horrible and MT-unsafe. Can't we reuse some of these global - // lists here? don't dare to change it now, but should be done later! - static wxList closing; +#ifdef __POCKETPC__ +// Responds to the OK button in a PocketPC titlebar. This +// can be overridden, or you can change the id used for +// sending the event, by calling SetAffirmativeId. +bool wxDialog::DoOK() +{ + const int idOk = GetAffirmativeId(); + if ( EmulateButtonClickIfPresent(idOk) ) + return true; - if ( closing.Member(this) ) - return; + wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetAffirmativeId()); + event.SetEventObject(this); - closing.Append(this); + return HandleWindowEvent(event); +} +#endif // __POCKETPC__ - wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); - cancelEvent.SetEventObject( this ); - GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog +#if wxUSE_TOOLBAR && defined(__POCKETPC__) +// create main toolbar by calling OnCreateToolBar() +wxToolBar* wxDialog::CreateToolBar(long style, wxWindowID winid, const wxString& name) +{ + m_dialogToolBar = OnCreateToolBar(style, winid, name); - closing.DeleteObject(this); + return m_dialogToolBar; } -void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) +// return a new toolbar +wxToolBar *wxDialog::OnCreateToolBar(long style, + wxWindowID winid, + const wxString& name) { -#if wxUSE_CTL3D - Ctl3dColorChange(); -#else - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); - Refresh(); -#endif + return new wxToolMenuBar(this, winid, + wxDefaultPosition, wxDefaultSize, + style, name); } +#endif // --------------------------------------------------------------------------- -// dialog window proc +// dialog Windows messages processing // --------------------------------------------------------------------------- WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) @@ -456,17 +495,13 @@ WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPar { switch ( LOWORD(wParam) ) { -#ifndef __SMARTPHONE__ +#ifdef __POCKETPC__ case IDOK: - wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL), wxButton); - if ( btn && btn->IsEnabled() ) - { - // if we do have a cancel button, do press it - btn->MSWCommand(BN_CLICKED, 0 /* unused */); - processed = true; - break; - } -#else // ifdef __SMARTPHONE__ + processed = DoOK(); + if (!processed) + processed = !Close(); +#endif +#ifdef __SMARTPHONE__ case IDM_LEFT: case IDM_RIGHT: processed = HandleCommand( LOWORD(wParam) , 0 , NULL ); @@ -483,6 +518,19 @@ WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPar break; case WM_SIZE: + if ( m_hGripper ) + { + switch ( wParam ) + { + case SIZE_MAXIMIZED: + ShowGripper(false); + break; + + case SIZE_RESTORED: + ShowGripper(true); + } + } + // the Windows dialogs unfortunately are not meant to be resizeable // at all and their standard class doesn't include CS_[VH]REDRAW // styles which means that the window is not refreshed properly @@ -531,19 +579,3 @@ WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPar return rc; } - -#if wxUSE_CTL3D - -// Define for each class of dialog and control -WXHBRUSH wxDialog::OnCtlColor(WXHDC WXUNUSED(pDC), - WXHWND WXUNUSED(pWnd), - WXUINT WXUNUSED(nCtlColor), - WXUINT message, - WXWPARAM wParam, - WXLPARAM lParam) -{ - return (WXHBRUSH)Ctl3dCtlColorEx(message, wParam, lParam); -} - -#endif // wxUSE_CTL3D -