1998-05-20 14:12:05 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: mdi.cpp
|
|
|
|
// Purpose: MDI classes
|
|
|
|
// Author: Julian Smart
|
|
|
|
// Modified by:
|
|
|
|
// Created: 04/01/98
|
|
|
|
// RCS-ID: $Id$
|
|
|
|
// Copyright: (c) Julian Smart and Markus Holzem
|
|
|
|
// Licence: wxWindows license
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#ifdef __GNUG__
|
|
|
|
#pragma implementation "mdi.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
|
|
#ifdef __BORLANDC__
|
|
|
|
#pragma hdrstop
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef WX_PRECOMP
|
|
|
|
#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/statusbr.h"
|
|
|
|
#include "wx/settings.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "wx/mdi.h"
|
|
|
|
#include "wx/msw/private.h"
|
|
|
|
|
|
|
|
#if USE_NATIVE_STATUSBAR
|
|
|
|
#include <wx/msw/statbr95.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
extern wxList wxModelessWindows;
|
|
|
|
|
|
|
|
#define IDM_WINDOWTILE 4001
|
|
|
|
#define IDM_WINDOWCASCADE 4002
|
|
|
|
#define IDM_WINDOWICONS 4003
|
|
|
|
#define IDM_WINDOWNEXT 4004
|
|
|
|
// This range gives a maximum of 500
|
|
|
|
// MDI children. Should be enough :-)
|
|
|
|
#define wxFIRST_MDI_CHILD 4100
|
|
|
|
#define wxLAST_MDI_CHILD 4600
|
|
|
|
|
|
|
|
// Status border dimensions
|
|
|
|
#define wxTHICK_LINE_BORDER 3
|
|
|
|
#define wxTHICK_LINE_WIDTH 1
|
|
|
|
|
|
|
|
extern char wxMDIFrameClassName[];
|
|
|
|
extern char wxMDIChildFrameClassName[];
|
|
|
|
extern wxWindow *wxWndHook;
|
|
|
|
|
|
|
|
#if !USE_SHARED_LIBRARY
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame)
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame)
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow)
|
|
|
|
|
|
|
|
BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
|
|
|
|
EVT_SIZE(wxMDIParentFrame::OnSize)
|
|
|
|
EVT_ACTIVATE(wxMDIParentFrame::OnActivate)
|
|
|
|
EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
|
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
|
|
BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
|
|
|
|
EVT_SCROLL(wxMDIClientWindow::OnScroll)
|
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
wxMDIParentFrame::wxMDIParentFrame(void)
|
|
|
|
{
|
|
|
|
m_clientWindow = NULL;
|
|
|
|
m_currentChild = NULL;
|
|
|
|
m_windowMenu = 0;
|
|
|
|
m_parentFrameActive = TRUE;
|
|
|
|
m_frameToolBar = NULL ;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wxMDIParentFrame::Create(wxWindow *parent,
|
|
|
|
const wxWindowID id,
|
|
|
|
const wxString& title,
|
|
|
|
const wxPoint& pos,
|
|
|
|
const wxSize& size,
|
|
|
|
const long style,
|
|
|
|
const wxString& name)
|
|
|
|
{
|
|
|
|
m_defaultIcon = (WXHICON) (wxSTD_MDIPARENTFRAME_ICON ? wxSTD_MDIPARENTFRAME_ICON : wxDEFAULT_MDIPARENTFRAME_ICON);
|
|
|
|
|
|
|
|
m_frameToolBar = NULL ;
|
|
|
|
m_clientWindow = NULL;
|
|
|
|
m_currentChild = NULL;
|
|
|
|
m_windowMenu = 0;
|
|
|
|
m_parentFrameActive = TRUE;
|
|
|
|
|
|
|
|
if (!parent)
|
|
|
|
wxTopLevelWindows.Append(this);
|
|
|
|
|
|
|
|
SetName(name);
|
|
|
|
m_windowStyle = style;
|
|
|
|
|
|
|
|
if (parent) parent->AddChild(this);
|
|
|
|
|
|
|
|
if ( id > -1 )
|
|
|
|
m_windowId = id;
|
|
|
|
else
|
|
|
|
m_windowId = (int)NewControlId();
|
|
|
|
|
|
|
|
int x = pos.x;
|
|
|
|
int y = pos.y;
|
|
|
|
int width = size.x;
|
|
|
|
int height = size.y;
|
|
|
|
|
|
|
|
m_windowMenu = (WXHMENU) ::LoadMenu(wxGetInstance(), "wxWindowMenu");
|
|
|
|
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("Loaded m_windowMenu %d\n", m_windowMenu);
|
|
|
|
#endif
|
|
|
|
|
1998-06-23 10:29:23 +00:00
|
|
|
DWORD msflags = WS_OVERLAPPED ;
|
1998-05-20 14:12:05 +00:00
|
|
|
if (style & wxMINIMIZE_BOX)
|
|
|
|
msflags |= WS_MINIMIZEBOX;
|
|
|
|
if (style & wxMAXIMIZE_BOX)
|
|
|
|
msflags |= WS_MAXIMIZEBOX;
|
|
|
|
if (style & wxTHICK_FRAME)
|
|
|
|
msflags |= WS_THICKFRAME;
|
|
|
|
if (style & wxSYSTEM_MENU)
|
|
|
|
msflags |= WS_SYSMENU;
|
|
|
|
if ((style & wxMINIMIZE) || (style & wxICONIZE))
|
|
|
|
msflags |= WS_MINIMIZE;
|
|
|
|
if (style & wxMAXIMIZE)
|
|
|
|
msflags |= WS_MAXIMIZE;
|
|
|
|
if (style & wxCAPTION)
|
|
|
|
msflags |= WS_CAPTION;
|
1998-06-23 10:29:23 +00:00
|
|
|
|
|
|
|
// Adding WS_CLIPCHILDREN causes children not to be properly
|
|
|
|
// drawn when first displaying them.
|
|
|
|
// if (style & wxCLIP_CHILDREN)
|
|
|
|
// msflags |= WS_CLIPCHILDREN;
|
1998-05-20 14:12:05 +00:00
|
|
|
|
|
|
|
wxWindow::MSWCreate(m_windowId, parent, wxMDIFrameClassName, this, title, x, y, width, height,
|
|
|
|
msflags);
|
|
|
|
|
|
|
|
wxModelessWindows.Append(this);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxMDIParentFrame::~wxMDIParentFrame(void)
|
|
|
|
{
|
|
|
|
DestroyChildren();
|
|
|
|
|
|
|
|
DestroyMenu((HMENU) m_windowMenu); // Destroy dummy "Window" menu
|
|
|
|
m_windowMenu = 0;
|
|
|
|
|
|
|
|
if (m_clientWindow->MSWGetOldWndProc())
|
|
|
|
m_clientWindow->UnsubclassWin();
|
|
|
|
|
|
|
|
m_clientWindow->m_hWnd = 0;
|
|
|
|
delete m_clientWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get size *available for subwindows* i.e. excluding menu bar.
|
|
|
|
void wxMDIParentFrame::GetClientSize(int *x, int *y) const
|
|
|
|
{
|
|
|
|
RECT rect;
|
|
|
|
GetClientRect((HWND) GetHWND(), &rect);
|
|
|
|
|
|
|
|
int cwidth = rect.right;
|
|
|
|
int cheight = rect.bottom;
|
|
|
|
/*
|
|
|
|
if (m_frameToolBar)
|
|
|
|
{
|
|
|
|
int tw, th;
|
|
|
|
m_frameToolBar->GetSize(&tw, &th);
|
|
|
|
cheight -= th;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
if ( GetStatusBar() )
|
|
|
|
{
|
|
|
|
int sw, sh;
|
|
|
|
GetStatusBar()->GetSize(&sw, &sh);
|
|
|
|
cheight -= sh;
|
|
|
|
}
|
|
|
|
|
|
|
|
*x = cwidth;
|
|
|
|
*y = cheight;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIParentFrame::SetMenuBar(wxMenuBar *menu_bar)
|
|
|
|
{
|
|
|
|
if (!menu_bar)
|
|
|
|
{
|
|
|
|
m_frameMenuBar = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (menu_bar->m_menuBarFrame)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
HMENU menu = CreateMenu();
|
|
|
|
|
|
|
|
for (i = 0; i < menu_bar->m_menuCount; i ++)
|
|
|
|
{
|
|
|
|
HMENU popup = (HMENU)menu_bar->m_menus[i]->m_hMenu;
|
|
|
|
//
|
|
|
|
// After looking Bounds Checker result, it seems that all
|
|
|
|
// menus must be individually destroyed. So, don't reset m_hMenu,
|
|
|
|
// to allow ~wxMenu to do the job.
|
|
|
|
//
|
|
|
|
menu_bar->m_menus[i]->m_savehMenu = (WXHMENU) popup;
|
|
|
|
// Uncommenting for the moment... JACS
|
|
|
|
menu_bar->m_menus[i]->m_hMenu = (WXHMENU) NULL;
|
|
|
|
AppendMenu(menu, MF_POPUP | MF_STRING, (UINT)popup, menu_bar->m_titles[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
menu_bar->m_hMenu = (WXHMENU)menu;
|
|
|
|
if (m_frameMenuBar)
|
|
|
|
delete m_frameMenuBar;
|
|
|
|
|
|
|
|
this->m_hMenu = (WXHMENU) menu;
|
|
|
|
|
|
|
|
// MDI parent-specific code follows
|
|
|
|
|
|
|
|
HMENU subMenu = GetSubMenu((HMENU) m_windowMenu, 0);
|
|
|
|
|
|
|
|
// Try to insert Window menu in front of Help, otherwise append it.
|
|
|
|
int N = GetMenuItemCount(menu);
|
|
|
|
bool success = FALSE;
|
|
|
|
for (i = 0; i < N; i++)
|
|
|
|
{
|
|
|
|
char buf[100];
|
|
|
|
int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION);
|
|
|
|
if ((chars > 0) && (strcmp(buf, "&Help") == 0 ||
|
|
|
|
strcmp(buf, "Help") == 0))
|
|
|
|
{
|
|
|
|
success = TRUE;
|
|
|
|
InsertMenu(menu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
|
|
|
|
(UINT)subMenu, "&Window");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!success)
|
|
|
|
AppendMenu(menu, MF_POPUP,
|
|
|
|
(UINT)subMenu,
|
|
|
|
"&Window");
|
|
|
|
m_parentFrameActive = TRUE;
|
|
|
|
#ifdef __WIN32__
|
|
|
|
SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDISETMENU,
|
|
|
|
(WPARAM)menu,
|
|
|
|
(LPARAM)subMenu);
|
|
|
|
#else
|
|
|
|
SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDISETMENU, 0,
|
|
|
|
MAKELPARAM(menu, subMenu));
|
|
|
|
#endif
|
|
|
|
DrawMenuBar((HWND) GetHWND());
|
|
|
|
|
|
|
|
m_frameMenuBar = menu_bar;
|
|
|
|
menu_bar->m_menuBarFrame = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIParentFrame::OnSize(wxSizeEvent& event)
|
|
|
|
{
|
|
|
|
#if USE_CONSTRAINTS
|
|
|
|
if (GetAutoLayout())
|
|
|
|
Layout();
|
|
|
|
#endif
|
|
|
|
int x = 0;
|
|
|
|
int y = 0;
|
|
|
|
int width, height;
|
|
|
|
GetClientSize(&width, &height);
|
|
|
|
if ( GetToolBar() )
|
|
|
|
{
|
|
|
|
int wt, ht;
|
|
|
|
GetToolBar()->GetSize(&wt, &ht);
|
|
|
|
height -= ht;
|
|
|
|
y += ht;
|
|
|
|
GetToolBar()->SetSize(0, 0, width, ht);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( GetClientWindow() )
|
|
|
|
GetClientWindow()->SetSize(x, y, width, height);
|
|
|
|
|
|
|
|
// forward WM_SIZE to status bar control
|
|
|
|
#if USE_NATIVE_STATUSBAR
|
|
|
|
if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
|
|
|
|
((wxStatusBar95 *)m_frameStatusBar)->OnSize(event);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIParentFrame::OnActivate(wxActivateEvent& event)
|
|
|
|
{
|
|
|
|
// Do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
#if WXWIN_COMPATIBILITY
|
|
|
|
void wxMDIParentFrame::OldOnSize(int x, int y)
|
|
|
|
{
|
|
|
|
#if WXWIN_COMPATIBILITY == 1
|
|
|
|
wxSizeEvent event(wxSize(x, y), m_windowId);
|
|
|
|
event.SetEventObject( this );
|
|
|
|
GetEventHandler()->ProcessEvent(event);
|
|
|
|
#else
|
|
|
|
|
|
|
|
#if USE_CONSTRAINTS
|
|
|
|
if (GetAutoLayout())
|
|
|
|
Layout();
|
|
|
|
#endif
|
|
|
|
int x = 0;
|
|
|
|
int y = 0;
|
|
|
|
int width, height;
|
|
|
|
GetClientSize(&width, &height);
|
|
|
|
if ( GetToolBar() )
|
|
|
|
{
|
|
|
|
int wt, ht;
|
|
|
|
GetToolBar()->GetSize(&wt, &ht);
|
|
|
|
height -= ht;
|
|
|
|
y += ht;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( GetClientWindow() )
|
|
|
|
GetClientWindow()->SetSize(x, y, width, height);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default activation behaviour - nothing.
|
|
|
|
// Default activation behaviour - override dedault wxFrame behaviour
|
|
|
|
void wxMDIParentFrame::OldOnActivate(bool flag)
|
|
|
|
{
|
|
|
|
#if WXWIN_COMPATIBILITY == 1
|
|
|
|
wxActivateEvent event(wxEVT_ACTIVATE, flag, m_windowId);
|
|
|
|
event.SetEventObject( this );
|
|
|
|
GetEventHandler()->ProcessEvent(event);
|
|
|
|
#else
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Returns the active MDI child window
|
|
|
|
wxMDIChildFrame *wxMDIParentFrame::GetActiveChild(void) const
|
|
|
|
{
|
|
|
|
// HWND hWnd = (HWND)LOWORD(SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDIGETACTIVE, 0, 0L));
|
|
|
|
HWND hWnd = (HWND)SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDIGETACTIVE, 0, 0L);
|
|
|
|
if (hWnd == 0)
|
|
|
|
return NULL;
|
|
|
|
else
|
|
|
|
return (wxMDIChildFrame *)wxFindWinFromHandle((WXHWND) hWnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the client window class (don't Create the window,
|
|
|
|
// just return a new class)
|
|
|
|
wxMDIClientWindow *wxMDIParentFrame::OnCreateClient(void)
|
|
|
|
{
|
|
|
|
return new wxMDIClientWindow ;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Responds to colour changes, and passes event on to children.
|
|
|
|
void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
|
|
|
|
{
|
|
|
|
if ( m_clientWindow )
|
|
|
|
{
|
|
|
|
m_clientWindow->SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
|
|
|
|
m_clientWindow->Refresh();
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
if ( m_frameToolBar )
|
|
|
|
{
|
|
|
|
wxSysColourChangedEvent event2;
|
|
|
|
event2.eventObject = m_frameToolBar;
|
|
|
|
m_frameToolBar->GetEventHandler()->ProcessEvent(event2);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Propagate the event to the non-top-level children
|
|
|
|
wxFrame::OnSysColourChanged(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
// MDI operations
|
|
|
|
void wxMDIParentFrame::Cascade(void)
|
|
|
|
{
|
|
|
|
::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDICASCADE, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIParentFrame::Tile(void)
|
|
|
|
{
|
|
|
|
::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDITILE, MDITILE_HORIZONTAL, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIParentFrame::ArrangeIcons(void)
|
|
|
|
{
|
|
|
|
::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDIICONARRANGE, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIParentFrame::ActivateNext(void)
|
|
|
|
{
|
|
|
|
::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDINEXT, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIParentFrame::ActivatePrevious(void)
|
|
|
|
{
|
|
|
|
::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDINEXT, 0, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
// Returns a style for the client window - usually 0
|
|
|
|
// or, for example, wxHSCROLL | wxVSCROLL
|
|
|
|
long wxMDIParentFrame::GetClientStyle(void) const
|
|
|
|
{
|
|
|
|
return wxHSCROLL | wxVSCROLL ;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool wxMDIParentFrame::MSWOnDestroy(void)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIParentFrame::MSWOnCreate(WXLPCREATESTRUCT WXUNUSED(cs))
|
|
|
|
{
|
|
|
|
m_clientWindow = new wxMDIClientWindow;
|
|
|
|
// Uses own style for client style
|
|
|
|
m_clientWindow->CreateClient(this, GetWindowStyleFlag());
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIParentFrame::MSWOnSize(const int x, const int y, const WXUINT id)
|
|
|
|
{
|
|
|
|
switch (id)
|
|
|
|
{
|
|
|
|
case SIZEFULLSCREEN:
|
|
|
|
case SIZENORMAL:
|
|
|
|
m_iconized = FALSE;
|
|
|
|
break;
|
|
|
|
case SIZEICONIC:
|
|
|
|
m_iconized = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!m_iconized)
|
|
|
|
{
|
|
|
|
// forward WM_SIZE to status bar control
|
|
|
|
#if USE_NATIVE_STATUSBAR
|
|
|
|
if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
|
|
|
|
{
|
|
|
|
wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId());
|
|
|
|
event.SetEventObject( m_frameStatusBar );
|
|
|
|
|
|
|
|
((wxStatusBar95 *)m_frameStatusBar)->OnSize(event);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
PositionStatusBar();
|
|
|
|
|
|
|
|
GetEventHandler()->OldOnSize(x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wxMDIParentFrame::MSWOnActivate(const int state, const bool minimized, const WXHWND activate)
|
|
|
|
{
|
|
|
|
wxWindow::MSWOnActivate(state, minimized, activate);
|
|
|
|
|
|
|
|
// If this window is an MDI parent, we must also send an OnActivate message
|
|
|
|
// to the current child.
|
|
|
|
if ((m_currentChild != NULL) && ((state == WA_ACTIVE) || (state == WA_CLICKACTIVE)))
|
|
|
|
{
|
|
|
|
#if WXWIN_COMPATIBILITY
|
|
|
|
m_currentChild->GetEventHandler()->OldOnActivate(TRUE);
|
|
|
|
#else
|
|
|
|
wxActivateEvent event(wxEVT_ACTIVATE, TRUE,
|
|
|
|
m_currentChild.m_windowId);
|
|
|
|
event.eventObject = m_currentChild;
|
|
|
|
m_currentChild->GetEventHandler()->ProcessEvent(event);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wxMDIParentFrame::MSWOnCommand(const WXWORD id, const WXWORD cmd, const WXHWND control)
|
|
|
|
{
|
|
|
|
if (cmd == 0)
|
|
|
|
{
|
|
|
|
// In case it's e.g. a toolbar.
|
|
|
|
wxWindow *win = wxFindWinFromHandle(control);
|
|
|
|
if (win)
|
|
|
|
return win->MSWCommand(cmd, id);
|
|
|
|
|
|
|
|
switch (id)
|
|
|
|
{
|
|
|
|
case IDM_WINDOWCASCADE:
|
|
|
|
SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDICASCADE, MDITILE_SKIPDISABLED, 0);
|
|
|
|
return TRUE;
|
|
|
|
case IDM_WINDOWTILE:
|
|
|
|
SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDITILE, MDITILE_HORIZONTAL, 0);
|
|
|
|
return TRUE;
|
|
|
|
case IDM_WINDOWICONS:
|
|
|
|
SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDIICONARRANGE, 0, 0);
|
|
|
|
return TRUE;
|
|
|
|
case IDM_WINDOWNEXT:
|
|
|
|
SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDINEXT, 0, 0);
|
|
|
|
return TRUE;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (id >= 0xF000)
|
|
|
|
{
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("wxMDIFrame::OnCommand %d: system command: calling default window proc\n", GetHWND());
|
|
|
|
#endif
|
|
|
|
return FALSE; // Get WndProc to call default proc
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_parentFrameActive && (id < wxFIRST_MDI_CHILD || id > wxLAST_MDI_CHILD))
|
|
|
|
{
|
|
|
|
ProcessCommand(id);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else if (m_currentChild && (id < wxFIRST_MDI_CHILD || id > wxLAST_MDI_CHILD))
|
|
|
|
{
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("wxMDIFrame::MSWOnCommand %d: calling child OnCommand\n", GetHWND());
|
|
|
|
#endif
|
|
|
|
return m_currentChild->MSWOnCommand(id, cmd, control);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (id >= wxFIRST_MDI_CHILD && id <= wxLAST_MDI_CHILD)
|
|
|
|
{
|
|
|
|
wxNode* node = GetChildren()->First();
|
|
|
|
while (node)
|
|
|
|
{
|
|
|
|
wxWindow* child = (wxWindow*) node->Data();
|
|
|
|
if (child->GetHWND())
|
|
|
|
{
|
|
|
|
#ifdef __WIN32__
|
|
|
|
long childId = GetWindowLong((HWND) child->GetHWND(), GWL_ID);
|
|
|
|
#else
|
|
|
|
long childId = GetWindowWord((HWND) child->GetHWND(), GWW_ID);
|
|
|
|
#endif
|
|
|
|
if (childId == id)
|
|
|
|
{
|
|
|
|
::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDIACTIVATE, (WPARAM) (HWND) child->GetHWND(), 0);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
node = node->Next();
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
wxWindow* child = FindItem(id);
|
|
|
|
if (child)
|
|
|
|
{
|
|
|
|
::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDIACTIVATE, (WPARAM) (HWND) child->GetHWND(), 0);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIParentFrame::MSWOnMenuHighlight(const WXWORD nItem, const WXWORD nFlags, const WXHMENU hSysMenu)
|
|
|
|
{
|
|
|
|
if (m_parentFrameActive)
|
|
|
|
{
|
|
|
|
// TODO
|
|
|
|
if (nFlags == 0xFFFF && hSysMenu == (WXHMENU) NULL)
|
|
|
|
GetEventHandler()->OldOnMenuSelect(-1);
|
|
|
|
else if (nFlags != MF_SEPARATOR)
|
|
|
|
GetEventHandler()->OldOnMenuSelect(nItem);
|
|
|
|
}
|
|
|
|
else if (m_currentChild)
|
|
|
|
{
|
|
|
|
m_currentChild->MSWOnMenuHighlight(nItem, nFlags, hSysMenu);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
long wxMDIParentFrame::MSWDefWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
|
|
|
|
{
|
|
|
|
WXHWND clientWnd;
|
|
|
|
if ( GetClientWindow() )
|
|
|
|
clientWnd = GetClientWindow()->GetHWND();
|
|
|
|
else
|
|
|
|
clientWnd = 0;
|
|
|
|
|
|
|
|
return DefFrameProc((HWND) GetHWND(), (HWND) clientWnd, message, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wxMDIParentFrame::MSWProcessMessage(WXMSG* msg)
|
|
|
|
{
|
|
|
|
MSG *pMsg = (MSG *)msg;
|
|
|
|
|
|
|
|
if ((m_currentChild != (wxWindow *)NULL) && (m_currentChild->GetHWND() != (WXHWND) NULL) && m_currentChild->MSWProcessMessage(msg))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if (m_acceleratorTable != (WXHANDLE) NULL &&
|
|
|
|
::TranslateAccelerator((HWND) GetHWND(), (HANDLE) m_acceleratorTable, pMsg))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN)
|
|
|
|
{
|
|
|
|
if (::TranslateMDISysAccel((HWND) GetClientWindow()->GetHWND(), pMsg))
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wxMDIParentFrame::MSWOnEraseBkgnd(const WXHDC WXUNUSED(pDC))
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern wxWindow *wxWndHook;
|
|
|
|
extern wxList *wxWinHandleList;
|
|
|
|
|
|
|
|
wxMDIChildFrame::wxMDIChildFrame(void)
|
|
|
|
{
|
|
|
|
// m_active = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
|
|
|
|
const wxWindowID id,
|
|
|
|
const wxString& title,
|
|
|
|
const wxPoint& pos,
|
|
|
|
const wxSize& size,
|
|
|
|
const long style,
|
|
|
|
const wxString& name)
|
|
|
|
{
|
|
|
|
m_defaultIcon = (WXHICON) (wxSTD_MDICHILDFRAME_ICON ? wxSTD_MDICHILDFRAME_ICON : wxDEFAULT_MDICHILDFRAME_ICON);
|
|
|
|
|
|
|
|
SetName(name);
|
|
|
|
|
|
|
|
if ( id > -1 )
|
|
|
|
m_windowId = id;
|
|
|
|
else
|
|
|
|
m_windowId = (int)NewControlId();
|
|
|
|
|
|
|
|
if (parent) parent->AddChild(this);
|
|
|
|
|
|
|
|
wxWndHook = this;
|
|
|
|
|
|
|
|
int x = pos.x;
|
|
|
|
int y = pos.y;
|
|
|
|
int width = size.x;
|
|
|
|
int height = size.y;
|
|
|
|
|
|
|
|
MDICREATESTRUCT mcs;
|
|
|
|
|
|
|
|
mcs.szClass = wxMDIChildFrameClassName;
|
|
|
|
mcs.szTitle = title;
|
|
|
|
mcs.hOwner = wxGetInstance();
|
|
|
|
if (x > -1) mcs.x = x;
|
|
|
|
else mcs.x = CW_USEDEFAULT;
|
|
|
|
|
|
|
|
if (y > -1) mcs.y = y;
|
|
|
|
else mcs.y = CW_USEDEFAULT;
|
|
|
|
|
|
|
|
if (width > -1) mcs.cx = width;
|
|
|
|
else mcs.cx = CW_USEDEFAULT;
|
|
|
|
|
|
|
|
if (height > -1) mcs.cy = height;
|
|
|
|
else mcs.cy = CW_USEDEFAULT;
|
|
|
|
|
|
|
|
DWORD msflags = WS_OVERLAPPED | WS_CLIPCHILDREN ;
|
|
|
|
if (style & wxMINIMIZE_BOX)
|
|
|
|
msflags |= WS_MINIMIZEBOX;
|
|
|
|
if (style & wxMAXIMIZE_BOX)
|
|
|
|
msflags |= WS_MAXIMIZEBOX;
|
|
|
|
if (style & wxTHICK_FRAME)
|
|
|
|
msflags |= WS_THICKFRAME;
|
|
|
|
if (style & wxSYSTEM_MENU)
|
|
|
|
msflags |= WS_SYSMENU;
|
|
|
|
if ((style & wxMINIMIZE) || (style & wxICONIZE))
|
|
|
|
msflags |= WS_MINIMIZE;
|
|
|
|
if (style & wxMAXIMIZE)
|
|
|
|
msflags |= WS_MAXIMIZE;
|
|
|
|
if (style & wxCAPTION)
|
|
|
|
msflags |= WS_CAPTION;
|
|
|
|
|
|
|
|
mcs.style = msflags;
|
|
|
|
|
|
|
|
mcs.lParam = 0;
|
|
|
|
|
|
|
|
DWORD Return = SendMessage((HWND) parent->GetClientWindow()->GetHWND(),
|
|
|
|
WM_MDICREATE, 0, (LONG)(LPSTR)&mcs);
|
|
|
|
|
|
|
|
//handle = (HWND)LOWORD(Return);
|
|
|
|
// Must be the DWORRD for WIN32. And in 16 bits, HIWORD=0 (says Microsoft)
|
|
|
|
m_hWnd = (WXHWND)Return;
|
|
|
|
|
|
|
|
// This gets reassigned so can't be stored
|
|
|
|
// m_windowId = GetWindowLong((HWND) m_hWnd, GWL_ID);
|
|
|
|
|
|
|
|
wxWndHook = NULL;
|
|
|
|
wxWinHandleList->Append((long)GetHWND(), this);
|
|
|
|
|
|
|
|
SetWindowLong((HWND) GetHWND(), 0, (long)this);
|
|
|
|
|
|
|
|
wxModelessWindows.Append(this);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxMDIChildFrame::~wxMDIChildFrame(void)
|
|
|
|
{
|
|
|
|
MSWDestroyWindow();
|
|
|
|
|
|
|
|
ResetWindowStyle(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the client size (i.e. leave the calculation of borders etc.
|
|
|
|
// to wxWindows)
|
|
|
|
void wxMDIChildFrame::SetClientSize(const int width, const int height)
|
|
|
|
{
|
|
|
|
HWND hWnd = (HWND) GetHWND();
|
|
|
|
|
|
|
|
RECT rect;
|
|
|
|
GetClientRect(hWnd, &rect);
|
|
|
|
|
|
|
|
RECT rect2;
|
|
|
|
GetWindowRect(hWnd, &rect2);
|
|
|
|
|
|
|
|
// Find the difference between the entire window (title bar and all)
|
|
|
|
// and the client area; add this to the new client size to move the
|
|
|
|
// window
|
|
|
|
int actual_width = rect2.right - rect2.left - rect.right + width;
|
|
|
|
int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
|
|
|
|
|
|
|
|
if (GetStatusBar())
|
|
|
|
{
|
|
|
|
int sx, sy;
|
|
|
|
GetStatusBar()->GetSize(&sx, &sy);
|
|
|
|
actual_height += sy;
|
|
|
|
}
|
|
|
|
|
|
|
|
POINT point;
|
|
|
|
point.x = rect2.left;
|
|
|
|
point.y = rect2.top;
|
|
|
|
|
|
|
|
// If there's an MDI parent, must subtract the parent's top left corner
|
|
|
|
// since MoveWindow moves relative to the parent
|
|
|
|
wxMDIParentFrame *mdiParent = (wxMDIParentFrame *)GetParent();
|
|
|
|
::ScreenToClient((HWND) mdiParent->GetClientWindow()->GetHWND(), &point);
|
|
|
|
|
|
|
|
MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
|
|
|
|
#if WXWIN_COMPATIBILITY
|
|
|
|
GetEventHandler()->OldOnSize(width, height);
|
|
|
|
#else
|
|
|
|
wxSizeEvent event(wxSize(width, height), m_windowId);
|
|
|
|
event.eventObject = this;
|
|
|
|
GetEventHandler()->ProcessEvent(event);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIChildFrame::GetPosition(int *x, int *y) const
|
|
|
|
{
|
|
|
|
RECT rect;
|
|
|
|
GetWindowRect((HWND) GetHWND(), &rect);
|
|
|
|
POINT point;
|
|
|
|
point.x = rect.left;
|
|
|
|
point.y = rect.top;
|
|
|
|
|
|
|
|
// Since we now have the absolute screen coords,
|
|
|
|
// if there's a parent we must subtract its top left corner
|
|
|
|
wxMDIParentFrame *mdiParent = (wxMDIParentFrame *)GetParent();
|
|
|
|
::ScreenToClient((HWND) mdiParent->GetClientWindow()->GetHWND(), &point);
|
|
|
|
|
|
|
|
*x = point.x;
|
|
|
|
*y = point.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar)
|
|
|
|
{
|
|
|
|
if (!menu_bar)
|
|
|
|
{
|
|
|
|
m_frameMenuBar = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (menu_bar->m_menuBarFrame)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
HMENU menu = CreateMenu();
|
|
|
|
|
|
|
|
for (i = 0; i < menu_bar->m_menuCount; i ++)
|
|
|
|
{
|
|
|
|
HMENU popup = (HMENU)menu_bar->m_menus[i]->m_hMenu;
|
|
|
|
//
|
|
|
|
// After looking Bounds Checker result, it seems that all
|
|
|
|
// menus must be individually destroyed. So, don't reset m_hMenu,
|
|
|
|
// to allow ~wxMenu to do the job.
|
|
|
|
//
|
|
|
|
menu_bar->m_menus[i]->m_savehMenu = (WXHMENU) popup;
|
|
|
|
// Uncommenting for the moment... JACS
|
|
|
|
menu_bar->m_menus[i]->m_hMenu = 0;
|
|
|
|
::AppendMenu((HMENU) menu, MF_POPUP | MF_STRING, (UINT)popup, menu_bar->m_titles[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
menu_bar->m_hMenu = (WXHMENU)menu;
|
|
|
|
if (m_frameMenuBar)
|
|
|
|
delete m_frameMenuBar;
|
|
|
|
|
|
|
|
this->m_hMenu = (WXHMENU) menu;
|
|
|
|
|
|
|
|
wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
|
|
|
|
|
|
|
|
parent->m_parentFrameActive = FALSE;
|
|
|
|
HMENU subMenu = GetSubMenu((HWND) parent->GetWindowMenu(), 0);
|
|
|
|
|
|
|
|
// Try to insert Window menu in front of Help, otherwise append it.
|
|
|
|
int N = GetMenuItemCount(menu);
|
|
|
|
bool success = FALSE;
|
|
|
|
for (i = 0; i < N; i++)
|
|
|
|
{
|
|
|
|
char buf[100];
|
|
|
|
int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION);
|
|
|
|
if ((chars > 0) && (strcmp(buf, "&Help") == 0 ||
|
|
|
|
strcmp(buf, "Help") == 0))
|
|
|
|
{
|
|
|
|
success = TRUE;
|
|
|
|
InsertMenu(menu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
|
|
|
|
(UINT)subMenu, "&Window");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!success)
|
|
|
|
AppendMenu(menu, MF_POPUP,
|
|
|
|
(UINT)subMenu,
|
|
|
|
"&Window");
|
|
|
|
#ifdef __WIN32__
|
|
|
|
SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU,
|
|
|
|
(WPARAM)menu,
|
|
|
|
(LPARAM)subMenu);
|
|
|
|
#else
|
|
|
|
SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, 0,
|
|
|
|
MAKELPARAM(menu, subMenu));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
DrawMenuBar((HWND) parent->GetHWND());
|
|
|
|
m_frameMenuBar = menu_bar;
|
|
|
|
menu_bar->m_menuBarFrame = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// MDI operations
|
|
|
|
void wxMDIChildFrame::Maximize(void)
|
|
|
|
{
|
|
|
|
wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
|
|
|
|
if ( parent && parent->GetClientWindow() )
|
|
|
|
::SendMessage( (HWND) parent->GetClientWindow()->GetHWND(), WM_MDIMAXIMIZE, (WPARAM) (HWND) GetHWND(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIChildFrame::Restore(void)
|
|
|
|
{
|
|
|
|
wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
|
|
|
|
if ( parent && parent->GetClientWindow() )
|
|
|
|
::SendMessage( (HWND) parent->GetClientWindow()->GetHWND(), WM_MDIRESTORE, (WPARAM) (HWND) GetHWND(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIChildFrame::Activate(void)
|
|
|
|
{
|
|
|
|
wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
|
|
|
|
if ( parent && parent->GetClientWindow() )
|
|
|
|
::SendMessage( (HWND) parent->GetClientWindow()->GetHWND(), WM_MDIACTIVATE, (WPARAM) (HWND) GetHWND(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static HWND invalidHandle = 0;
|
|
|
|
void wxMDIChildFrame::MSWOnSize(const int x, const int y, const WXUINT id)
|
|
|
|
{
|
|
|
|
if (!GetHWND()) return;
|
|
|
|
|
|
|
|
if (invalidHandle == (HWND) GetHWND())
|
|
|
|
{
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("wxMDIChildFrame::OnSize %d: invalid, so returning.\n", GetHWND());
|
|
|
|
#endif
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
(void)MSWDefWindowProc(m_lastMsg, m_lastWParam, m_lastLParam);
|
|
|
|
|
|
|
|
switch (id)
|
|
|
|
{
|
|
|
|
case SIZEFULLSCREEN:
|
|
|
|
case SIZENORMAL:
|
|
|
|
m_iconized = FALSE;
|
|
|
|
break;
|
|
|
|
case SIZEICONIC:
|
|
|
|
m_iconized = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!m_iconized)
|
|
|
|
{
|
|
|
|
// forward WM_SIZE to status bar control
|
|
|
|
#if USE_NATIVE_STATUSBAR
|
|
|
|
if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
|
|
|
|
{
|
|
|
|
wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId());
|
|
|
|
event.SetEventObject( m_frameStatusBar );
|
|
|
|
|
|
|
|
((wxStatusBar95 *)m_frameStatusBar)->OnSize(event);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
PositionStatusBar();
|
|
|
|
|
|
|
|
wxWindow::MSWOnSize(x, y, id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wxMDIChildFrame::MSWOnCommand(const WXWORD id, const WXWORD cmd, const WXHWND control)
|
|
|
|
{
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("wxMDIChildFrame::MSWOnCommand %d\n", GetHWND());
|
|
|
|
#endif
|
|
|
|
if ((cmd == 0) && GetHWND())
|
|
|
|
{
|
|
|
|
// In case it's e.g. a toolbar.
|
|
|
|
wxWindow *win = wxFindWinFromHandle(control);
|
|
|
|
if (win)
|
|
|
|
return win->MSWCommand(cmd, id);
|
|
|
|
|
|
|
|
if (GetMenuBar() && GetMenuBar()->FindItemForId(id))
|
|
|
|
{
|
|
|
|
ProcessCommand(id);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
long wxMDIChildFrame::MSWDefWindowProc(WXUINT message, WXUINT wParam, WXLPARAM lParam)
|
|
|
|
{
|
|
|
|
if (GetHWND())
|
|
|
|
return DefMDIChildProc((HWND) GetHWND(), (UINT) message, (WPARAM) wParam, (LPARAM) lParam);
|
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wxMDIChildFrame::MSWProcessMessage(WXMSG *msg)
|
|
|
|
{
|
|
|
|
MSG *pMsg = (MSG *)msg;
|
|
|
|
if (m_acceleratorTable && GetHWND())
|
|
|
|
{
|
|
|
|
wxFrame *parent = (wxFrame *)GetParent();
|
|
|
|
HWND parent_hwnd = (HWND) parent->GetHWND();
|
|
|
|
return (::TranslateAccelerator(parent_hwnd, (HANDLE) m_acceleratorTable, pMsg) != 0);
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
long wxMDIChildFrame::MSWOnMDIActivate(const long activate, const WXHWND WXUNUSED(one), const WXHWND WXUNUSED(two))
|
|
|
|
{
|
|
|
|
wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
|
|
|
|
HMENU parent_menu = (HMENU) parent->GetWinMenu();
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("Parent menu is %d\n", parent_menu);
|
|
|
|
#endif
|
|
|
|
HMENU child_menu = (HMENU) GetWinMenu();
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("Child menu is %d\n", child_menu);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (activate)
|
|
|
|
{
|
|
|
|
// m_active = TRUE;
|
|
|
|
parent->m_currentChild = this;
|
|
|
|
if (child_menu)
|
|
|
|
{
|
|
|
|
parent->m_parentFrameActive = FALSE;
|
|
|
|
HMENU subMenu = GetSubMenu((HMENU) parent->GetWindowMenu(), 0);
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("Window submenu is %d\n", subMenu);
|
|
|
|
#endif
|
|
|
|
// HMENU subMenu = 0;
|
|
|
|
#ifdef __WIN32__
|
|
|
|
::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU,
|
|
|
|
(WPARAM)child_menu,
|
|
|
|
(LPARAM)subMenu);
|
|
|
|
#else
|
|
|
|
::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, 0,
|
|
|
|
MAKELONG(child_menu, subMenu));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
::DrawMenuBar((HWND) parent->GetHWND());
|
|
|
|
}
|
|
|
|
GetEventHandler()->OldOnActivate(TRUE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (parent->m_currentChild == this)
|
|
|
|
parent->m_currentChild = NULL;
|
|
|
|
GetEventHandler()->OldOnActivate(FALSE);
|
|
|
|
|
|
|
|
// m_active = FALSE;
|
|
|
|
if (parent_menu)
|
|
|
|
{
|
|
|
|
parent->m_parentFrameActive = TRUE;
|
|
|
|
HMENU subMenu = GetSubMenu((HMENU) parent->GetWindowMenu(), 0);
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("Window submenu is %d\n", subMenu);
|
|
|
|
#endif
|
|
|
|
// HMENU subMenu = 0;
|
|
|
|
#ifdef __WIN32__
|
|
|
|
::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU,
|
|
|
|
(WPARAM)parent_menu,
|
|
|
|
(LPARAM)subMenu);
|
|
|
|
#else
|
|
|
|
::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, 0,
|
|
|
|
MAKELONG(parent_menu, subMenu));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
::DrawMenuBar((HWND) parent->GetHWND());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// TODO
|
|
|
|
bool flag = (activate != 0);
|
|
|
|
GetEventHandler()->OldOnActivate(flag);
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("Finished (de)activating\n");
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIChildFrame::MSWDestroyWindow(void)
|
|
|
|
{
|
|
|
|
MSWDetachWindowMenu();
|
|
|
|
invalidHandle = (HWND) GetHWND();
|
|
|
|
|
|
|
|
wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
|
|
|
|
|
|
|
|
// Must make sure this handle is invalidated (set to NULL)
|
|
|
|
// since all sorts of things could happen after the
|
|
|
|
// child client is destroyed, but before the wxFrame is
|
|
|
|
// destroyed.
|
|
|
|
|
|
|
|
HWND oldHandle = (HWND)GetHWND();
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("*** About to DestroyWindow MDI child %d\n", oldHandle);
|
|
|
|
#endif
|
|
|
|
#ifdef __WIN32__
|
|
|
|
SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDIDESTROY, (WPARAM)oldHandle, (LPARAM)0);
|
|
|
|
#else
|
|
|
|
SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDIDESTROY, (HWND)oldHandle, 0);
|
|
|
|
#endif
|
|
|
|
#if DEBUG > 1
|
|
|
|
wxDebugMsg("*** Finished DestroyWindow MDI child %d\n", oldHandle);
|
|
|
|
#endif
|
|
|
|
invalidHandle = 0;
|
|
|
|
|
|
|
|
if (m_hMenu)
|
|
|
|
{
|
|
|
|
::DestroyMenu((HMENU) m_hMenu);
|
|
|
|
m_hMenu = 0;
|
|
|
|
}
|
|
|
|
m_hWnd = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change the client window's extended style so we don't
|
|
|
|
// get a client edge style when a child is maximised (a double
|
|
|
|
// border looks silly.)
|
|
|
|
bool wxMDIChildFrame::ResetWindowStyle(void *vrect)
|
|
|
|
{
|
|
|
|
#if defined(__WIN95__)
|
|
|
|
RECT *rect = (RECT *)vrect;
|
|
|
|
wxMDIParentFrame* pFrameWnd = (wxMDIParentFrame *)GetParent();
|
|
|
|
wxMDIChildFrame* pChild = pFrameWnd->GetActiveChild();
|
|
|
|
if (!pChild || (pChild == this))
|
|
|
|
{
|
|
|
|
DWORD dwStyle = ::GetWindowLong((HWND) pFrameWnd->GetClientWindow()->GetHWND(), GWL_EXSTYLE);
|
|
|
|
DWORD dwThisStyle = ::GetWindowLong((HWND) GetHWND(), GWL_STYLE);
|
|
|
|
DWORD dwNewStyle = dwStyle;
|
|
|
|
if (pChild != NULL && (dwThisStyle & WS_MAXIMIZE))
|
|
|
|
dwNewStyle &= ~(WS_EX_CLIENTEDGE);
|
|
|
|
else
|
|
|
|
dwNewStyle |= WS_EX_CLIENTEDGE;
|
|
|
|
|
|
|
|
if (dwStyle != dwNewStyle)
|
|
|
|
{
|
|
|
|
::RedrawWindow((HWND) pFrameWnd->GetClientWindow()->GetHWND(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
|
|
|
|
::SetWindowLong((HWND) pFrameWnd->GetClientWindow()->GetHWND(), GWL_EXSTYLE, dwNewStyle);
|
|
|
|
::SetWindowPos((HWND) pFrameWnd->GetClientWindow()->GetHWND(), NULL, 0, 0, 0, 0,
|
|
|
|
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOCOPYBITS);
|
|
|
|
if (rect)
|
|
|
|
::GetClientRect((HWND) pFrameWnd->GetClientWindow()->GetHWND(), rect);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
#else
|
|
|
|
return FALSE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxMDIChildFrame::MSWOnWindowPosChanging(void *pos)
|
|
|
|
{
|
|
|
|
WINDOWPOS *lpPos = (WINDOWPOS *)pos;
|
|
|
|
#if defined(__WIN95__)
|
|
|
|
if (!(lpPos->flags & SWP_NOSIZE))
|
|
|
|
{
|
|
|
|
RECT rectClient;
|
|
|
|
DWORD dwExStyle = ::GetWindowLong((HWND) GetHWND(), GWL_EXSTYLE);
|
|
|
|
DWORD dwStyle = ::GetWindowLong((HWND) GetHWND(), GWL_STYLE);
|
|
|
|
if (ResetWindowStyle((void *) & rectClient) && (dwStyle & WS_MAXIMIZE))
|
|
|
|
{
|
|
|
|
::AdjustWindowRectEx(&rectClient, dwStyle, FALSE, dwExStyle);
|
|
|
|
lpPos->x = rectClient.left;
|
|
|
|
lpPos->y = rectClient.top;
|
|
|
|
lpPos->cx = rectClient.right - rectClient.left;
|
|
|
|
lpPos->cy = rectClient.bottom - rectClient.top;
|
|
|
|
}
|
|
|
|
wxMDIParentFrame* pFrameWnd = (wxMDIParentFrame *)GetParent();
|
|
|
|
if (pFrameWnd && pFrameWnd->GetToolBar())
|
|
|
|
{
|
|
|
|
pFrameWnd->GetToolBar()->Refresh();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
Default();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Client window
|
|
|
|
wxMDIClientWindow::wxMDIClientWindow(void)
|
|
|
|
{
|
|
|
|
m_scrollX = 0;
|
|
|
|
m_scrollY = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxMDIClientWindow::~wxMDIClientWindow(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, const long style)
|
|
|
|
{
|
|
|
|
m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE);
|
|
|
|
|
|
|
|
CLIENTCREATESTRUCT ccs;
|
|
|
|
m_windowStyle = style;
|
|
|
|
m_windowParent = parent;
|
|
|
|
|
|
|
|
ccs.hWindowMenu = (HMENU) parent->GetWindowMenu();
|
|
|
|
ccs.idFirstChild = wxFIRST_MDI_CHILD;
|
|
|
|
|
|
|
|
DWORD msStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN ;
|
|
|
|
if ( parent->GetWindowStyleFlag() & wxHSCROLL )
|
|
|
|
msStyle |= WS_HSCROLL;
|
|
|
|
if ( parent->GetWindowStyleFlag() & wxVSCROLL )
|
|
|
|
msStyle |= WS_VSCROLL ;
|
|
|
|
|
|
|
|
#if defined(__WIN95__)
|
|
|
|
DWORD exStyle = WS_EX_CLIENTEDGE;
|
|
|
|
#else
|
|
|
|
DWORD exStyle = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
wxWndHook = this;
|
|
|
|
m_hWnd = (WXHWND) ::CreateWindowEx(exStyle, "mdiclient", NULL,
|
|
|
|
msStyle, 0, 0, 0, 0, (HWND) parent->GetHWND(), NULL,
|
|
|
|
wxGetInstance(), (LPSTR)(LPCLIENTCREATESTRUCT)&ccs);
|
|
|
|
SubclassWin(m_hWnd);
|
|
|
|
wxWndHook = NULL;
|
|
|
|
|
|
|
|
return (m_hWnd != 0) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Window procedure: here for debugging purposes
|
|
|
|
long wxMDIClientWindow::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
|
|
|
{
|
|
|
|
return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
|
|
|
|
// return MSWDefWindowProc(nMsg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
long wxMDIClientWindow::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
|
|
|
{
|
|
|
|
if ( MSWGetOldWndProc() != 0)
|
|
|
|
return ::CallWindowProc(CASTWNDPROC (FARPROC) MSWGetOldWndProc(), (HWND) GetHWND(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
|
|
|
|
else
|
|
|
|
return ::DefWindowProc((HWND) m_hWnd, (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Explicitly call default scroll behaviour
|
|
|
|
void wxMDIClientWindow::OnScroll(wxScrollEvent& event)
|
|
|
|
{
|
|
|
|
// Note: for client windows, the scroll position is not set in
|
|
|
|
// WM_HSCROLL, WM_VSCROLL, so we can't easily determine what
|
|
|
|
// scroll position we're at.
|
|
|
|
// This makes it hard to paint patterns or bitmaps in the background,
|
|
|
|
// and have the client area scrollable as well.
|
|
|
|
|
|
|
|
if ( event.GetOrientation() == wxHORIZONTAL )
|
|
|
|
m_scrollX = event.GetPosition(); // Always returns zero!
|
|
|
|
else
|
|
|
|
m_scrollY = event.GetPosition(); // Always returns zero!
|
|
|
|
|
|
|
|
Default();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should hand the message to the default proc
|
|
|
|
long wxMDIClientWindow::MSWOnMDIActivate(const long bActivate, const WXHWND, const WXHWND)
|
|
|
|
{
|
|
|
|
return Default();
|
|
|
|
}
|
|
|
|
|