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:
@@ -467,6 +467,7 @@ GTK:
|
|||||||
MSW:
|
MSW:
|
||||||
|
|
||||||
- Added wxGCDC(wxEnhMetaFileDC) ctor (Marcin Wojdyr).
|
- Added wxGCDC(wxEnhMetaFileDC) ctor (Marcin Wojdyr).
|
||||||
|
- Added wxTopLevelWindow::MSWGetSystemMenu().
|
||||||
|
|
||||||
|
|
||||||
2.9.2: (released 2011-07-05)
|
2.9.2: (released 2011-07-05)
|
||||||
|
@@ -77,6 +77,19 @@ public:
|
|||||||
virtual bool CanSetTransparent();
|
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
|
// implementation from now on
|
||||||
// --------------------------
|
// --------------------------
|
||||||
|
|
||||||
@@ -214,6 +227,10 @@ private:
|
|||||||
void* m_activateInfo;
|
void* m_activateInfo;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// The system menu: initially NULL but can be set (once) by
|
||||||
|
// MSWGetSystemMenu(). Owned by this window.
|
||||||
|
wxMenu *m_menuSystem;
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
wxDECLARE_NO_COPY_CLASS(wxTopLevelWindowMSW);
|
wxDECLARE_NO_COPY_CLASS(wxTopLevelWindowMSW);
|
||||||
};
|
};
|
||||||
|
@@ -262,6 +262,33 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void Maximize(bool maximize = true);
|
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
|
Use a system-dependent way to attract users attention to the window when
|
||||||
it is in background.
|
it is in background.
|
||||||
|
@@ -648,6 +648,24 @@ MyFrame::MyFrame(const wxString& title)
|
|||||||
// covers our entire client area to avoid jarring colour jumps
|
// covers our entire client area to avoid jarring colour jumps
|
||||||
SetOwnBackgroundColour(m_canvas->GetBackgroundColour());
|
SetOwnBackgroundColour(m_canvas->GetBackgroundColour());
|
||||||
#endif // wxUSE_INFOBAR
|
#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()
|
MyFrame::~MyFrame()
|
||||||
|
@@ -141,6 +141,8 @@ void wxTopLevelWindowMSW::Init()
|
|||||||
|
|
||||||
m_activateInfo = (void*) info;
|
m_activateInfo = (void*) info;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
m_menuSystem = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
|
WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
|
||||||
@@ -326,9 +328,9 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX
|
|||||||
WXLRESULT rc = 0;
|
WXLRESULT rc = 0;
|
||||||
bool processed = false;
|
bool processed = false;
|
||||||
|
|
||||||
#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
|
|
||||||
switch ( message )
|
switch ( message )
|
||||||
{
|
{
|
||||||
|
#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
|
||||||
case WM_ACTIVATE:
|
case WM_ACTIVATE:
|
||||||
{
|
{
|
||||||
SHACTIVATEINFO* info = (SHACTIVATEINFO*) m_activateInfo;
|
SHACTIVATEINFO* info = (SHACTIVATEINFO*) m_activateInfo;
|
||||||
@@ -355,8 +357,32 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX
|
|||||||
}
|
}
|
||||||
break;
|
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 )
|
if ( !processed )
|
||||||
rc = wxTopLevelWindowBase::MSWWindowProc(message, wParam, lParam);
|
rc = wxTopLevelWindowBase::MSWWindowProc(message, wParam, lParam);
|
||||||
@@ -578,6 +604,8 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent,
|
|||||||
|
|
||||||
wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
|
wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
|
||||||
{
|
{
|
||||||
|
delete m_menuSystem;
|
||||||
|
|
||||||
SendDestroyEvent();
|
SendDestroyEvent();
|
||||||
|
|
||||||
#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
|
#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)
|
bool wxTopLevelWindowMSW::SetTransparent(wxByte alpha)
|
||||||
|
Reference in New Issue
Block a user