git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15869 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
1405 lines
42 KiB
C++
1405 lines
42 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: frame.cpp
|
|
// Purpose: wxFrame
|
|
// Author: David Webster
|
|
// Modified by:
|
|
// Created: 10/27/99
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) David Webster
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/defs.h"
|
|
#include "wx/object.h"
|
|
#include "wx/dynarray.h"
|
|
#include "wx/list.h"
|
|
#include "wx/hash.h"
|
|
#include "wx/string.h"
|
|
#include "wx/intl.h"
|
|
#include "wx/log.h"
|
|
#include "wx/event.h"
|
|
#include "wx/setup.h"
|
|
#include "wx/frame.h"
|
|
#include "wx/menu.h"
|
|
#include "wx/app.h"
|
|
#include "wx/utils.h"
|
|
#include "wx/dialog.h"
|
|
#include "wx/settings.h"
|
|
#include "wx/dcclient.h"
|
|
#include "wx/mdi.h"
|
|
#endif // WX_PRECOMP
|
|
|
|
#include "wx/os2/private.h"
|
|
|
|
#if wxUSE_STATUSBAR
|
|
#include "wx/statusbr.h"
|
|
#include "wx/generic/statusbr.h"
|
|
#endif // wxUSE_STATUSBAR
|
|
|
|
#if wxUSE_TOOLBAR
|
|
#include "wx/toolbar.h"
|
|
#endif // wxUSE_TOOLBAR
|
|
|
|
#include "wx/menuitem.h"
|
|
#include "wx/log.h"
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// globals
|
|
// ----------------------------------------------------------------------------
|
|
|
|
extern wxWindowList wxModelessWindows;
|
|
extern wxList WXDLLEXPORT wxPendingDelete;
|
|
|
|
#if wxUSE_MENUS_NATIVE
|
|
extern wxMenu *wxCurrentPopupMenu;
|
|
#endif
|
|
|
|
extern void wxAssociateWinWithHandle( HWND hWnd
|
|
,wxWindowOS2* pWin
|
|
);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// event tables
|
|
// ----------------------------------------------------------------------------
|
|
|
|
BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
|
|
EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
|
|
END_EVENT_TABLE()
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
|
|
|
|
// ============================================================================
|
|
// implementation
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// static class members
|
|
// ----------------------------------------------------------------------------
|
|
#if wxUSE_STATUSBAR
|
|
|
|
#if wxUSE_NATIVE_STATUSBAR
|
|
bool wxFrame::m_bUseNativeStatusBar = TRUE;
|
|
#else
|
|
bool wxFrame::m_bUseNativeStatusBar = FALSE;
|
|
#endif
|
|
|
|
#endif //wxUSE_STATUSBAR
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// creation/destruction
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxFrame::Init()
|
|
{
|
|
m_nFsStatusBarFields = 0;
|
|
m_nFsStatusBarHeight = 0;
|
|
m_nFsToolBarHeight = 0;
|
|
m_hWndToolTip = 0L;
|
|
m_bWasMinimized = FALSE;
|
|
|
|
|
|
m_frameMenuBar = NULL;
|
|
m_frameToolBar = NULL;
|
|
m_frameStatusBar = NULL;
|
|
|
|
m_hTitleBar = NULLHANDLE;
|
|
m_hHScroll = NULLHANDLE;
|
|
m_hVScroll = NULLHANDLE;
|
|
|
|
//
|
|
// Initialize SWP's
|
|
//
|
|
memset(&m_vSwpTitleBar, 0, sizeof(SWP));
|
|
memset(&m_vSwpMenuBar, 0, sizeof(SWP));
|
|
memset(&m_vSwpHScroll, 0, sizeof(SWP));
|
|
memset(&m_vSwpVScroll, 0, sizeof(SWP));
|
|
memset(&m_vSwpStatusBar, 0, sizeof(SWP));
|
|
memset(&m_vSwpToolBar, 0, sizeof(SWP));
|
|
m_bIconized = FALSE;
|
|
|
|
} // end of wxFrame::Init
|
|
|
|
bool wxFrame::Create(
|
|
wxWindow* pParent
|
|
, wxWindowID vId
|
|
, const wxString& rsTitle
|
|
, const wxPoint& rPos
|
|
, const wxSize& rSize
|
|
, long lStyle
|
|
, const wxString& rsName
|
|
)
|
|
{
|
|
if (!wxTopLevelWindow::Create( pParent
|
|
,vId
|
|
,rsTitle
|
|
,rPos
|
|
,rSize
|
|
,lStyle
|
|
,rsName
|
|
))
|
|
return FALSE;
|
|
wxModelessWindows.Append(this);
|
|
return TRUE;
|
|
} // end of wxFrame::Create
|
|
|
|
wxFrame::~wxFrame()
|
|
{
|
|
m_isBeingDeleted = TRUE;
|
|
DeleteAllBars();
|
|
} // end of wxFrame::~wxFrame
|
|
|
|
//
|
|
// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
|
|
//
|
|
void wxFrame::DoGetClientSize(
|
|
int* pX
|
|
, int* pY
|
|
) const
|
|
{
|
|
wxTopLevelWindow::DoGetClientSize( pX
|
|
,pY
|
|
);
|
|
//
|
|
// No need to use statusbar code as in WIN32 as the FORMATFRAME
|
|
// window procedure ensures PM knows about the new frame client
|
|
// size internally. A ::WinQueryWindowRect (that is called in
|
|
// wxWindow's GetClient size from above) is all that is needed!
|
|
//
|
|
} // end of wxFrame::DoGetClientSize
|
|
|
|
//
|
|
// Set the client size (i.e. leave the calculation of borders etc.
|
|
// to wxWindows)
|
|
//
|
|
void wxFrame::DoSetClientSize(
|
|
int nWidth
|
|
, int nHeight
|
|
)
|
|
{
|
|
wxStatusBar* pStatusBar = GetStatusBar();
|
|
|
|
//
|
|
// Statusbars are not part of the OS/2 Client but parent frame
|
|
// so no statusbar consideration
|
|
//
|
|
wxTopLevelWindow::DoSetClientSize( nWidth
|
|
,nHeight
|
|
);
|
|
} // end of wxFrame::DoSetClientSize
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxFrame: various geometry-related functions
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxFrame::Raise()
|
|
{
|
|
wxFrameBase::Raise();
|
|
::WinSetWindowPos( (HWND) GetParent()->GetHWND()
|
|
,HWND_TOP
|
|
,0
|
|
,0
|
|
,0
|
|
,0
|
|
,SWP_ZORDER
|
|
);
|
|
}
|
|
|
|
#if wxUSE_STATUSBAR
|
|
wxStatusBar* wxFrame::OnCreateStatusBar(
|
|
int nNumber
|
|
, long lulStyle
|
|
, wxWindowID vId
|
|
, const wxString& rName
|
|
)
|
|
{
|
|
wxStatusBar* pStatusBar = NULL;
|
|
SWP vSwp;
|
|
ERRORID vError;
|
|
wxString sError;
|
|
|
|
pStatusBar = wxFrameBase::OnCreateStatusBar( nNumber
|
|
,lulStyle
|
|
,vId
|
|
,rName
|
|
);
|
|
|
|
if( !pStatusBar )
|
|
return NULL;
|
|
|
|
wxClientDC vDC(pStatusBar);
|
|
int nY;
|
|
|
|
//
|
|
// Set the height according to the font and the border size
|
|
//
|
|
vDC.SetFont(pStatusBar->GetFont()); // Screws up the menues for some reason
|
|
vDC.GetTextExtent( "X"
|
|
,NULL
|
|
,&nY
|
|
);
|
|
|
|
int nHeight = ((11 * nY) / 10 + 2 * pStatusBar->GetBorderY());
|
|
|
|
pStatusBar->SetSize( -1
|
|
,-1
|
|
,-1
|
|
,nHeight
|
|
);
|
|
|
|
::WinSetParent( pStatusBar->GetHWND()
|
|
,m_hFrame
|
|
,FALSE
|
|
);
|
|
::WinSetOwner( pStatusBar->GetHWND()
|
|
,m_hFrame
|
|
);
|
|
//
|
|
// to show statusbar
|
|
//
|
|
if(::WinIsWindowShowing(m_hFrame))
|
|
::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
|
|
|
|
return pStatusBar;
|
|
} // end of wxFrame::OnCreateStatusBar
|
|
|
|
void wxFrame::PositionStatusBar()
|
|
{
|
|
SWP vSwp;
|
|
ERRORID vError;
|
|
wxString sError;
|
|
|
|
//
|
|
// Native status bar positions itself
|
|
//
|
|
if (m_frameStatusBar)
|
|
{
|
|
int nWidth;
|
|
int nY;
|
|
int nStatbarWidth;
|
|
int nStatbarHeight;
|
|
HWND hWndClient;
|
|
RECTL vRect;
|
|
RECTL vFRect;
|
|
|
|
::WinQueryWindowRect(m_hFrame, &vRect);
|
|
nY = vRect.yTop;
|
|
::WinMapWindowPoints(m_hFrame, HWND_DESKTOP, (PPOINTL)&vRect, 2);
|
|
vFRect = vRect;
|
|
::WinCalcFrameRect(m_hFrame, &vRect, TRUE);
|
|
nWidth = vRect.xRight - vRect.xLeft;
|
|
nY = nY - (vRect.yBottom - vFRect.yBottom);
|
|
|
|
m_frameStatusBar->GetSize( &nStatbarWidth
|
|
,&nStatbarHeight
|
|
);
|
|
|
|
nY= nY - nStatbarHeight;
|
|
//
|
|
// 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( vRect.xLeft - vFRect.xLeft
|
|
,nY
|
|
,nWidth
|
|
,nStatbarHeight
|
|
);
|
|
if (!::WinQueryWindowPos(m_frameStatusBar->GetHWND(), &vSwp))
|
|
{
|
|
vError = ::WinGetLastError(vHabmain);
|
|
sError = wxPMErrorToStr(vError);
|
|
wxLogError("Error setting parent for StautsBar. Error: %s\n", sError);
|
|
return;
|
|
}
|
|
}
|
|
} // end of wxFrame::PositionStatusBar
|
|
#endif // wxUSE_STATUSBAR
|
|
|
|
#if wxUSE_MENUS_NATIVE
|
|
void wxFrame::DetachMenuBar()
|
|
{
|
|
if (m_frameMenuBar)
|
|
{
|
|
m_frameMenuBar->Detach();
|
|
m_frameMenuBar = NULL;
|
|
}
|
|
} // end of wxFrame::DetachMenuBar
|
|
|
|
void wxFrame::SetMenuBar(
|
|
wxMenuBar* pMenuBar
|
|
)
|
|
{
|
|
ERRORID vError;
|
|
wxString sError;
|
|
HWND hTitlebar = NULLHANDLE;
|
|
HWND hHScroll = NULLHANDLE;
|
|
HWND hVScroll = NULLHANDLE;
|
|
HWND hMenuBar = NULLHANDLE;
|
|
SWP vSwp;
|
|
SWP vSwpTitlebar;
|
|
SWP vSwpVScroll;
|
|
SWP vSwpHScroll;
|
|
SWP vSwpMenu;
|
|
|
|
if (!pMenuBar)
|
|
{
|
|
DetachMenuBar();
|
|
|
|
//
|
|
// Actually remove the menu from the frame
|
|
//
|
|
m_hMenu = (WXHMENU)0;
|
|
InternalSetMenuBar();
|
|
}
|
|
else // set new non NULL menu bar
|
|
{
|
|
m_frameMenuBar = NULL;
|
|
|
|
//
|
|
// Can set a menubar several times.
|
|
// TODO: how to prevent a memory leak if you have a currently-unattached
|
|
// menubar? wxWindows assumes that the frame will delete the menu (otherwise
|
|
// there are problems for MDI).
|
|
//
|
|
if (pMenuBar->GetHMenu())
|
|
{
|
|
m_hMenu = pMenuBar->GetHMenu();
|
|
}
|
|
else
|
|
{
|
|
pMenuBar->Detach();
|
|
m_hMenu = pMenuBar->Create();
|
|
if (!m_hMenu)
|
|
return;
|
|
}
|
|
InternalSetMenuBar();
|
|
m_frameMenuBar = pMenuBar;
|
|
pMenuBar->Attach((wxFrame*)this);
|
|
}
|
|
} // end of wxFrame::SetMenuBar
|
|
|
|
void wxFrame::AttachMenuBar(
|
|
wxMenuBar* pMenubar
|
|
)
|
|
{
|
|
wxFrameBase::AttachMenuBar(pMenubar);
|
|
|
|
m_frameMenuBar = pMenubar;
|
|
|
|
if (!pMenubar)
|
|
{
|
|
//
|
|
// Actually remove the menu from the frame
|
|
//
|
|
m_hMenu = (WXHMENU)0;
|
|
InternalSetMenuBar();
|
|
}
|
|
else // Set new non NULL menu bar
|
|
{
|
|
//
|
|
// Can set a menubar several times.
|
|
//
|
|
if (pMenubar->GetHMenu())
|
|
{
|
|
m_hMenu = pMenubar->GetHMenu();
|
|
}
|
|
else
|
|
{
|
|
if (pMenubar->IsAttached())
|
|
pMenubar->Detach();
|
|
|
|
m_hMenu = pMenubar->Create();
|
|
|
|
if (!m_hMenu)
|
|
return;
|
|
}
|
|
InternalSetMenuBar();
|
|
}
|
|
} // end of wxFrame::AttachMenuBar
|
|
|
|
void wxFrame::InternalSetMenuBar()
|
|
{
|
|
ERRORID vError;
|
|
wxString sError;
|
|
//
|
|
// Set the parent and owner of the menubar to be the frame
|
|
//
|
|
if (!::WinSetParent(m_hMenu, m_hFrame, FALSE))
|
|
{
|
|
vError = ::WinGetLastError(vHabmain);
|
|
sError = wxPMErrorToStr(vError);
|
|
wxLogError("Error setting parent for submenu. Error: %s\n", sError);
|
|
}
|
|
|
|
if (!::WinSetOwner(m_hMenu, m_hFrame))
|
|
{
|
|
vError = ::WinGetLastError(vHabmain);
|
|
sError = wxPMErrorToStr(vError);
|
|
wxLogError("Error setting parent for submenu. Error: %s\n", sError);
|
|
}
|
|
::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
|
|
} // end of wxFrame::InternalSetMenuBar
|
|
#endif // wxUSE_MENUS_NATIVE
|
|
|
|
//
|
|
// Responds to colour changes, and passes event on to children
|
|
//
|
|
void wxFrame::OnSysColourChanged(
|
|
wxSysColourChangedEvent& rEvent
|
|
)
|
|
{
|
|
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
|
|
Refresh();
|
|
|
|
#if wxUSE_STATUSBAR
|
|
if (m_frameStatusBar)
|
|
{
|
|
wxSysColourChangedEvent vEvent2;
|
|
|
|
vEvent2.SetEventObject(m_frameStatusBar);
|
|
m_frameStatusBar->GetEventHandler()->ProcessEvent(vEvent2);
|
|
}
|
|
#endif //wxUSE_STATUSBAR
|
|
|
|
//
|
|
// Propagate the event to the non-top-level children
|
|
//
|
|
wxWindow::OnSysColourChanged(rEvent);
|
|
} // end of wxFrame::OnSysColourChanged
|
|
|
|
// Pass TRUE to show full screen, FALSE to restore.
|
|
bool wxFrame::ShowFullScreen(
|
|
bool bShow
|
|
, long lStyle
|
|
)
|
|
{
|
|
if (bShow)
|
|
{
|
|
if (IsFullScreen())
|
|
return FALSE;
|
|
|
|
m_bFsIsShowing = TRUE;
|
|
m_lFsStyle = lStyle;
|
|
|
|
#if wxUSE_TOOLBAR
|
|
wxToolBar* pTheToolBar = GetToolBar();
|
|
#endif //wxUSE_TOOLBAR
|
|
|
|
#if wxUSE_STATUSBAR
|
|
wxStatusBar* pTheStatusBar = GetStatusBar();
|
|
#endif //wxUSE_STATUSBAR
|
|
|
|
int nDummyWidth;
|
|
|
|
#if wxUSE_TOOLBAR
|
|
if (pTheToolBar)
|
|
pTheToolBar->GetSize(&nDummyWidth, &m_nFsToolBarHeight);
|
|
#endif //wxUSE_TOOLBAR
|
|
|
|
#if wxUSE_STATUSBAR
|
|
if (pTheStatusBar)
|
|
pTheStatusBar->GetSize(&nDummyWidth, &m_nFsStatusBarHeight);
|
|
#endif //wxUSE_STATUSBAR
|
|
|
|
#if wxUSE_TOOLBAR
|
|
//
|
|
// Zap the toolbar, menubar, and statusbar
|
|
//
|
|
if ((lStyle & wxFULLSCREEN_NOTOOLBAR) && pTheToolBar)
|
|
{
|
|
pTheToolBar->SetSize(-1,0);
|
|
pTheToolBar->Show(FALSE);
|
|
}
|
|
#endif //wxUSE_TOOLBAR
|
|
|
|
if (lStyle & wxFULLSCREEN_NOMENUBAR)
|
|
{
|
|
::WinSetParent(m_hMenu, m_hFrame, FALSE);
|
|
::WinSetOwner(m_hMenu, m_hFrame);
|
|
::WinSendMsg((HWND)m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
|
|
}
|
|
|
|
#if wxUSE_STATUSBAR
|
|
//
|
|
// Save the number of fields in the statusbar
|
|
//
|
|
if ((lStyle & wxFULLSCREEN_NOSTATUSBAR) && pTheStatusBar)
|
|
{
|
|
m_nFsStatusBarFields = pTheStatusBar->GetFieldsCount();
|
|
SetStatusBar((wxStatusBar*) NULL);
|
|
delete pTheStatusBar;
|
|
}
|
|
else
|
|
m_nFsStatusBarFields = 0;
|
|
#endif //wxUSE_STATUSBAR
|
|
|
|
//
|
|
// Zap the frame borders
|
|
//
|
|
|
|
//
|
|
// Save the 'normal' window style
|
|
//
|
|
m_lFsOldWindowStyle = ::WinQueryWindowULong(m_hFrame, QWL_STYLE);
|
|
|
|
//
|
|
// Save the old position, width & height, maximize state
|
|
//
|
|
m_vFsOldSize = GetRect();
|
|
m_bFsIsMaximized = IsMaximized();
|
|
|
|
//
|
|
// Decide which window style flags to turn off
|
|
//
|
|
LONG lNewStyle = m_lFsOldWindowStyle;
|
|
LONG lOffFlags = 0;
|
|
|
|
if (lStyle & wxFULLSCREEN_NOBORDER)
|
|
lOffFlags |= FCF_BORDER;
|
|
if (lStyle & wxFULLSCREEN_NOCAPTION)
|
|
lOffFlags |= (FCF_TASKLIST | FCF_SYSMENU);
|
|
|
|
lNewStyle &= (~lOffFlags);
|
|
|
|
//
|
|
// Change our window style to be compatible with full-screen mode
|
|
//
|
|
::WinSetWindowULong((HWND)m_hFrame, QWL_STYLE, (ULONG)lNewStyle);
|
|
|
|
//
|
|
// Resize to the size of the desktop
|
|
int nWidth;
|
|
int nHeight;
|
|
|
|
RECTL vRect;
|
|
|
|
::WinQueryWindowRect(HWND_DESKTOP, &vRect);
|
|
nWidth = vRect.xRight - vRect.xLeft;
|
|
//
|
|
// Rmember OS/2 is backwards!
|
|
//
|
|
nHeight = vRect.yTop - vRect.yBottom;
|
|
|
|
SetSize( nWidth
|
|
,nHeight
|
|
);
|
|
|
|
//
|
|
// Now flush the window style cache and actually go full-screen
|
|
//
|
|
::WinSetWindowPos( (HWND) GetParent()->GetHWND()
|
|
,HWND_TOP
|
|
,0
|
|
,0
|
|
,nWidth
|
|
,nHeight
|
|
,SWP_SIZE | SWP_SHOW
|
|
);
|
|
|
|
wxSizeEvent vEvent( wxSize( nWidth
|
|
,nHeight
|
|
)
|
|
,GetId()
|
|
);
|
|
|
|
GetEventHandler()->ProcessEvent(vEvent);
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (!IsFullScreen())
|
|
return FALSE;
|
|
|
|
m_bFsIsShowing = FALSE;
|
|
|
|
#if wxUSE_TOOLBAR
|
|
wxToolBar* pTheToolBar = GetToolBar();
|
|
|
|
//
|
|
// Restore the toolbar, menubar, and statusbar
|
|
//
|
|
if (pTheToolBar && (m_lFsStyle & wxFULLSCREEN_NOTOOLBAR))
|
|
{
|
|
pTheToolBar->SetSize(-1, m_nFsToolBarHeight);
|
|
pTheToolBar->Show(TRUE);
|
|
}
|
|
#endif //wxUSE_TOOLBAR
|
|
|
|
#if wxUSE_STATUSBAR
|
|
if ((m_lFsStyle & wxFULLSCREEN_NOSTATUSBAR) && (m_nFsStatusBarFields > 0))
|
|
{
|
|
CreateStatusBar(m_nFsStatusBarFields);
|
|
// PositionStatusBar();
|
|
}
|
|
#endif //wxUSE_STATUSBAR
|
|
|
|
if ((m_lFsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
|
|
{
|
|
::WinSetParent(m_hMenu, m_hFrame, FALSE);
|
|
::WinSetOwner(m_hMenu, m_hFrame);
|
|
::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
|
|
}
|
|
Maximize(m_bFsIsMaximized);
|
|
|
|
::WinSetWindowULong( m_hFrame
|
|
,QWL_STYLE
|
|
,(ULONG)m_lFsOldWindowStyle
|
|
);
|
|
::WinSetWindowPos( (HWND) GetParent()->GetHWND()
|
|
,HWND_TOP
|
|
,m_vFsOldSize.x
|
|
,m_vFsOldSize.y
|
|
,m_vFsOldSize.width
|
|
,m_vFsOldSize.height
|
|
,SWP_SIZE | SWP_SHOW
|
|
);
|
|
}
|
|
return wxFrameBase::ShowFullScreen(bShow, lStyle);
|
|
} // end of wxFrame::ShowFullScreen
|
|
|
|
//
|
|
// Frame window
|
|
//
|
|
// ----------------------------------------------------------------------------
|
|
// wxFrame size management: we exclude the areas taken by menu/status/toolbars
|
|
// from the client area, so the client area is what's really available for the
|
|
// frame contents
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Checks if there is a toolbar, and returns the first free client position
|
|
wxPoint wxFrame::GetClientAreaOrigin() const
|
|
{
|
|
wxPoint vPoint(0, 0);
|
|
|
|
#if wxUSE_TOOLBAR
|
|
if (GetToolBar())
|
|
{
|
|
int nWidth;
|
|
int nHeight;
|
|
|
|
GetToolBar()->GetSize( &nWidth
|
|
,&nHeight
|
|
);
|
|
|
|
if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
|
|
{
|
|
vPoint.x += nWidth;
|
|
}
|
|
else
|
|
{
|
|
// PM is backwards from windows
|
|
vPoint.y += nHeight;
|
|
}
|
|
}
|
|
#endif //wxUSE_TOOLBAR
|
|
return vPoint;
|
|
} // end of wxFrame::GetClientAreaOrigin
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// tool/status bar stuff
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#if wxUSE_TOOLBAR
|
|
|
|
wxToolBar* wxFrame::CreateToolBar(
|
|
long lStyle
|
|
, wxWindowID vId
|
|
, const wxString& rName
|
|
)
|
|
{
|
|
if (wxFrameBase::CreateToolBar( lStyle
|
|
,vId
|
|
,rName
|
|
))
|
|
{
|
|
PositionToolBar();
|
|
}
|
|
return m_frameToolBar;
|
|
} // end of wxFrame::CreateToolBar
|
|
|
|
void wxFrame::PositionToolBar()
|
|
{
|
|
HWND hWndClient;
|
|
RECTL vRect;
|
|
|
|
::WinQueryWindowRect(GetHwnd(), &vRect);
|
|
|
|
#if wxUSE_STATUSBAR
|
|
if (GetStatusBar())
|
|
{
|
|
int nStatusX;
|
|
int nStatusY;
|
|
|
|
GetStatusBar()->GetClientSize( &nStatusX
|
|
,&nStatusY
|
|
);
|
|
// PM is backwards from windows
|
|
vRect.yBottom += nStatusY;
|
|
}
|
|
#endif // wxUSE_STATUSBAR
|
|
|
|
if ( m_frameToolBar )
|
|
{
|
|
int nToolbarWidth;
|
|
int nToolbarHeight;
|
|
|
|
m_frameToolBar->GetSize( &nToolbarWidth
|
|
,&nToolbarHeight
|
|
);
|
|
|
|
if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
|
|
{
|
|
nToolbarHeight = vRect.yBottom;
|
|
}
|
|
else
|
|
{
|
|
nToolbarWidth = vRect.xRight;
|
|
}
|
|
|
|
//
|
|
// Use the 'real' PM position here
|
|
//
|
|
GetToolBar()->SetSize( 0
|
|
,0
|
|
,nToolbarWidth
|
|
,nToolbarHeight
|
|
,wxSIZE_NO_ADJUSTMENTS
|
|
);
|
|
}
|
|
} // end of wxFrame::PositionToolBar
|
|
#endif // wxUSE_TOOLBAR
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// frame state (iconized/maximized/...)
|
|
// ----------------------------------------------------------------------------
|
|
|
|
//
|
|
// propagate our state change to all child frames: this allows us to emulate X
|
|
// Windows behaviour where child frames float independently of the parent one
|
|
// on the desktop, but are iconized/restored with it
|
|
//
|
|
void wxFrame::IconizeChildFrames(
|
|
bool bIconize
|
|
)
|
|
{
|
|
for (wxWindowList::Node* pNode = GetChildren().GetFirst();
|
|
pNode;
|
|
pNode = pNode->GetNext() )
|
|
{
|
|
wxWindow* pWin = pNode->GetData();
|
|
wxFrame* pFrame = wxDynamicCast(pWin, wxFrame);
|
|
|
|
if ( pFrame
|
|
#if wxUSE_MDI_ARCHITECTURE
|
|
&& !wxDynamicCast(pFrame, wxMDIChildFrame)
|
|
#endif // wxUSE_MDI_ARCHITECTURE
|
|
)
|
|
{
|
|
//
|
|
// We don't want to restore the child frames which had been
|
|
// iconized even before we were iconized, so save the child frame
|
|
// status when iconizing the parent frame and check it when
|
|
// restoring it.
|
|
//
|
|
if (bIconize)
|
|
{
|
|
pFrame->m_bWasMinimized = pFrame->IsIconized();
|
|
}
|
|
|
|
//
|
|
// This test works for both iconizing and restoring
|
|
//
|
|
if (!pFrame->m_bWasMinimized)
|
|
pFrame->Iconize(bIconize);
|
|
}
|
|
}
|
|
} // end of wxFrame::IconizeChildFrames
|
|
|
|
WXHICON wxFrame::GetDefaultIcon() const
|
|
{
|
|
return (WXHICON)(wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON
|
|
: wxDEFAULT_FRAME_ICON);
|
|
}
|
|
// ===========================================================================
|
|
// message processing
|
|
// ===========================================================================
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// preprocessing
|
|
// ---------------------------------------------------------------------------
|
|
bool wxFrame::OS2TranslateMessage(
|
|
WXMSG* pMsg
|
|
)
|
|
{
|
|
//
|
|
// try the menu bar accels
|
|
//
|
|
wxMenuBar* pMenuBar = GetMenuBar();
|
|
|
|
if (!pMenuBar)
|
|
return FALSE;
|
|
|
|
#if wxUSE_ACCEL && wxUSE_MENUS_NATIVE
|
|
const wxAcceleratorTable& rAcceleratorTable = pMenuBar->GetAccelTable();
|
|
return rAcceleratorTable.Translate(GetHWND(), pMsg);
|
|
#else
|
|
return FALSE;
|
|
#endif //wxUSE_ACCEL
|
|
} // end of wxFrame::OS2TranslateMessage
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// our private (non virtual) message handlers
|
|
// ---------------------------------------------------------------------------
|
|
bool wxFrame::HandlePaint()
|
|
{
|
|
RECTL vRect;
|
|
|
|
if (::WinQueryUpdateRect(GetHWND(), &vRect))
|
|
{
|
|
if (m_bIconized)
|
|
{
|
|
//
|
|
// Icons in PM are the same as "pointers"
|
|
//
|
|
const wxIcon& vIcon = GetIcon();
|
|
HPOINTER hIcon;
|
|
|
|
if (vIcon.Ok())
|
|
hIcon = (HPOINTER)::WinSendMsg(m_hFrame, WM_QUERYICON, 0L, 0L);
|
|
else
|
|
hIcon = (HPOINTER)m_hDefaultIcon;
|
|
|
|
//
|
|
// Hold a pointer to the dc so long as the OnPaint() message
|
|
// is being processed
|
|
//
|
|
RECTL vRect2;
|
|
HPS hPs = ::WinBeginPaint(GetHwnd(), NULLHANDLE, &vRect2);
|
|
|
|
//
|
|
// Erase background before painting or we get white background
|
|
//
|
|
OS2DefWindowProc(WM_ERASEBACKGROUND, (MPARAM)hPs, (MPARAM)&vRect2);
|
|
|
|
if (hIcon)
|
|
{
|
|
HWND hWndClient;
|
|
RECTL vRect3;
|
|
|
|
::WinQueryWindowRect(GetHwnd(), &vRect3);
|
|
|
|
static const int nIconWidth = 32;
|
|
static const int nIconHeight = 32;
|
|
int nIconX = (int)((vRect3.xRight - nIconWidth)/2);
|
|
int nIconY = (int)((vRect3.yBottom + nIconHeight)/2);
|
|
|
|
::WinDrawPointer(hPs, nIconX, nIconY, hIcon, DP_NORMAL);
|
|
}
|
|
::WinEndPaint(hPs);
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (!wxWindow::HandlePaint())
|
|
{
|
|
HPS hPS;
|
|
RECTL vRect;
|
|
|
|
hPS = ::WinBeginPaint( GetHwnd()
|
|
,NULLHANDLE
|
|
,&vRect
|
|
);
|
|
if(hPS)
|
|
{
|
|
::GpiCreateLogColorTable( hPS
|
|
,0L
|
|
,LCOLF_CONSECRGB
|
|
,0L
|
|
,(LONG)wxTheColourDatabase->m_nSize
|
|
,(PLONG)wxTheColourDatabase->m_palTable
|
|
);
|
|
::GpiCreateLogColorTable( hPS
|
|
,0L
|
|
,LCOLF_RGB
|
|
,0L
|
|
,0L
|
|
,NULL
|
|
);
|
|
|
|
::WinFillRect( hPS
|
|
,&vRect
|
|
,GetBackgroundColour().GetPixel()
|
|
);
|
|
::WinEndPaint(hPS);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// nothing to paint - processed
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
} // end of wxFrame::HandlePaint
|
|
|
|
bool wxFrame::HandleSize(
|
|
int nX
|
|
, int nY
|
|
, WXUINT nId
|
|
)
|
|
{
|
|
bool bProcessed = FALSE;
|
|
|
|
switch (nId)
|
|
{
|
|
case kSizeNormal:
|
|
//
|
|
// Only do it it if we were iconized before, otherwise resizing the
|
|
// parent frame has a curious side effect of bringing it under it's
|
|
// children
|
|
if (!m_bIconized )
|
|
break;
|
|
|
|
//
|
|
// restore all child frames too
|
|
//
|
|
IconizeChildFrames(FALSE);
|
|
(void)SendIconizeEvent(FALSE);
|
|
|
|
//
|
|
// fall through
|
|
//
|
|
|
|
case kSizeMax:
|
|
m_bIconized = FALSE;
|
|
break;
|
|
|
|
case kSizeMin:
|
|
//
|
|
// Iconize all child frames too
|
|
//
|
|
IconizeChildFrames(TRUE);
|
|
(void)SendIconizeEvent();
|
|
m_bIconized = TRUE;
|
|
break;
|
|
}
|
|
|
|
if (!m_bIconized)
|
|
{
|
|
//
|
|
// forward WM_SIZE to status bar control
|
|
//
|
|
#if wxUSE_NATIVE_STATUSBAR
|
|
if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
|
|
{
|
|
wxSizeEvent vEvent( wxSize( nX
|
|
,nY
|
|
)
|
|
,m_frameStatusBar->GetId()
|
|
);
|
|
|
|
vEvent.SetEventObject(m_frameStatusBar);
|
|
m_frameStatusBar->OnSize(vEvent);
|
|
}
|
|
#endif // wxUSE_NATIVE_STATUSBAR
|
|
|
|
PositionStatusBar();
|
|
#if wxUSE_TOOLBAR
|
|
PositionToolBar();
|
|
#endif // wxUSE_TOOLBAR
|
|
|
|
bProcessed = wxWindow::HandleSize( nX
|
|
,nY
|
|
,nId
|
|
);
|
|
}
|
|
return bProcessed;
|
|
} // end of wxFrame::HandleSize
|
|
|
|
bool wxFrame::HandleCommand(
|
|
WXWORD nId
|
|
, WXWORD nCmd
|
|
, WXHWND hControl
|
|
)
|
|
{
|
|
if (hControl)
|
|
{
|
|
//
|
|
// In case it's e.g. a toolbar.
|
|
//
|
|
wxWindow* pWin = wxFindWinFromHandle(hControl);
|
|
|
|
if (pWin)
|
|
return pWin->OS2Command( nCmd
|
|
,nId
|
|
);
|
|
}
|
|
|
|
//
|
|
// Handle here commands from menus and accelerators
|
|
//
|
|
if (nCmd == CMDSRC_MENU || nCmd == CMDSRC_ACCELERATOR)
|
|
{
|
|
#if wxUSE_MENUS_NATIVE
|
|
if (wxCurrentPopupMenu)
|
|
{
|
|
wxMenu* pPopupMenu = wxCurrentPopupMenu;
|
|
|
|
wxCurrentPopupMenu = NULL;
|
|
|
|
return pPopupMenu->OS2Command( nCmd
|
|
,nId
|
|
);
|
|
return TRUE;
|
|
}
|
|
#endif
|
|
|
|
if (ProcessCommand(nId))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
} // end of wxFrame::HandleCommand
|
|
|
|
bool wxFrame::HandleMenuSelect(
|
|
WXWORD nItem
|
|
, WXWORD nFlags
|
|
, WXHMENU hMenu
|
|
)
|
|
{
|
|
if( !nFlags )
|
|
{
|
|
MENUITEM mItem;
|
|
MRESULT rc;
|
|
|
|
rc = ::WinSendMsg(hMenu, MM_QUERYITEM, MPFROM2SHORT(nItem, TRUE), (MPARAM)&mItem);
|
|
|
|
if(rc && !(mItem.afStyle & (MIS_SUBMENU | MIS_SEPARATOR)))
|
|
{
|
|
wxMenuEvent vEvent(wxEVT_MENU_HIGHLIGHT, nItem);
|
|
|
|
vEvent.SetEventObject(this);
|
|
GetEventHandler()->ProcessEvent(vEvent); // return value would be ignored by PM
|
|
}
|
|
else
|
|
{
|
|
DoGiveHelp(wxEmptyString, FALSE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
} // end of wxFrame::HandleMenuSelect
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Main Frame window proc
|
|
// ---------------------------------------------------------------------------
|
|
MRESULT EXPENTRY wxFrameMainWndProc(
|
|
HWND hWnd
|
|
, ULONG ulMsg
|
|
, MPARAM wParam
|
|
, MPARAM lParam
|
|
)
|
|
{
|
|
MRESULT rc = (MRESULT)0;
|
|
bool bProcessed = FALSE;
|
|
wxFrame* pWnd = NULL;
|
|
|
|
pWnd = (wxFrame*) wxFindWinFromHandle((WXHWND) hWnd);
|
|
switch (ulMsg)
|
|
{
|
|
case WM_QUERYFRAMECTLCOUNT:
|
|
if(pWnd && pWnd->m_fnOldWndProc)
|
|
{
|
|
USHORT uItemCount = SHORT1FROMMR(pWnd->m_fnOldWndProc(hWnd, ulMsg, wParam, lParam));
|
|
|
|
rc = MRFROMSHORT(uItemCount);
|
|
}
|
|
break;
|
|
|
|
case WM_FORMATFRAME:
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
// Applications that subclass frame controls may find that the frame is already
|
|
// subclassed the number of frame controls is variable.
|
|
// The WM_FORMATFRAME and WM_QUERYFRAMECTLCOUNT messages must always be
|
|
// subclassed by calling the previous window procedure and modifying its result.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
{
|
|
int nItemCount;
|
|
int i;
|
|
PSWP pSWP = NULL;
|
|
SWP vSwpStb;
|
|
RECTL vRectl;
|
|
RECTL vRstb;
|
|
int nHeight=0;
|
|
|
|
pSWP = (PSWP)PVOIDFROMMP(wParam);
|
|
nItemCount = SHORT1FROMMR(pWnd->m_fnOldWndProc(hWnd, ulMsg, wParam, lParam));
|
|
if(pWnd->m_frameStatusBar)
|
|
{
|
|
::WinQueryWindowRect(pWnd->m_frameStatusBar->GetHWND(), &vRstb);
|
|
pWnd->m_frameStatusBar->GetSize(NULL, &nHeight);
|
|
::WinQueryWindowRect(pWnd->m_hFrame, &vRectl);
|
|
::WinMapWindowPoints(pWnd->m_hFrame, HWND_DESKTOP, (PPOINTL)&vRectl, 2);
|
|
vRstb = vRectl;
|
|
::WinCalcFrameRect(pWnd->m_hFrame, &vRectl, TRUE);
|
|
|
|
vSwpStb.x = vRectl.xLeft - vRstb.xLeft;
|
|
vSwpStb.y = vRectl.yBottom - vRstb.yBottom;
|
|
vSwpStb.cx = vRectl.xRight - vRectl.xLeft - 1; //?? -1 ??
|
|
vSwpStb.cy = nHeight;
|
|
vSwpStb.fl = SWP_SIZE |SWP_MOVE | SWP_SHOW;
|
|
vSwpStb.hwnd = pWnd->m_frameStatusBar->GetHWND();
|
|
vSwpStb.hwndInsertBehind = HWND_TOP;
|
|
}
|
|
::WinQueryWindowRect(pWnd->m_hFrame, &vRectl);
|
|
::WinMapWindowPoints(pWnd->m_hFrame, HWND_DESKTOP, (PPOINTL)&vRectl, 2);
|
|
::WinCalcFrameRect(pWnd->m_hFrame, &vRectl, TRUE);
|
|
::WinMapWindowPoints(HWND_DESKTOP, pWnd->m_hFrame, (PPOINTL)&vRectl, 2);
|
|
for(i = 0; i < nItemCount; i++)
|
|
{
|
|
if(pWnd->m_hWnd && pSWP[i].hwnd == pWnd->m_hWnd)
|
|
{
|
|
pSWP[i].x = vRectl.xLeft;
|
|
pSWP[i].y = vRectl.yBottom + nHeight;
|
|
pSWP[i].cx = vRectl.xRight - vRectl.xLeft;
|
|
pSWP[i].cy = vRectl.yTop - vRectl.yBottom - nHeight;
|
|
pSWP[i].fl = SWP_SIZE | SWP_MOVE | SWP_SHOW;
|
|
pSWP[i].hwndInsertBehind = HWND_TOP;
|
|
}
|
|
}
|
|
bProcessed = TRUE;
|
|
rc = MRFROMSHORT(nItemCount);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if(pWnd && pWnd->m_fnOldWndProc)
|
|
rc = pWnd->m_fnOldWndProc(hWnd, ulMsg, wParam, lParam);
|
|
else
|
|
rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
|
|
}
|
|
return rc;
|
|
} // end of wxFrameMainWndProc
|
|
|
|
MRESULT EXPENTRY wxFrameWndProc(
|
|
HWND hWnd
|
|
, ULONG ulMsg
|
|
, MPARAM wParam
|
|
, MPARAM lParam
|
|
)
|
|
{
|
|
//
|
|
// Trace all ulMsgs - useful for the debugging
|
|
//
|
|
HWND parentHwnd;
|
|
wxFrame* pWnd = NULL;
|
|
|
|
parentHwnd = WinQueryWindow(hWnd,QW_PARENT);
|
|
pWnd = (wxFrame*) wxFindWinFromHandle((WXHWND) hWnd);
|
|
|
|
//
|
|
// When we get the first message for the HWND we just created, we associate
|
|
// it with wxWindow stored in wxWndHook
|
|
//
|
|
|
|
MRESULT rc = (MRESULT)0;
|
|
bool bProcessed = FALSE;
|
|
|
|
//
|
|
// Stop right here if we don't have a valid handle in our wxWindow object.
|
|
//
|
|
if (pWnd && !pWnd->GetHWND())
|
|
{
|
|
pWnd->SetHWND((WXHWND) hWnd);
|
|
rc = pWnd->OS2DefWindowProc(ulMsg, wParam, lParam );
|
|
pWnd->SetHWND(0);
|
|
}
|
|
else
|
|
{
|
|
if (pWnd)
|
|
rc = pWnd->OS2WindowProc(ulMsg, wParam, lParam);
|
|
else
|
|
rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
|
|
}
|
|
return rc;
|
|
} // end of wxFrameWndProc
|
|
|
|
MRESULT wxFrame::OS2WindowProc(
|
|
WXUINT uMessage
|
|
, WXWPARAM wParam
|
|
, WXLPARAM lParam
|
|
)
|
|
{
|
|
MRESULT mRc = 0L;
|
|
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;
|
|
|
|
case WM_PAINT:
|
|
bProcessed = HandlePaint();
|
|
mRc = (MRESULT)FALSE;
|
|
break;
|
|
|
|
case WM_ERASEBACKGROUND:
|
|
//
|
|
// Returning TRUE to requests PM to paint the window background
|
|
// in SYSCLR_WINDOW. We capture this here because the PS returned
|
|
// in Frames is the PS for the whole frame, which we can't really
|
|
// use at all. If you want to paint a different background, do it
|
|
// in an OnPaint using a wxPaintDC.
|
|
//
|
|
mRc = (MRESULT)(TRUE);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
WORD wId;
|
|
WORD wCmd;
|
|
WXHWND hWnd;
|
|
|
|
UnpackCommand( (WXWPARAM)wParam
|
|
,(WXLPARAM)lParam
|
|
,&wId
|
|
,&hWnd
|
|
,&wCmd
|
|
);
|
|
|
|
bProcessed = HandleCommand( wId
|
|
,wCmd
|
|
,(WXHWND)hWnd
|
|
);
|
|
}
|
|
break;
|
|
|
|
case WM_MENUSELECT:
|
|
{
|
|
WXWORD wItem;
|
|
WXWORD wFlags;
|
|
WXHMENU hMenu;
|
|
|
|
UnpackMenuSelect( wParam
|
|
,lParam
|
|
,&wItem
|
|
,&wFlags
|
|
,&hMenu
|
|
);
|
|
bProcessed = HandleMenuSelect( wItem
|
|
,wFlags
|
|
,hMenu
|
|
);
|
|
mRc = (MRESULT)TRUE;
|
|
}
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
{
|
|
SHORT nScxold = SHORT1FROMMP(wParam); // Old horizontal size.
|
|
SHORT nScyold = SHORT2FROMMP(wParam); // Old vertical size.
|
|
SHORT nScxnew = SHORT1FROMMP(lParam); // New horizontal size.
|
|
SHORT nScynew = SHORT2FROMMP(lParam); // New vertical size.
|
|
|
|
lParam = MRFROM2SHORT( nScxnew - 20
|
|
,nScynew - 30
|
|
);
|
|
}
|
|
bProcessed = HandleSize(LOWORD(lParam), HIWORD(lParam), (WXUINT)wParam);
|
|
mRc = (MRESULT)FALSE;
|
|
break;
|
|
|
|
case CM_QUERYDRAGIMAGE:
|
|
{
|
|
const wxIcon& vIcon = GetIcon();
|
|
HPOINTER hIcon;
|
|
|
|
if (vIcon.Ok())
|
|
hIcon = (HPOINTER)::WinSendMsg(GetHWND(), WM_QUERYICON, 0L, 0L);
|
|
else
|
|
hIcon = (HPOINTER)m_hDefaultIcon;
|
|
mRc = (MRESULT)hIcon;
|
|
bProcessed = mRc != 0;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!bProcessed )
|
|
mRc = wxWindow::OS2WindowProc( uMessage
|
|
,wParam
|
|
,lParam
|
|
);
|
|
return (MRESULT)mRc;
|
|
} // wxFrame::OS2WindowProc
|
|
|
|
void wxFrame::SetClient(WXHWND c_Hwnd)
|
|
{
|
|
// Duh...nothing to do under OS/2
|
|
}
|
|
|
|
void wxFrame::SetClient(
|
|
wxWindow* pWindow
|
|
)
|
|
{
|
|
wxWindow* pOldClient = this->GetClient();
|
|
bool bClientHasFocus = pOldClient && (pOldClient == wxWindow::FindFocus());
|
|
|
|
if(pOldClient == pWindow) // nothing to do
|
|
return;
|
|
if(pWindow == NULL) // just need to remove old client
|
|
{
|
|
if(pOldClient == NULL) // nothing to do
|
|
return;
|
|
|
|
if(bClientHasFocus )
|
|
this->SetFocus();
|
|
|
|
pOldClient->Enable( FALSE );
|
|
pOldClient->Show( FALSE );
|
|
::WinSetWindowUShort(pOldClient->GetHWND(), QWS_ID, (USHORT)pOldClient->GetId());
|
|
// to avoid OS/2 bug need to update frame
|
|
::WinSendMsg((HWND)this->GetFrame(), WM_UPDATEFRAME, (MPARAM)~0, 0);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Else need to change client
|
|
//
|
|
if(bClientHasFocus)
|
|
this->SetFocus();
|
|
|
|
::WinEnableWindowUpdate((HWND)GetHWND(), FALSE);
|
|
if(pOldClient)
|
|
{
|
|
pOldClient->Enable(FALSE);
|
|
pOldClient->Show(FALSE);
|
|
::WinSetWindowUShort(pOldClient->GetHWND(), QWS_ID, (USHORT)pOldClient->GetId());
|
|
}
|
|
pWindow->Reparent(this);
|
|
::WinSetWindowUShort(pWindow->GetHWND(), QWS_ID, FID_CLIENT);
|
|
::WinEnableWindowUpdate((HWND)GetHWND(), TRUE);
|
|
pWindow->Enable();
|
|
pWindow->Show(); // ensure client is showing
|
|
if( this->IsShown() )
|
|
{
|
|
this->Show();
|
|
::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
|
|
}
|
|
}
|
|
|
|
wxWindow* wxFrame::GetClient()
|
|
{
|
|
return wxFindWinFromHandle((WXHWND)::WinWindowFromID(m_hFrame, FID_CLIENT));
|
|
}
|