refactor WM_COMMAND messages handling in MDI frames to avoid duplicating code unnecessarily and generally streamline it; added possibility to use custom menu commands in the "Window" menu and specifying accelerators for them now works too (show this in the sample); finally added standard ids for the MDI window menu commands
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58462 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -144,6 +144,16 @@ wxID_MAXIMIZE_FRAME,
|
||||
wxID_ICONIZE_FRAME,
|
||||
wxID_RESTORE_FRAME,
|
||||
|
||||
// MDI window menu ids
|
||||
wxID_MDI_WINDOW_FIRST = 5230,
|
||||
wxID_MDI_WINDOW_CASCADE = wxID_MDI_WINDOW_FIRST,
|
||||
wxID_MDI_WINDOW_TILE_HORZ,
|
||||
wxID_MDI_WINDOW_TILE_VERT,
|
||||
wxID_MDI_WINDOW_ARRANGE_ICONS,
|
||||
wxID_MDI_WINDOW_PREV,
|
||||
wxID_MDI_WINDOW_NEXT,
|
||||
wxID_MDI_WINDOW_LAST = wxID_MDI_WINDOW_NEXT,
|
||||
|
||||
// IDs used by generic file dialog (13 consecutive starting from this value)
|
||||
wxID_FILEDLGG = 5900,
|
||||
|
||||
|
@@ -2002,6 +2002,16 @@ enum
|
||||
wxID_ICONIZE_FRAME,
|
||||
wxID_RESTORE_FRAME,
|
||||
|
||||
/* MDI window menu ids */
|
||||
wxID_MDI_WINDOW_FIRST = 5230,
|
||||
wxID_MDI_WINDOW_CASCADE = wxID_MDI_WINDOW_FIRST,
|
||||
wxID_MDI_WINDOW_TILE_HORZ,
|
||||
wxID_MDI_WINDOW_TILE_VERT,
|
||||
wxID_MDI_WINDOW_ARRANGE_ICONS,
|
||||
wxID_MDI_WINDOW_PREV,
|
||||
wxID_MDI_WINDOW_NEXT,
|
||||
wxID_MDI_WINDOW_LAST = wxID_MDI_WINDOW_NEXT,
|
||||
|
||||
/* IDs used by generic file dialog (13 consecutive starting from this value) */
|
||||
wxID_FILEDLGG = 5900,
|
||||
|
||||
|
@@ -107,6 +107,9 @@ public:
|
||||
// get the currently active menu: this is the same as the frame menu for
|
||||
// normal frames but is overridden by wxMDIParentFrame
|
||||
virtual WXHMENU MSWGetActiveMenu() const { return m_hMenu; }
|
||||
|
||||
// find the item in our menu bar: this is again a hook for MDI frames
|
||||
virtual wxMenuItem *MSWFindMenuBarItem(WXWORD id);
|
||||
#endif // wxUSE_MENUS
|
||||
|
||||
protected:
|
||||
|
@@ -15,6 +15,8 @@
|
||||
|
||||
#include "wx/frame.h"
|
||||
|
||||
class WXDLLIMPEXP_FWD_CORE wxAcceleratorTable;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// wxMDIParentFrame
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -22,7 +24,7 @@
|
||||
class WXDLLIMPEXP_CORE wxMDIParentFrame : public wxMDIParentFrameBase
|
||||
{
|
||||
public:
|
||||
wxMDIParentFrame();
|
||||
wxMDIParentFrame() { }
|
||||
wxMDIParentFrame(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxString& title,
|
||||
@@ -103,6 +105,7 @@ public:
|
||||
#if wxUSE_MENUS
|
||||
// override wxFrameBase function to also look in the active child menu bar
|
||||
virtual const wxMenuItem *FindItemInMenuBar(int menuId) const;
|
||||
virtual wxMenuItem *MSWFindMenuBarItem(WXWORD id);
|
||||
#endif // wxUSE_MENUS
|
||||
|
||||
protected:
|
||||
@@ -115,12 +118,13 @@ protected:
|
||||
// set the size of the MDI client window to match the frame size
|
||||
void UpdateClientSize();
|
||||
|
||||
|
||||
// true if MDI Frame is intercepting commands, not child
|
||||
bool m_parentFrameActive;
|
||||
|
||||
private:
|
||||
#if wxUSE_MENUS
|
||||
// "Window" menu commands event handlers
|
||||
void OnMDICommand(wxCommandEvent& event);
|
||||
void OnMDIChild(wxCommandEvent& event);
|
||||
|
||||
|
||||
// add/remove window menu if we have it (i.e. m_windowMenu != NULL)
|
||||
void AddWindowMenu();
|
||||
void RemoveWindowMenu();
|
||||
@@ -128,6 +132,10 @@ private:
|
||||
// update the window menu (if we have it) to enable or disable the commands
|
||||
// which only make sense when we have more than one child
|
||||
void UpdateWindowMenu(bool enable);
|
||||
|
||||
#if wxUSE_ACCEL
|
||||
wxAcceleratorTable *m_accelWindowMenu;
|
||||
#endif // wxUSE_ACCEL
|
||||
#endif // wxUSE_MENUS
|
||||
|
||||
// return the number of child frames we currently have (maybe 0)
|
||||
@@ -187,7 +195,6 @@ public:
|
||||
// Handlers
|
||||
bool HandleMDIActivate(long bActivate, WXHWND, WXHWND);
|
||||
bool HandleWindowPosChanging(void *lpPos);
|
||||
bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control);
|
||||
bool HandleGetMinMaxInfo(void *mmInfo);
|
||||
|
||||
virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
|
||||
|
@@ -310,6 +310,17 @@ public:
|
||||
window style but this function also allows to do it by passing @NULL
|
||||
pointer as @a menu.
|
||||
|
||||
The menu may include the items with the following standard identifiers
|
||||
(but may use arbitrary text and help strings and bitmaps for them):
|
||||
- @c wxID_MDI_WINDOW_CASCADE
|
||||
- @c wxID_MDI_WINDOW_TILE_HORZ
|
||||
- @c wxID_MDI_WINDOW_TILE_VERT
|
||||
- @c wxID_MDI_WINDOW_ARRANGE_ICONS
|
||||
- @c wxID_MDI_WINDOW_PREV
|
||||
- @c wxID_MDI_WINDOW_NEXT
|
||||
All of which are handled by wxMDIParentFrame itself. If any other
|
||||
commands are used in the menu, the derived frame should handle them.
|
||||
|
||||
This function is currently not available under OS X.
|
||||
|
||||
@param menu
|
||||
|
@@ -69,6 +69,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
|
||||
EVT_MENU(MDI_FULLSCREEN, MyFrame::OnFullScreen)
|
||||
EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
|
||||
|
||||
EVT_MENU(wxID_CLOSE_ALL, MyFrame::OnCloseAll)
|
||||
|
||||
EVT_CLOSE(MyFrame::OnClose)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
@@ -150,12 +152,33 @@ MyFrame::MyFrame()
|
||||
// Associate the menu bar with the frame
|
||||
SetMenuBar(menu_bar);
|
||||
|
||||
#if 0
|
||||
// Experimental: change the window menu
|
||||
wxMenu* windowMenu = new wxMenu;
|
||||
windowMenu->Append(5000, "My menu item!");
|
||||
frame->SetWindowMenu(windowMenu);
|
||||
#endif
|
||||
|
||||
// This shows that the standard window menu may be customized:
|
||||
wxMenu * const windowMenu = GetWindowMenu();
|
||||
if ( windowMenu )
|
||||
{
|
||||
// we can change the labels of standard items (which also means we can
|
||||
// set up accelerators for them as they're part of the label)
|
||||
windowMenu->SetLabel(wxID_MDI_WINDOW_TILE_HORZ,
|
||||
"&Tile horizontally\tCtrl-Shift-H");
|
||||
windowMenu->SetLabel(wxID_MDI_WINDOW_TILE_VERT,
|
||||
"&Tile vertically\tCtrl-Shift-V");
|
||||
|
||||
// we can also change the help string
|
||||
windowMenu->SetHelpString(wxID_MDI_WINDOW_CASCADE,
|
||||
"Arrange windows in cascade");
|
||||
|
||||
// we can remove some items
|
||||
windowMenu->Delete(wxID_MDI_WINDOW_ARRANGE_ICONS);
|
||||
|
||||
// and we can add completely custom commands -- but then we must handle
|
||||
// them ourselves, see OnCloseAll()
|
||||
windowMenu->AppendSeparator();
|
||||
windowMenu->Append(wxID_CLOSE_ALL, "&Close all windows\tCtrl-Shift-C",
|
||||
"Close all open windows");
|
||||
|
||||
SetWindowMenu(windowMenu);
|
||||
}
|
||||
#endif // wxUSE_MENUS
|
||||
|
||||
#if wxUSE_STATUSBAR
|
||||
@@ -236,6 +259,17 @@ void MyFrame::OnFullScreen(wxCommandEvent& event)
|
||||
ShowFullScreen(event.IsChecked());
|
||||
}
|
||||
|
||||
void MyFrame::OnCloseAll(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
for ( wxWindowList::const_iterator i = GetChildren().begin();
|
||||
i != GetChildren().end();
|
||||
++i )
|
||||
{
|
||||
if ( wxDynamicCast(*i, wxMDIChildFrame) )
|
||||
(*i)->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void MyFrame::OnSize(wxSizeEvent& event)
|
||||
{
|
||||
int w, h;
|
||||
|
@@ -53,6 +53,8 @@ private:
|
||||
void OnNewWindow(wxCommandEvent& event);
|
||||
void OnFullScreen(wxCommandEvent& event);
|
||||
void OnQuit(wxCommandEvent& event);
|
||||
void OnCloseAll(wxCommandEvent& event);
|
||||
|
||||
void OnClose(wxCloseEvent& event);
|
||||
|
||||
wxTextCtrl *m_textWindow;
|
||||
|
@@ -890,8 +890,9 @@ bool wxFrame::HandleSize(int WXUNUSED(x), int WXUNUSED(y), WXUINT id)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wxFrame::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control)
|
||||
bool wxFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
|
||||
{
|
||||
#if wxUSE_MENUS
|
||||
// we only need to handle the menu and accelerator commands from the items
|
||||
// of our menu bar, base wxWindow class already handles the rest
|
||||
if ( !control && (cmd == 0 /* menu */ || cmd == 1 /* accel */) )
|
||||
@@ -900,25 +901,24 @@ bool wxFrame::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control)
|
||||
if ( !wxCurrentPopupMenu )
|
||||
#endif // wxUSE_MENUS_NATIVE
|
||||
{
|
||||
wxMenuBar * const mbar = GetMenuBar();
|
||||
if ( mbar )
|
||||
{
|
||||
// sign extend to int from short before comparing with the
|
||||
// other int ids
|
||||
const int id = (signed short)id_;
|
||||
|
||||
wxMenuItem * const mitem = mbar->FindItem(id);
|
||||
wxMenuItem * const mitem = MSWFindMenuBarItem(id);
|
||||
if ( mitem )
|
||||
return ProcessCommand(mitem);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // wxUSE_MENUS
|
||||
|
||||
return wxFrameBase::HandleCommand(id_, cmd, control);;
|
||||
return wxFrameBase::HandleCommand(id, cmd, control);;
|
||||
}
|
||||
|
||||
#if wxUSE_MENUS
|
||||
|
||||
wxMenuItem *wxFrame::MSWFindMenuBarItem(WXWORD id)
|
||||
{
|
||||
wxMenuBar * const mbar = GetMenuBar();
|
||||
return mbar ? mbar->FindItem((signed short)id) : NULL;
|
||||
}
|
||||
|
||||
bool wxFrame::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu)
|
||||
{
|
||||
int item;
|
||||
|
326
src/msw/mdi.cpp
326
src/msw/mdi.cpp
@@ -59,13 +59,6 @@ extern void wxRemoveHandleAssociation(wxWindow *win);
|
||||
// constants
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static const int IDM_WINDOWTILEHOR = 4001;
|
||||
static const int IDM_WINDOWCASCADE = 4002;
|
||||
static const int IDM_WINDOWICONS = 4003;
|
||||
static const int IDM_WINDOWNEXT = 4004;
|
||||
static const int IDM_WINDOWTILEVERT = 4005;
|
||||
static const int IDM_WINDOWPREV = 4006;
|
||||
|
||||
// This range gives a maximum of 500 MDI children. Should be enough :-)
|
||||
static const int wxFIRST_MDI_CHILD = 4100;
|
||||
static const int wxLAST_MDI_CHILD = 4600;
|
||||
@@ -85,12 +78,6 @@ static void MDIInsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu);
|
||||
// Remove the window menu
|
||||
static void MDIRemoveWindowMenu(wxWindow *win, WXHMENU menu);
|
||||
|
||||
// is this an id of an MDI child?
|
||||
inline bool IsMdiCommandId(int id)
|
||||
{
|
||||
return (id >= wxFIRST_MDI_CHILD) && (id <= wxLAST_MDI_CHILD);
|
||||
}
|
||||
|
||||
// unpack the parameters of WM_MDIACTIVATE message
|
||||
static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
|
||||
WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact);
|
||||
@@ -121,6 +108,13 @@ BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
|
||||
EVT_SIZE(wxMDIParentFrame::OnSize)
|
||||
EVT_ICONIZE(wxMDIParentFrame::OnIconized)
|
||||
EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
|
||||
|
||||
#if wxUSE_MENUS
|
||||
EVT_MENU_RANGE(wxFIRST_MDI_CHILD, wxLAST_MDI_CHILD,
|
||||
wxMDIParentFrame::OnMDIChild)
|
||||
EVT_MENU_RANGE(wxID_MDI_WINDOW_FIRST, wxID_MDI_WINDOW_LAST,
|
||||
wxMDIParentFrame::OnMDICommand)
|
||||
#endif // wxUSE_MENUS
|
||||
END_EVENT_TABLE()
|
||||
|
||||
BEGIN_EVENT_TABLE(wxMDIChildFrame, wxFrame)
|
||||
@@ -136,11 +130,6 @@ END_EVENT_TABLE()
|
||||
// the children
|
||||
// ===========================================================================
|
||||
|
||||
wxMDIParentFrame::wxMDIParentFrame()
|
||||
{
|
||||
m_parentFrameActive = true;
|
||||
}
|
||||
|
||||
bool wxMDIParentFrame::Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxString& title,
|
||||
@@ -156,16 +145,19 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
|
||||
// normal case: we have the window menu, so construct it
|
||||
m_windowMenu = new wxMenu;
|
||||
|
||||
m_windowMenu->Append(IDM_WINDOWCASCADE, _("&Cascade"));
|
||||
m_windowMenu->Append(IDM_WINDOWTILEHOR, _("Tile &Horizontally"));
|
||||
m_windowMenu->Append(IDM_WINDOWTILEVERT, _("Tile &Vertically"));
|
||||
m_windowMenu->Append(wxID_MDI_WINDOW_CASCADE, _("&Cascade"));
|
||||
m_windowMenu->Append(wxID_MDI_WINDOW_TILE_HORZ, _("Tile &Horizontally"));
|
||||
m_windowMenu->Append(wxID_MDI_WINDOW_TILE_VERT, _("Tile &Vertically"));
|
||||
m_windowMenu->AppendSeparator();
|
||||
m_windowMenu->Append(IDM_WINDOWICONS, _("&Arrange Icons"));
|
||||
m_windowMenu->Append(IDM_WINDOWNEXT, _("&Next"));
|
||||
m_windowMenu->Append(IDM_WINDOWPREV, _("&Previous"));
|
||||
m_windowMenu->Append(wxID_MDI_WINDOW_ARRANGE_ICONS, _("&Arrange Icons"));
|
||||
m_windowMenu->Append(wxID_MDI_WINDOW_NEXT, _("&Next"));
|
||||
m_windowMenu->Append(wxID_MDI_WINDOW_PREV, _("&Previous"));
|
||||
}
|
||||
|
||||
m_parentFrameActive = true;
|
||||
#if wxUSE_MENUS && wxUSE_ACCEL
|
||||
// the default menu doesn't have any accelerators (even if we have it)
|
||||
m_accelWindowMenu = NULL;
|
||||
#endif // wxUSE_MENUS && wxUSE_ACCEL
|
||||
|
||||
if (!parent)
|
||||
wxTopLevelWindows.Append(this);
|
||||
@@ -213,6 +205,10 @@ wxMDIParentFrame::~wxMDIParentFrame()
|
||||
m_frameStatusBar = NULL;
|
||||
#endif // wxUSE_STATUSBAR
|
||||
|
||||
#if wxUSE_MENUS && wxUSE_ACCEL
|
||||
delete m_accelWindowMenu;
|
||||
#endif // wxUSE_MENUS && wxUSE_ACCEL
|
||||
|
||||
DestroyChildren();
|
||||
|
||||
// the MDI frame menubar is not automatically deleted by Windows unlike for
|
||||
@@ -238,10 +234,10 @@ wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
|
||||
{
|
||||
HWND hWnd = (HWND)::SendMessage(GetWinHwnd(GetClientWindow()),
|
||||
WM_MDIGETACTIVE, 0, 0L);
|
||||
if ( hWnd == 0 )
|
||||
if ( !hWnd )
|
||||
return NULL;
|
||||
|
||||
return (wxMDIChildFrame *)wxFindWinFromHandle(hWnd);
|
||||
return static_cast<wxMDIChildFrame *>(wxFindWinFromHandle(hWnd));
|
||||
}
|
||||
|
||||
int wxMDIParentFrame::GetChildFramesCount() const
|
||||
@@ -323,8 +319,8 @@ void wxMDIParentFrame::UpdateWindowMenu(bool enable)
|
||||
{
|
||||
if ( m_windowMenu )
|
||||
{
|
||||
m_windowMenu->Enable(IDM_WINDOWNEXT, enable);
|
||||
m_windowMenu->Enable(IDM_WINDOWPREV, enable);
|
||||
m_windowMenu->Enable(wxID_MDI_WINDOW_NEXT, enable);
|
||||
m_windowMenu->Enable(wxID_MDI_WINDOW_PREV, enable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,8 +328,6 @@ void wxMDIParentFrame::UpdateWindowMenu(bool enable)
|
||||
|
||||
void wxMDIParentFrame::InternalSetMenuBar()
|
||||
{
|
||||
m_parentFrameActive = true;
|
||||
|
||||
if ( GetActiveChild() )
|
||||
{
|
||||
AddWindowMenu();
|
||||
@@ -350,6 +344,8 @@ void wxMDIParentFrame::InternalSetMenuBar()
|
||||
|
||||
void wxMDIParentFrame::SetWindowMenu(wxMenu* menu)
|
||||
{
|
||||
if ( menu != m_windowMenu )
|
||||
{
|
||||
// notice that Remove/AddWindowMenu() are safe to call even when
|
||||
// m_windowMenu is NULL
|
||||
RemoveWindowMenu();
|
||||
@@ -359,6 +355,15 @@ void wxMDIParentFrame::SetWindowMenu(wxMenu* menu)
|
||||
m_windowMenu = menu;
|
||||
|
||||
AddWindowMenu();
|
||||
}
|
||||
|
||||
#if wxUSE_ACCEL
|
||||
delete m_accelWindowMenu;
|
||||
m_accelWindowMenu = NULL;
|
||||
|
||||
if ( menu && menu->HasAccels() )
|
||||
m_accelWindowMenu = menu->CreateAccelTable();
|
||||
#endif // wxUSE_ACCEL
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -396,9 +401,9 @@ void wxMDIParentFrame::DoMenuUpdates(wxMenu* menu)
|
||||
const wxMenuItem *wxMDIParentFrame::FindItemInMenuBar(int menuId) const
|
||||
{
|
||||
const wxMenuItem *item = wxFrame::FindItemInMenuBar(menuId);
|
||||
if ( !item && m_currentChild )
|
||||
if ( !item && GetActiveChild() )
|
||||
{
|
||||
item = m_currentChild->FindItemInMenuBar(menuId);
|
||||
item = GetActiveChild()->FindItemInMenuBar(menuId);
|
||||
}
|
||||
|
||||
return item;
|
||||
@@ -587,94 +592,22 @@ bool wxMDIParentFrame::HandleActivate(int state, bool minimized, WXHWND activate
|
||||
|
||||
// If this window is an MDI parent, we must also send an OnActivate message
|
||||
// to the current child.
|
||||
if ( (m_currentChild != NULL) &&
|
||||
if ( GetActiveChild() &&
|
||||
((state == WA_ACTIVE) || (state == WA_CLICKACTIVE)) )
|
||||
{
|
||||
wxActivateEvent event(wxEVT_ACTIVATE, true, m_currentChild->GetId());
|
||||
event.SetEventObject( m_currentChild );
|
||||
if ( m_currentChild->HandleWindowEvent(event) )
|
||||
wxActivateEvent event(wxEVT_ACTIVATE, true, GetActiveChild()->GetId());
|
||||
event.SetEventObject( GetActiveChild() );
|
||||
if ( GetActiveChild()->HandleWindowEvent(event) )
|
||||
processed = true;
|
||||
}
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
bool wxMDIParentFrame::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND hwnd)
|
||||
#if wxUSE_MENUS
|
||||
|
||||
void wxMDIParentFrame::OnMDIChild(wxCommandEvent& event)
|
||||
{
|
||||
// sign extend to int from short before comparing with the other int ids
|
||||
int id = (signed short)id_;
|
||||
|
||||
// In case it's e.g. a toolbar.
|
||||
if ( hwnd )
|
||||
{
|
||||
wxWindow *win = wxFindWinFromHandle(hwnd);
|
||||
if ( win )
|
||||
return win->MSWCommand(cmd, id);
|
||||
}
|
||||
|
||||
if (wxCurrentPopupMenu)
|
||||
{
|
||||
wxMenu *popupMenu = wxCurrentPopupMenu;
|
||||
wxCurrentPopupMenu = NULL;
|
||||
if (popupMenu->MSWCommand(cmd, id))
|
||||
return true;
|
||||
}
|
||||
|
||||
// is it one of standard MDI commands?
|
||||
WXWPARAM wParam = 0;
|
||||
WXLPARAM lParam = 0;
|
||||
int msg;
|
||||
switch ( id )
|
||||
{
|
||||
case IDM_WINDOWCASCADE:
|
||||
msg = WM_MDICASCADE;
|
||||
wParam = MDITILE_SKIPDISABLED;
|
||||
break;
|
||||
|
||||
case IDM_WINDOWTILEHOR:
|
||||
wParam |= MDITILE_HORIZONTAL;
|
||||
// fall through
|
||||
|
||||
case IDM_WINDOWTILEVERT:
|
||||
if ( !wParam )
|
||||
wParam = MDITILE_VERTICAL;
|
||||
msg = WM_MDITILE;
|
||||
wParam |= MDITILE_SKIPDISABLED;
|
||||
break;
|
||||
|
||||
case IDM_WINDOWICONS:
|
||||
msg = WM_MDIICONARRANGE;
|
||||
break;
|
||||
|
||||
case IDM_WINDOWNEXT:
|
||||
msg = WM_MDINEXT;
|
||||
lParam = 0; // next child
|
||||
break;
|
||||
|
||||
case IDM_WINDOWPREV:
|
||||
msg = WM_MDINEXT;
|
||||
lParam = 1; // previous child
|
||||
break;
|
||||
|
||||
default:
|
||||
msg = 0;
|
||||
}
|
||||
|
||||
if ( msg )
|
||||
{
|
||||
::SendMessage(GetWinHwnd(GetClientWindow()), msg, wParam, lParam);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME VZ: what does this test do??
|
||||
if (id >= 0xF000)
|
||||
{
|
||||
return false; // Get WndProc to call default proc
|
||||
}
|
||||
|
||||
if ( IsMdiCommandId(id) )
|
||||
{
|
||||
wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
|
||||
while ( node )
|
||||
{
|
||||
@@ -682,33 +615,84 @@ bool wxMDIParentFrame::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND hwnd)
|
||||
if ( child->GetHWND() )
|
||||
{
|
||||
int childId = wxGetWindowId(child->GetHWND());
|
||||
if ( childId == (signed short)id )
|
||||
if ( childId == event.GetId() )
|
||||
{
|
||||
::SendMessage( GetWinHwnd(GetClientWindow()),
|
||||
WM_MDIACTIVATE,
|
||||
(WPARAM)child->GetHWND(), 0);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
else if ( m_parentFrameActive )
|
||||
{
|
||||
return ProcessCommand(id);
|
||||
}
|
||||
else if ( m_currentChild )
|
||||
{
|
||||
return m_currentChild->HandleCommand(id, cmd, hwnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this shouldn't happen because it means that our messages are being
|
||||
// lost (they're not sent to the parent frame nor to the children)
|
||||
wxFAIL_MSG(wxT("MDI parent frame is not active, yet there is no active MDI child?"));
|
||||
}
|
||||
|
||||
return false;
|
||||
node = node->GetNext();
|
||||
}
|
||||
|
||||
wxFAIL_MSG( "unknown MDI child selected?" );
|
||||
}
|
||||
|
||||
void wxMDIParentFrame::OnMDICommand(wxCommandEvent& event)
|
||||
{
|
||||
WXWPARAM wParam = 0;
|
||||
WXLPARAM lParam = 0;
|
||||
int msg;
|
||||
switch ( event.GetId() )
|
||||
{
|
||||
case wxID_MDI_WINDOW_CASCADE:
|
||||
msg = WM_MDICASCADE;
|
||||
wParam = MDITILE_SKIPDISABLED;
|
||||
break;
|
||||
|
||||
case wxID_MDI_WINDOW_TILE_HORZ:
|
||||
wParam |= MDITILE_HORIZONTAL;
|
||||
// fall through
|
||||
|
||||
case wxID_MDI_WINDOW_TILE_VERT:
|
||||
if ( !wParam )
|
||||
wParam = MDITILE_VERTICAL;
|
||||
msg = WM_MDITILE;
|
||||
wParam |= MDITILE_SKIPDISABLED;
|
||||
break;
|
||||
|
||||
case wxID_MDI_WINDOW_ARRANGE_ICONS:
|
||||
msg = WM_MDIICONARRANGE;
|
||||
break;
|
||||
|
||||
case wxID_MDI_WINDOW_NEXT:
|
||||
msg = WM_MDINEXT;
|
||||
lParam = 0; // next child
|
||||
break;
|
||||
|
||||
case wxID_MDI_WINDOW_PREV:
|
||||
msg = WM_MDINEXT;
|
||||
lParam = 1; // previous child
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "unknown MDI command" );
|
||||
return;
|
||||
}
|
||||
|
||||
::SendMessage(GetWinHwnd(GetClientWindow()), msg, wParam, lParam);
|
||||
}
|
||||
|
||||
wxMenuItem *wxMDIParentFrame::MSWFindMenuBarItem(WXWORD id)
|
||||
{
|
||||
wxMenuItem *mitem = wxFrame::MSWFindMenuBarItem(id);
|
||||
if ( !mitem && m_windowMenu )
|
||||
mitem = m_windowMenu->FindItem((signed short)id);
|
||||
|
||||
return mitem;
|
||||
}
|
||||
|
||||
#endif // wxUSE_MENUS
|
||||
|
||||
bool wxMDIParentFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
|
||||
{
|
||||
wxMDIChildFrame * const child = GetActiveChild();
|
||||
if ( child && child->HandleCommand(id, cmd, hwnd) )
|
||||
return true;
|
||||
|
||||
return wxFrame::HandleCommand(id, cmd, hwnd);
|
||||
}
|
||||
|
||||
WXLRESULT wxMDIParentFrame::MSWDefWindowProc(WXUINT message,
|
||||
@@ -729,19 +713,28 @@ bool wxMDIParentFrame::MSWTranslateMessage(WXMSG* msg)
|
||||
MSG *pMsg = (MSG *)msg;
|
||||
|
||||
// first let the current child get it
|
||||
if ( m_currentChild && m_currentChild->GetHWND() &&
|
||||
m_currentChild->MSWTranslateMessage(msg) )
|
||||
wxMDIChildFrame * const child = GetActiveChild();
|
||||
if ( child && child->MSWTranslateMessage(msg) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// then try out accel table (will also check the menu accels)
|
||||
// then try out accelerator table (will also check the accelerators for the
|
||||
// normal menu items)
|
||||
if ( wxFrame::MSWTranslateMessage(msg) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// finally, check for MDI specific built in accel keys
|
||||
#if wxUSE_MENUS && wxUSE_ACCEL
|
||||
// but it doesn't check for the (custom) accelerators of the window menu
|
||||
// items as it's not part of the menu bar as it's handled by Windows itself
|
||||
// so we need to do this explicitly
|
||||
if ( m_accelWindowMenu->Translate(this, msg) )
|
||||
return true;
|
||||
#endif // wxUSE_MENUS && wxUSE_ACCEL
|
||||
|
||||
// finally, check for MDI specific built-in accelerators
|
||||
if ( pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN )
|
||||
{
|
||||
if ( ::TranslateMDISysAccel(GetWinHwnd(GetClientWindow()), pMsg))
|
||||
@@ -985,8 +978,6 @@ void wxMDIChildFrame::InternalSetMenuBar()
|
||||
|
||||
MDIInsertWindowMenu(parent->GetClientWindow(),
|
||||
m_hMenu, GetMDIWindowMenu(parent));
|
||||
|
||||
parent->m_parentFrameActive = false;
|
||||
}
|
||||
|
||||
void wxMDIChildFrame::DetachMenuBar()
|
||||
@@ -1049,17 +1040,6 @@ WXLRESULT wxMDIChildFrame::MSWWindowProc(WXUINT message,
|
||||
|
||||
switch ( message )
|
||||
{
|
||||
case WM_COMMAND:
|
||||
{
|
||||
WORD id, cmd;
|
||||
WXHWND hwnd;
|
||||
UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
|
||||
&id, &hwnd, &cmd);
|
||||
|
||||
processed = HandleCommand(id, cmd, (WXHWND)hwnd);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_GETMINMAXINFO:
|
||||
processed = HandleGetMinMaxInfo((MINMAXINFO *)lParam);
|
||||
break;
|
||||
@@ -1102,40 +1082,6 @@ WXLRESULT wxMDIChildFrame::MSWWindowProc(WXUINT message,
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool wxMDIChildFrame::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND hwnd)
|
||||
{
|
||||
// sign extend to int from short before comparing with the other int ids
|
||||
int id = (signed short)id_;
|
||||
|
||||
// In case it's e.g. a toolbar.
|
||||
if ( hwnd )
|
||||
{
|
||||
wxWindow *win = wxFindWinFromHandle(hwnd);
|
||||
if (win)
|
||||
return win->MSWCommand(cmd, id);
|
||||
}
|
||||
|
||||
if (wxCurrentPopupMenu)
|
||||
{
|
||||
wxMenu *popupMenu = wxCurrentPopupMenu;
|
||||
wxCurrentPopupMenu = NULL;
|
||||
if (popupMenu->MSWCommand(cmd, id))
|
||||
return true;
|
||||
}
|
||||
|
||||
bool processed;
|
||||
if (GetMenuBar() && GetMenuBar()->FindItem(id))
|
||||
{
|
||||
processed = ProcessCommand(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
processed = false;
|
||||
}
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate),
|
||||
WXHWND hwndAct,
|
||||
WXHWND hwndDeact)
|
||||
@@ -1149,35 +1095,27 @@ bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate),
|
||||
if ( m_hWnd == hwndAct )
|
||||
{
|
||||
activated = true;
|
||||
parent->m_currentChild = this;
|
||||
parent->SetActiveChild(this);
|
||||
|
||||
WXHMENU hMenuChild = m_hMenu;
|
||||
if ( hMenuChild )
|
||||
{
|
||||
parent->m_parentFrameActive = false;
|
||||
|
||||
hMenuToSet = hMenuChild;
|
||||
}
|
||||
}
|
||||
else if ( m_hWnd == hwndDeact )
|
||||
{
|
||||
wxASSERT_MSG( parent->m_currentChild == this,
|
||||
wxASSERT_MSG( parent->GetActiveChild() == this,
|
||||
wxT("can't deactivate MDI child which wasn't active!") );
|
||||
|
||||
activated = false;
|
||||
parent->m_currentChild = NULL;
|
||||
parent->SetActiveChild(NULL);
|
||||
|
||||
WXHMENU hMenuParent = parent->m_hMenu;
|
||||
|
||||
// activate the the parent menu only when there is no other child
|
||||
// that has been activated
|
||||
if ( hMenuParent && !hwndAct )
|
||||
{
|
||||
parent->m_parentFrameActive = true;
|
||||
|
||||
hMenuToSet = hMenuParent;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have nothing to do with it
|
||||
|
Reference in New Issue
Block a user