Added wxTopLevelWindow::MSWGetSystemMenu() method.
Also generate events corresponding to WM_SYSCOMMAND messages for the custom items of the system menu. Add a small snippet to test the new functionality to the dialogs sample. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68596 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
960493053b
commit
ddae52629c
@ -467,6 +467,7 @@ GTK:
|
||||
MSW:
|
||||
|
||||
- Added wxGCDC(wxEnhMetaFileDC) ctor (Marcin Wojdyr).
|
||||
- Added wxTopLevelWindow::MSWGetSystemMenu().
|
||||
|
||||
|
||||
2.9.2: (released 2011-07-05)
|
||||
|
@ -77,6 +77,19 @@ public:
|
||||
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
|
||||
// --------------------------
|
||||
|
||||
@ -214,6 +227,10 @@ private:
|
||||
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);
|
||||
};
|
||||
|
@ -262,6 +262,33 @@ public:
|
||||
*/
|
||||
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.
|
||||
|
@ -648,6 +648,24 @@ MyFrame::MyFrame(const wxString& title)
|
||||
// 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()
|
||||
|
@ -141,6 +141,8 @@ void wxTopLevelWindowMSW::Init()
|
||||
|
||||
m_activateInfo = (void*) info;
|
||||
#endif
|
||||
|
||||
m_menuSystem = NULL;
|
||||
}
|
||||
|
||||
WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
|
||||
@ -326,9 +328,9 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX
|
||||
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;
|
||||
@ -355,8 +357,32 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX
|
||||
}
|
||||
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);
|
||||
@ -578,6 +604,8 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent,
|
||||
|
||||
wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
|
||||
{
|
||||
delete m_menuSystem;
|
||||
|
||||
SendDestroyEvent();
|
||||
|
||||
#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
|
||||
@ -1226,6 +1254,39 @@ void wxTopLevelWindowMSW::RequestUserAttention(int flags)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user