X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b96340e6f457071d63196f877c6df0ea1cc2af04..11ec1f16f83fd89a86c2b8912c991b226c15886e:/src/msw/dialog.cpp diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index 8df2875db1..bc03783404 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -96,31 +96,35 @@ END_EVENT_TABLE() // wxDialog construction // ---------------------------------------------------------------------------- -wxDialog::wxDialog() +void wxDialog::Init() { m_oldFocus = (wxWindow *)NULL; + m_isShown = FALSE; + m_windowDisabler = (wxWindowDisabler *)NULL; + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); } -bool wxDialog::Create(wxWindow *parent, wxWindowID id, +bool wxDialog::Create(wxWindow *parent, + wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name) { + Init(); + m_oldFocus = FindFocus(); - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); SetName(name); wxTopLevelWindows.Append(this); - // windowFont = wxTheFontList->FindOrCreateFont(11, wxSWISS, wxNORMAL, wxNORMAL); - - if (parent) parent->AddChild(this); + if ( parent ) + parent->AddChild(this); if ( id == -1 ) m_windowId = (int)NewControlId(); @@ -139,8 +143,6 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id, m_windowStyle = style; - m_isShown = FALSE; - if (width < 0) width = wxDIALOG_DEFAULT_WIDTH; if (height < 0) @@ -152,8 +154,11 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id, WXDWORD extendedStyle = MakeExtendedStyle(m_windowStyle); if (m_windowStyle & wxSTAY_ON_TOP) extendedStyle |= WS_EX_TOPMOST; - if (m_exStyle & wxFRAME_EX_CONTEXTHELP) + +#ifndef __WIN16__ + if (m_exStyle & wxDIALOG_EX_CONTEXTHELP) extendedStyle |= WS_EX_CONTEXTHELP; +#endif // Allows creation of dialogs with & without captions under MSWindows, // resizeable or not (but a resizeable dialog always has caption - @@ -165,12 +170,30 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id, dlg = wxT("wxCaptionDialog"); else dlg = wxT("wxNoCaptionDialog"); + +#ifdef __WXMICROWIN__ + extern const wxChar *wxFrameClassName; + + int msflags = WS_OVERLAPPED|WS_POPUP; + if (style & wxCAPTION) + msflags |= WS_CAPTION; + if (style & wxCLIP_CHILDREN) + msflags |= WS_CLIPCHILDREN; + if ((style & wxTHICK_FRAME) == 0) + msflags |= WS_BORDER; + MSWCreate(m_windowId, parent, wxFrameClassName, this, NULL, + x, y, width, height, + msflags, + NULL, + extendedStyle); + +#else MSWCreate(m_windowId, parent, NULL, this, NULL, x, y, width, height, 0, // style is not used if we have dlg template dlg, extendedStyle); - +#endif HWND hwnd = (HWND)GetHWND(); if ( !hwnd ) @@ -180,14 +203,47 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id, return FALSE; } +#ifndef __WXMICROWIN__ SubclassWin(GetHWND()); - +#endif + SetWindowText(hwnd, title); - SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); return TRUE; } +bool wxDialog::EnableCloseButton(bool enable) +{ +#ifndef __WXMICROWIN__ + // get system (a.k.a. window) menu + HMENU hmenu = ::GetSystemMenu(GetHwnd(), FALSE /* get it */); + if ( !hmenu ) + { + wxLogLastError(_T("GetSystemMenu")); + + return FALSE; + } + + // enabling/disabling the close item from it also automatically + // disables/enabling the close title bar button + if ( !::EnableMenuItem(hmenu, SC_CLOSE, + MF_BYCOMMAND | (enable ? MF_ENABLED : MF_GRAYED)) ) + { + wxLogLastError(_T("EnableMenuItem(SC_CLOSE)")); + + return FALSE; + } + + // update appearance immediately + if ( !::DrawMenuBar(GetHwnd()) ) + { + wxLogLastError(_T("DrawMenuBar")); + } +#endif + + return TRUE; +} + void wxDialog::SetModal(bool flag) { if ( flag ) @@ -210,8 +266,7 @@ wxDialog::~wxDialog() wxTopLevelWindows.DeleteObject(this); - // this will call BringWindowToTop() if necessary to bring back our parent - // window to top + // this will also reenable all the other windows for a modal dialog Show(FALSE); if ( !IsModal() ) @@ -340,38 +395,33 @@ void wxDialog::DoShowModal() if (oldFocus) hwndOldFocus = (HWND) oldFocus->GetHWND(); - // inside this block, all app windows are disabled + // remember where the focus was + if ( !oldFocus ) { - wxWindowDisabler wd(this); + oldFocus = parent; + if ( parent ) + hwndOldFocus = GetHwndOf(parent); + } - // remember where the focus was - if ( !oldFocus ) - { - oldFocus = parent; - if (parent) - hwndOldFocus = (HWND) parent->GetHWND(); - } + // disable all other app windows + wxASSERT_MSG( !m_windowDisabler, _T("disabling windows twice?") ); - // enter the modal loop - while ( IsModalShowing() ) - { + m_windowDisabler = new wxWindowDisabler(this); + + // enter the modal loop + while ( IsModalShowing() ) + { #if wxUSE_THREADS - wxMutexGuiLeaveOrEnter(); + wxMutexGuiLeaveOrEnter(); #endif // wxUSE_THREADS - while ( !wxTheApp->Pending() && wxTheApp->ProcessIdle() ) - ; + while ( !wxTheApp->Pending() && wxTheApp->ProcessIdle() ) + ; - // a message came or no more idle processing to do - wxTheApp->DoMessage(); - } + // a message came or no more idle processing to do + wxTheApp->DoMessage(); } -#ifdef __WIN32__ - if ( parent ) - ::SetActiveWindow(GetHwndOf(parent)); -#endif // __WIN32__ - // and restore focus // Note that this code MUST NOT access the dialog object's data // in case the object has been deleted (which will be the case @@ -386,16 +436,15 @@ void wxDialog::DoShowModal() bool wxDialog::Show(bool show) { - // The following is required when the parent has been disabled, (modal - // dialogs, or modeless dialogs with disabling such as wxProgressDialog). - // Otherwise the parent disappears behind other windows when the dialog is - // hidden. if ( !show ) { - wxWindow *parent = GetParent(); - if ( parent ) + // if we had disabled other app windows, reenable them back now because + // if they stay disabled Windows will activate another window (one + // which is enabled, anyhow) and we will lose activation + if ( m_windowDisabler ) { - ::BringWindowToTop(GetHwndOf(parent)); + delete m_windowDisabler; + m_windowDisabler = NULL; } } @@ -424,6 +473,18 @@ bool wxDialog::Show(bool show) { // use it m_parent = parent; + + // VZ: to make dialog behave properly we should reparent + // the dialog for Windows as well - unfortunately, + // following the docs for SetParent() results in this + // code which plainly doesn't work +#if 0 + long dwStyle = ::GetWindowLong(GetHwnd(), GWL_STYLE); + dwStyle &= ~WS_POPUP; + dwStyle |= WS_CHILD; + ::SetWindowLong(GetHwnd(), GWL_STYLE, dwStyle); + ::SetParent(GetHwnd(), GetHwndOf(parent)); +#endif // 0 } } @@ -467,7 +528,7 @@ void wxDialog::EndModal(int retCode) // ---------------------------------------------------------------------------- // Standard buttons -void wxDialog::OnOK(wxCommandEvent& event) +void wxDialog::OnOK(wxCommandEvent& WXUNUSED(event)) { if ( Validate() && TransferDataFromWindow() ) { @@ -475,7 +536,7 @@ void wxDialog::OnOK(wxCommandEvent& event) } } -void wxDialog::OnApply(wxCommandEvent& event) +void wxDialog::OnApply(wxCommandEvent& WXUNUSED(event)) { if ( Validate() ) TransferDataFromWindow(); @@ -483,12 +544,12 @@ void wxDialog::OnApply(wxCommandEvent& event) // TODO probably need to disable the Apply button until things change again } -void wxDialog::OnCancel(wxCommandEvent& event) +void wxDialog::OnCancel(wxCommandEvent& WXUNUSED(event)) { EndModal(wxID_CANCEL); } -void wxDialog::OnCloseWindow(wxCloseEvent& event) +void wxDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) { // We'll send a Cancel message by default, which may close the dialog. // Check for looping if the Cancel event handler calls Close(). @@ -529,7 +590,7 @@ bool wxDialog::Destroy() return TRUE; } -void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& event) +void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) { #if wxUSE_CTL3D Ctl3dColorChange(); @@ -550,6 +611,7 @@ long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) switch ( message ) { +#if 0 // now that we got owner window right it doesn't seem to be needed case WM_ACTIVATE: switch ( LOWORD(wParam) ) { @@ -576,6 +638,7 @@ long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) // fall through to process it normally as well } break; +#endif // 0 case WM_CLOSE: // if we can't close, tell the system that we processed the @@ -583,6 +646,7 @@ long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) processed = !Close(); break; +#ifndef __WXMICROWIN__ case WM_SETCURSOR: // we want to override the busy cursor for modal dialogs: // typically, wxBeginBusyCursor() is called and then a modal dialog @@ -608,6 +672,7 @@ long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) rc = FALSE; } break; +#endif } if ( !processed )