Files
wxWidgets/src/os2/dialog.cpp
Julian Smart 3aa8e4ea6d Added automatic dialog scrolling ability
Added ability to resize wizard bitmaps automatically
Made it easier to derive from wxWizard and override behaviour,
mainly by making members protected instead of private



git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50942 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2007-12-29 16:35:39 +00:00

348 lines
9.6 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/os2/dialog.cpp
// Purpose: wxDialog class
// Author: David Webster
// Modified by:
// Created: 10/14/99
// RCS-ID: $Id$
// Copyright: (c) David Webster
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include "wx/dialog.h"
#ifndef WX_PRECOMP
#include "wx/utils.h"
#include "wx/frame.h"
#include "wx/app.h"
#include "wx/settings.h"
#include "wx/intl.h"
#include "wx/log.h"
#endif
#include "wx/os2/private.h"
#include "wx/evtloop.h"
#include "wx/ptr_scpd.h"
#define wxDIALOG_DEFAULT_X 300
#define wxDIALOG_DEFAULT_Y 300
#define wxDIALOG_DEFAULT_WIDTH 500
#define wxDIALOG_DEFAULT_HEIGHT 500
IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxTopLevelWindow)
// ----------------------------------------------------------------------------
// wxDialogModalData
// ----------------------------------------------------------------------------
// this is simply a container for any data we need to implement modality which
// allows us to avoid changing wxDialog each time the implementation changes
class wxDialogModalData
{
public:
wxDialogModalData(wxDialog *dialog) : m_evtLoop(dialog) { }
void RunLoop()
{
m_evtLoop.Run();
}
void ExitLoop()
{
m_evtLoop.Exit();
}
private:
wxModalEventLoop m_evtLoop;
};
wxDEFINE_TIED_SCOPED_PTR_TYPE(wxDialogModalData);
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxDialog construction
// ----------------------------------------------------------------------------
void wxDialog::Init()
{
m_pOldFocus = (wxWindow *)NULL;
m_isShown = false;
m_pWindowDisabler = (wxWindowDisabler *)NULL;
m_modalData = NULL;
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
} // end of wxDialog::Init
bool wxDialog::Create( wxWindow* pParent,
wxWindowID vId,
const wxString& rsTitle,
const wxPoint& rPos,
const wxSize& rSize,
long lStyle,
const wxString& rsName )
{
Init();
SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG);
//
// Save focus before doing anything which can potentially change it
//
m_pOldFocus = FindFocus();
//
// All dialogs should really have this style
//
lStyle |= wxTAB_TRAVERSAL;
if (!wxTopLevelWindow::Create( pParent
,vId
,rsTitle
,rPos
,rSize
,lStyle
,rsName
))
return false;
SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
//
// Must defer setting the title until after dialog is created and sized
//
if (!rsTitle.IsNull())
SetTitle(rsTitle);
return true;
} // end of wxDialog::Create
#if WXWIN_COMPATIBILITY_2_6
// 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();
Create(parent, wxID_ANY, title, wxPoint(x, y), wxSize(w, h), style, name);
}
void wxDialog::SetModal(bool WXUNUSED(bFlag))
{
// nothing to do, obsolete method
} // end of wxDialog::SetModal
#endif // WXWIN_COMPATIBILITY_2_6
wxDialog::~wxDialog()
{
m_isBeingDeleted = true;
// this will also reenable all the other windows for a modal dialog
Show(false);
} // end of wxDialog::~wxDialog
// ----------------------------------------------------------------------------
// showing the dialogs
// ----------------------------------------------------------------------------
#if WXWIN_COMPATIBILITY_2_6
bool wxDialog::IsModalShowing() const
{
return IsModal();
} // end of wxDialog::IsModalShowing
#endif // WXWIN_COMPATIBILITY_2_6
wxWindow *wxDialog::FindSuitableParent() const
{
// first try to use the currently active window
HWND hwndFg = ::WinQueryActiveWindow(HWND_DESKTOP);
wxWindow *parent = hwndFg ? wxFindWinFromHandle((WXHWND)hwndFg)
: NULL;
if ( !parent )
{
// next try the main app window
parent = wxTheApp->GetTopWindow();
}
// finally, check if the parent we found is really suitable
if ( !parent || parent == (wxWindow *)this || !parent->IsShown() )
{
// don't use this one
parent = NULL;
}
return parent;
}
bool wxDialog::Show( bool bShow )
{
if ( bShow == IsShown() )
return false;
if (!bShow && m_modalData )
{
// we need to do this before calling wxDialogBase version because if we
// had disabled other app windows, they must be reenabled right now as
// if they stay disabled Windows will activate another window (one
// which is enabled, anyhow) when we're hidden in the base class Show()
// and we will lose activation
m_modalData->ExitLoop();
#if 0
if (m_pWindowDisabler)
{
delete m_pWindowDisabler;
m_pWindowDisabler = NULL;
}
#endif
}
if (bShow)
{
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
InitDialog();
}
wxDialogBase::Show(bShow);
wxString title = GetTitle();
if (!title.empty())
::WinSetWindowText((HWND)GetHwnd(), title.c_str());
if ( bShow )
{
// dialogs don't get WM_SIZE message after creation unlike most (all?)
// other windows and so could start their life not laid out correctly
// if we didn't call Layout() from here
//
// NB: normally we should call it just the first time but doing it
// every time is simpler than keeping a flag
Layout();
}
return true;
} // end of wxDialog::Show
//
// Replacement for Show(true) for modal dialogs - returns return code
//
int wxDialog::ShowModal()
{
wxASSERT_MSG( !IsModal(), _T("wxDialog::ShowModal() reentered?") );
m_endModalCalled = false;
Show();
// EndModal may have been called from InitDialog handler (called from
// inside Show()), which would cause an infinite loop if we didn't take it
// into account
if ( !m_endModalCalled )
{
// modal dialog needs a parent window, so try to find one
wxWindow *parent = GetParent();
if ( !parent )
{
parent = FindSuitableParent();
}
// remember where the focus was
wxWindow *oldFocus = m_pOldFocus;
if ( !oldFocus )
{
// VZ: do we really want to do this?
oldFocus = parent;
}
// We have to remember the HWND because we need to check
// the HWND still exists (oldFocus can be garbage when the dialog
// exits, if it has been destroyed)
HWND hwndOldFocus = oldFocus ? GetHwndOf(oldFocus) : NULL;
//
// Before entering the modal loop, reset the "is in OnIdle()" flag (see
// comment in app.cpp)
//
extern bool gbInOnIdle;
bool bWasInOnIdle = gbInOnIdle;
gbInOnIdle = false;
// enter and run the modal loop
{
wxDialogModalDataTiedPtr modalData(&m_modalData,
new wxDialogModalData(this));
modalData->RunLoop();
}
gbInOnIdle = bWasInOnIdle;
// 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
// for a modal dialog that has been destroyed before calling EndModal).
if ( oldFocus && (oldFocus != this) && ::WinIsWindow(vHabmain, hwndOldFocus))
{
// This is likely to prove that the object still exists
if (wxFindWinFromHandle((WXHWND) hwndOldFocus) == oldFocus)
oldFocus->SetFocus();
}
}
return GetReturnCode();
} // end of wxDialog::ShowModal
void wxDialog::EndModal(
int nRetCode
)
{
wxASSERT_MSG( IsModal(), _T("EndModal() called for non modal dialog") );
m_endModalCalled = true;
SetReturnCode(nRetCode);
Hide();
} // end of wxDialog::EndModal
MRESULT wxDialog::OS2WindowProc( WXUINT uMessage, WXWPARAM wParam, WXLPARAM lParam )
{
MRESULT rc = 0;
bool bProcessed = false;
switch (uMessage)
{
case WM_CLOSE:
//
// If we can't close, tell the system that we processed the
// message - otherwise it would close us
//
bProcessed = !Close();
break;
}
if (!bProcessed)
rc = wxWindow::OS2WindowProc( uMessage
,wParam
,lParam
);
return rc;
} // end of wxDialog::OS2WindowProc