MSW:
- Added wxGCDC(wxEnhMetaFileDC) ctor (Marcin Wojdyr).
+- Added wxTopLevelWindow::MSWGetSystemMenu().
2.9.2: (released 2011-07-05)
virtual bool CanSetTransparent();
+ // MSW-specific methods
+ // --------------------
+
+ // Return the menu representing the "system" menu of the window. You can
+ // call wxMenu::AppendWhatever() methods on it but removing items from it
+ // is in general not a good idea.
+ //
+ // The pointer returned by this method belongs to the window and will be
+ // deleted when the window itself is, do not delete it yourself. May return
+ // NULL if getting the system menu failed.
+ wxMenu *MSWGetSystemMenu() const;
+
+
// implementation from now on
// --------------------------
void* m_activateInfo;
#endif
+ // The system menu: initially NULL but can be set (once) by
+ // MSWGetSystemMenu(). Owned by this window.
+ wxMenu *m_menuSystem;
+
DECLARE_EVENT_TABLE()
wxDECLARE_NO_COPY_CLASS(wxTopLevelWindowMSW);
};
*/
virtual void Maximize(bool maximize = true);
+ /**
+ MSW-specific function for accessing the system menu.
+
+ Returns a wxMenu pointer representing the system menu of the window
+ under MSW. The returned wxMenu may be used, if non-@c NULL, to add
+ extra items to the system menu. The usual @c wxEVT_COMMAND_MENU_SELECTED
+ events (that can be processed using @c EVT_MENU event table macro) will
+ then be generated for them. All the other wxMenu methods may be used as
+ well but notice that they won't allow you to access any standard system
+ menu items (e.g. they can't be deleted or modified in any way
+ currently).
+
+ Notice that because of the native system limitations the identifiers of
+ the items added to the system menu must be multiples of 16, otherwise
+ no events will be generated for them.
+
+ The returned pointer must @em not be deleted, it is owned by the window
+ and will be only deleted when the window itself is destroyed.
+
+ This function is not available in the other ports by design, any
+ occurrences of it in the portable code must be guarded by @code #ifdef
+ __WXMSW__ @endcode preprocessor guards.
+
+ @since 2.9.3
+ */
+ wxMenu *MSWGetSystemMenu() const;
+
/**
Use a system-dependent way to attract users attention to the window when
it is in background.
// covers our entire client area to avoid jarring colour jumps
SetOwnBackgroundColour(m_canvas->GetBackgroundColour());
#endif // wxUSE_INFOBAR
+
+#ifdef __WXMSW__
+ // Test MSW-specific function allowing to access the "system" menu.
+ wxMenu * const menu = MSWGetSystemMenu();
+ if ( menu )
+ {
+ menu->AppendSeparator();
+
+ // The ids of the menu commands in MSW system menu must be multiple of
+ // 16 so we can't use DIALOGS_ABOUTDLG_SIMPLE here because it might not
+ // satisfy this condition and need to define and connect a separate id.
+ static const int DIALOGS_SYSTEM_ABOUT = 0x4010;
+
+ menu->Append(DIALOGS_SYSTEM_ABOUT, "&About...");
+ Connect(DIALOGS_SYSTEM_ABOUT, wxEVT_COMMAND_MENU_SELECTED,
+ wxCommandEventHandler(MyFrame::ShowSimpleAboutDialog));
+ }
+#endif // __WXMSW__
}
MyFrame::~MyFrame()
m_activateInfo = (void*) info;
#endif
+
+ m_menuSystem = NULL;
}
WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
WXLRESULT rc = 0;
bool processed = false;
-#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
switch ( message )
{
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
case WM_ACTIVATE:
{
SHACTIVATEINFO* info = (SHACTIVATEINFO*) m_activateInfo;
}
break;
}
+#endif // __SMARTPHONE__ || __POCKETPC__
+
+ case WM_SYSCOMMAND:
+ // We may need to generate events for the items added to the system
+ // menu if it had been created (and presumably modified).
+ if ( m_menuSystem )
+ {
+ // From MSDN:
+ //
+ // ... the four low-order bits of the wParam parameter are
+ // used internally by the system. To obtain the correct
+ // result when testing the value of wParam, an application
+ // must combine the value 0xFFF0 with the wParam value by
+ // using the bitwise AND operator.
+ unsigned id = wParam & 0xfff0;
+
+ // SC_SIZE is the first of the system-defined commands and we
+ // leave those to DefWindowProc().
+ if ( id < SC_SIZE )
+ {
+ if ( m_menuSystem->MSWCommand(0 /* unused anyhow */, id) )
+ processed = true;
+ }
+ }
+ break;
}
-#endif
if ( !processed )
rc = wxTopLevelWindowBase::MSWWindowProc(message, wParam, lParam);
wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
{
+ delete m_menuSystem;
+
SendDestroyEvent();
#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
}
}
+wxMenu *wxTopLevelWindowMSW::MSWGetSystemMenu() const
+{
+ if ( !m_menuSystem )
+ {
+ HMENU hmenu = ::GetSystemMenu(GetHwnd(), FALSE);
+ if ( !hmenu )
+ {
+ wxLogLastError(wxT("GetSystemMenu()"));
+ return NULL;
+ }
+
+ wxTopLevelWindowMSW * const
+ self = const_cast<wxTopLevelWindowMSW *>(this);
+
+ self->m_menuSystem = wxMenu::MSWNewFromHMENU(hmenu);
+
+ // We need to somehow associate this menu with this window to ensure
+ // that we get events from it. A natural idea would be to pretend that
+ // it's attached to our menu bar but this wouldn't work if we don't
+ // have any menu bar which is a common case for applications using
+ // custom items in the system menu (they mostly do it exactly because
+ // they don't have any other menus).
+ //
+ // So reuse the invoking window pointer instead, this is not exactly
+ // correct but doesn't seem to have any serious drawbacks.
+ m_menuSystem->SetInvokingWindow(self);
+ }
+
+ return m_menuSystem;
+}
+
+// ----------------------------------------------------------------------------
+// Transparency support
// ---------------------------------------------------------------------------
bool wxTopLevelWindowMSW::SetTransparent(wxByte alpha)