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:
 | 
			
		||||
 | 
			
		||||
- 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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user