#pragma hdrstop
#endif
-#if wxUSE_MDI_ARCHITECTURE && !defined(__WXUNIVERSAL__)
+#if wxUSE_MDI && !defined(__WXUNIVERSAL__)
#ifndef WX_PRECOMP
#include "wx/setup.h"
// global variables
// ---------------------------------------------------------------------------
-extern wxWindowList wxModelessWindows; // from dialog.cpp
extern wxMenu *wxCurrentPopupMenu;
extern const wxChar *wxMDIFrameClassName; // from app.cpp
// constants
// ---------------------------------------------------------------------------
-static const int IDM_WINDOWTILE = 4001;
static const int IDM_WINDOWTILEHOR = 4001;
static const int IDM_WINDOWCASCADE = 4002;
static const int IDM_WINDOWICONS = 4003;
static const int wxFIRST_MDI_CHILD = 4100;
static const int wxLAST_MDI_CHILD = 4600;
-// Status border dimensions
-static const int wxTHICK_LINE_BORDER = 3;
-static const int wxTHICK_LINE_WIDTH = 1;
-
// ---------------------------------------------------------------------------
// private functions
// ---------------------------------------------------------------------------
if ( parent )
parent->AddChild(this);
- if ( id > -1 )
+ if ( id != wxID_ANY )
m_windowId = id;
else
m_windowId = NewControlId();
return false;
}
- wxModelessWindows.Append(this);
-
// unlike (almost?) all other windows, frames are created hidden
m_isShown = false;
wxMDIParentFrame::~wxMDIParentFrame()
{
- DestroyChildren();
-
- // already delete by DestroyChildren()
+ // see comment in ~wxMDIChildFrame
+#if wxUSE_TOOLBAR
m_frameToolBar = NULL;
+#endif
+#if wxUSE_STATUSBAR
m_frameStatusBar = NULL;
+#endif // wxUSE_STATUSBAR
+
+ DestroyChildren();
if (m_windowMenu)
{
}
}
+void wxMDIParentFrame::DoMenuUpdates(wxMenu* menu)
+{
+ wxMDIChildFrame *child = GetActiveChild();
+ if ( child )
+ {
+ wxEvtHandler* source = child->GetEventHandler();
+ wxMenuBar* bar = child->GetMenuBar();
+
+ if (menu)
+ {
+ menu->UpdateUI(source);
+ }
+ else
+ {
+ if ( bar != NULL )
+ {
+ int nCount = bar->GetMenuCount();
+ for (int n = 0; n < nCount; n++)
+ bar->GetMenu(n)->UpdateUI(source);
+ }
+ }
+ }
+ else
+ {
+ wxFrameBase::DoMenuUpdates(menu);
+ }
+}
+
void wxMDIParentFrame::OnSize(wxSizeEvent&)
{
if ( GetClientWindow() )
::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDICASCADE, 0, 0);
}
-// TODO: add a direction argument (hor/vert)
-void wxMDIParentFrame::Tile()
+void wxMDIParentFrame::Tile(wxOrientation orient)
{
- ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDITILE, MDITILE_HORIZONTAL, 0);
+ wxASSERT_MSG( orient == wxHORIZONTAL || orient == wxVERTICAL,
+ _T("invalid orientation value") );
+
+ ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDITILE,
+ orient == wxHORIZONTAL ? MDITILE_HORIZONTAL
+ : MDITILE_VERTICAL, 0);
}
void wxMDIParentFrame::ArrangeIcons()
// the MDI parent frame window proc
// ---------------------------------------------------------------------------
-long wxMDIParentFrame::MSWWindowProc(WXUINT message,
+WXLRESULT wxMDIParentFrame::MSWWindowProc(WXUINT message,
WXWPARAM wParam,
WXLPARAM lParam)
{
- long rc = 0;
+ WXLRESULT rc = 0;
bool processed = false;
switch ( message )
break;
case WM_SIZE:
- // as we don't (usually) resize the MDI client to exactly fit the
- // client area (we put it below the toolbar, above statusbar &c),
- // we should not pass this one to DefFrameProc
+ // though we don't (usually) resize the MDI client to exactly fit the
+ // client area we need to pass this one to DefFrameProc to allow the children to show
break;
}
return false;
}
-long wxMDIParentFrame::MSWDefWindowProc(WXUINT message,
+WXLRESULT wxMDIParentFrame::MSWDefWindowProc(WXUINT message,
WXWPARAM wParam,
WXLPARAM lParam)
{
void wxMDIChildFrame::Init()
{
m_needsResize = true;
+ m_needsInitialShow = true;
}
bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
const wxString& name)
{
SetName(name);
- wxWindowBase::Show(true); // MDI child frame starts off shown
- if ( id > -1 )
+ if ( id != wxID_ANY )
m_windowId = id;
else
m_windowId = (int)NewControlId();
MDICREATESTRUCT mcs;
- mcs.szClass = style & wxNO_FULL_REPAINT_ON_RESIZE
- ? wxMDIChildFrameClassNameNoRedraw
- : wxMDIChildFrameClassName;
+ mcs.szClass = style & wxFULL_REPAINT_ON_RESIZE
+ ? wxMDIChildFrameClassName
+ : wxMDIChildFrameClassNameNoRedraw;
mcs.szTitle = title;
mcs.hOwner = wxGetInstance();
- if (x > -1)
+ if (x != wxDefaultCoord)
mcs.x = x;
else
mcs.x = CW_USEDEFAULT;
- if (y > -1)
+ if (y != wxDefaultCoord)
mcs.y = y;
else
mcs.y = CW_USEDEFAULT;
- if (width > -1)
+ if (width != wxDefaultCoord)
mcs.cx = width;
else
mcs.cx = CW_USEDEFAULT;
- if (height > -1)
+ if (height != wxDefaultCoord)
mcs.cy = height;
else
mcs.cy = CW_USEDEFAULT;
- DWORD msflags = WS_OVERLAPPED | WS_CLIPCHILDREN | WS_THICKFRAME | WS_VISIBLE ;
+ DWORD msflags = WS_OVERLAPPED | WS_CLIPCHILDREN;
if (style & wxMINIMIZE_BOX)
msflags |= WS_MINIMIZEBOX;
if (style & wxMAXIMIZE_BOX)
wxAssociateWinWithHandle((HWND) GetHWND(), this);
- wxModelessWindows.Append(this);
-
return true;
}
wxMDIChildFrame::~wxMDIChildFrame()
{
- DestroyChildren();
-
- // already deleted by DestroyChildren()
+ // will be destroyed by DestroyChildren() but reset them before calling it
+ // to avoid using dangling pointers if a callback comes in the meanwhile
+#if wxUSE_TOOLBAR
m_frameToolBar = NULL;
+#endif
+#if wxUSE_STATUSBAR
m_frameStatusBar = NULL;
+#endif // wxUSE_STATUSBAR
+
+ DestroyChildren();
RemoveWindowMenu(NULL, m_hMenu);
MSWDestroyWindow();
}
+bool wxMDIChildFrame::Show(bool show)
+{
+ m_needsInitialShow = false;
+ return wxFrame::Show(show);
+}
+
// Set the client size (i.e. leave the calculation of borders etc.
-// to wxWindows)
+// to wxWidgets)
void wxMDIChildFrame::DoSetClientSize(int width, int height)
{
HWND hWnd = GetHwnd();
int actual_width = rect2.right - rect2.left - rect.right + width;
int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
+#if wxUSE_STATUSBAR
if (GetStatusBar() && GetStatusBar()->IsShown())
{
int sx, sy;
GetStatusBar()->GetSize(&sx, &sy);
actual_height += sy;
}
+#endif // wxUSE_STATUSBAR
POINT point;
point.x = rect2.left;
MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)true);
- wxSizeEvent event(wxSize(width, height), m_windowId);
+ wxSize size(width, height);
+ wxSizeEvent event(size, m_windowId);
event.SetEventObject( this );
GetEventHandler()->ProcessEvent(event);
}
wxMDIParentFrame *mdiParent = (wxMDIParentFrame *)GetParent();
::ScreenToClient((HWND) mdiParent->GetClientWindow()->GetHWND(), &point);
- *x = point.x;
- *y = point.y;
+ if (x)
+ *x = point.x;
+ if (y)
+ *y = point.y;
}
void wxMDIChildFrame::InternalSetMenuBar()
// MDI window proc and message handlers
// ---------------------------------------------------------------------------
-long wxMDIChildFrame::MSWWindowProc(WXUINT message,
+WXLRESULT wxMDIChildFrame::MSWWindowProc(WXUINT message,
WXWPARAM wParam,
WXLPARAM lParam)
{
- long rc = 0;
+ WXLRESULT rc = 0;
bool processed = false;
switch ( message )
lpPos->cx = rectClient.right - rectClient.left;
lpPos->cy = rectClient.bottom - rectClient.top;
}
+#if wxUSE_TOOLBAR
wxMDIParentFrame* pFrameWnd = (wxMDIParentFrame *)GetParent();
if (pFrameWnd && pFrameWnd->GetToolBar() && pFrameWnd->GetToolBar()->IsShown())
{
pFrameWnd->GetToolBar()->Refresh();
}
+#endif
}
#endif // Win95
// MDI specific message translation/preprocessing
// ---------------------------------------------------------------------------
-long wxMDIChildFrame::MSWDefWindowProc(WXUINT message, WXUINT wParam, WXLPARAM lParam)
+WXLRESULT wxMDIChildFrame::MSWDefWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{
return DefMDIChildProc(GetHwnd(),
(UINT)message, (WPARAM)wParam, (LPARAM)lParam);
void wxMDIChildFrame::OnIdle(wxIdleEvent& event)
{
+ // wxMSW prior to 2.5.3 created MDI child frames as visible, which resulted
+ // in flicker e.g. when the frame contained controls with non-trivial
+ // layout. Since 2.5.3, the frame is created hidden as all other top level
+ // windows. In order to maintain backward compatibility, the frame is shown
+ // in OnIdle, unless Show(false) was called by the programmer before.
+ if ( m_needsInitialShow )
+ {
+ Show(true);
+ }
+
// MDI child frames get their WM_SIZE when they're constructed but at this
// moment they don't have any children yet so all child windows will be
// positioned incorrectly when they are added later - to fix this, we
wxWindow *parent = win->GetParent();
wxCHECK_RET( parent, wxT("MDI client without parent frame? weird...") );
-#ifndef __WIN16__
::SendMessage(GetWinHwnd(win), WM_MDIREFRESHMENU, 0, 0L);
-#endif
::DrawMenuBar(GetWinHwnd(parent));
}
static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact)
{
-#ifdef __WIN32__
*activate = true;
*hwndAct = (WXHWND)lParam;
*hwndDeact = (WXHWND)wParam;
-#else // Win16
- *activate = (WXWORD)wParam;
- *hwndAct = (WXHWND)LOWORD(lParam);
- *hwndDeact = (WXHWND)HIWORD(lParam);
-#endif // Win32/Win16
}
-#endif
-// wxUSE_MDI_ARCHITECTURE && !defined(__WXUNIVERSAL__)
+#endif // wxUSE_MDI && !defined(__WXUNIVERSAL__)