⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 taskbar.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
// Name:        src/mac/carbon/taskbar.cpp
// Purpose:     wxTaskBarIcon
// Author:      Ryan Norton
// Modified by:
// Created:     09/25/2004
// RCS-ID:      $Id: taskbar.cpp,v 1.33 2006/05/21 21:45:30 ABX Exp $
// Copyright:   (c) 2004 Ryan Norton
// Licence:     wxWindows licence
///////////////////////////////////////////////////////////////////////////////

#include "wx/wxprec.h"

#ifdef wxHAS_TASK_BAR_ICON

#include "wx/taskbar.h"

#ifndef WX_PRECOMP
    #include "wx/dcmemory.h"
    #include "wx/menu.h"
    #include "wx/toplevel.h"
    #include "wx/icon.h"
#endif

#include "wx/mac/private.h"

class wxTaskBarIconImpl
{
public:
    wxTaskBarIconImpl(wxTaskBarIcon* parent);
    virtual ~wxTaskBarIconImpl();

    virtual bool IsIconInstalled() const = 0;
    virtual bool SetIcon(const wxIcon& icon, const wxString& tooltip) = 0;
    virtual bool RemoveIcon() = 0;
    virtual bool PopupMenu(wxMenu *menu) = 0;

    wxMenu * CreatePopupMenu()
    { return m_parent->CreatePopupMenu(); }

    wxTaskBarIcon *m_parent;
    class wxTaskBarIconWindow *m_menuEventWindow;

    DECLARE_NO_COPY_CLASS(wxTaskBarIconImpl)
};

//-----------------------------------------------------------------------------
//
//  wxTaskBarIconWindow
//
//  Event handler for menus
//  NB: Since wxWindows in Mac HAVE to have parents we need this to be
//  a top level window...
//-----------------------------------------------------------------------------

class wxTaskBarIconWindow : public wxTopLevelWindow
{
public:
    wxTaskBarIconWindow(wxTaskBarIconImpl *impl)
        : wxTopLevelWindow(NULL, wxID_ANY, wxEmptyString), m_impl(impl)
    {
        Connect(
            -1, wxEVT_COMMAND_MENU_SELECTED,
            wxCommandEventHandler(wxTaskBarIconWindow::OnMenuEvent) );
    }

    void OnMenuEvent(wxCommandEvent& event)
    {
        m_impl->m_parent->ProcessEvent(event);
    }

private:
    wxTaskBarIconImpl *m_impl;
};

class wxDockTaskBarIcon : public wxTaskBarIconImpl
{
public:
    wxDockTaskBarIcon(wxTaskBarIcon* parent);
    virtual ~wxDockTaskBarIcon();

    virtual bool IsIconInstalled() const;
    virtual bool SetIcon(const wxIcon& icon, const wxString& tooltip);
    virtual bool RemoveIcon();
    virtual bool PopupMenu(wxMenu *menu);

    wxMenu* DoCreatePopupMenu();

    EventHandlerRef     m_eventHandlerRef;
    EventHandlerUPP     m_eventupp;
    wxWindow           *m_eventWindow;
    wxMenu             *m_pMenu;
    MenuRef             m_theLastMenu;
    bool                m_iconAdded;
};

// Forward declarations for utility functions for dock implementation
pascal OSStatus wxDockEventHandler(
    EventHandlerCallRef inHandlerCallRef,
    EventRef inEvent, void* pData );
wxMenu * wxDeepCopyMenu( wxMenu *menu );


//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//  wxTaskBarIconImpl
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

wxTaskBarIconImpl::wxTaskBarIconImpl(wxTaskBarIcon* parent)
    : m_parent(parent), m_menuEventWindow(new wxTaskBarIconWindow(this))
{
}

wxTaskBarIconImpl::~wxTaskBarIconImpl()
{
    delete m_menuEventWindow;
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//  wxDockTaskBarIcon
//
//  OS X Dock implementation of wxTaskBarIcon using Carbon
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//-----------------------------------------------------------------------------
// wxDockEventHandler
//
// This is the global Mac/Carbon event handler for the dock.
// We need this for two reasons:
// 1) To handle wxTaskBarIcon menu events (see below for why)
// 2) To handle events from the dock when it requests a menu
//-----------------------------------------------------------------------------
pascal OSStatus wxDockEventHandler( EventHandlerCallRef inHandlerCallRef,
                                    EventRef inEvent, void *pData )
{
    // Get the parameters we want from the event
    wxDockTaskBarIcon* pTB = (wxDockTaskBarIcon*) pData;
    const UInt32 eventClass = GetEventClass(inEvent);
    const UInt32 eventKind = GetEventKind(inEvent);

    // Handle wxTaskBar menu events (note that this is a global event handler
    // so it will actually get called by all commands/menus)
    if ((eventClass == kEventClassCommand) && (eventKind == kEventCommandProcess))
    {
        // if we have no taskbar menu quickly pass it back to wxApp
        if (pTB->m_pMenu == NULL)
            return eventNotHandledErr;

        // This is the real reason why we need this. Normally menus
        // get handled in wxMacAppEventHandler
        //
        // pascal OSStatus wxMacAppEventHandler(EventHandlerCallRef handler,
        //                                      EventRef event, void *data)
        //
        // However, in the case of a taskbar menu call
        // command.menu.menuRef IS NULL!
        // Which causes the wxApp handler just to skip it.
        MenuRef taskbarMenuRef = MAC_WXHMENU(pTB->m_pMenu->GetHMenu());
        OSStatus err;

        // get the HICommand from the event
        HICommand command;
        err = GetEventParameter(
            inEvent, kEventParamDirectObject,
            typeHICommand, NULL,
            sizeof(HICommand), NULL, &command );
        if (err == noErr)
        {
            // Obtain the REAL menuRef and the menuItemIndex in the real menuRef
            //
            // NOTE: menuRef is generally used here for submenus, as
            // GetMenuItemRefCon could give an incorrect wxMenuItem if we pass
            // just the top level wxTaskBar menu
            MenuItemIndex menuItemIndex;
            MenuRef menuRef;

            err = GetIndMenuItemWithCommandID(
                taskbarMenuRef,
                command.commandID,
                1, &menuRef, &menuItemIndex );
            if (err == noErr)
            {
                MenuCommand id = command.commandID;
                wxMenuItem *item = NULL;

                if (id != 0) // get the wxMenuItem reference from the MenuRef
                    GetMenuItemRefCon( menuRef, menuItemIndex, (UInt32*) &item );

                if (item)
                {
                    // Handle items that are checkable
                    // FIXME: Doesn't work (at least on 10.2)!
                    if (item->IsCheckable())
                        item->Check( !item->IsChecked() );

                    // send the wxEvent to the wxMenu
                    item->GetMenu()->SendEvent( id, item->IsCheckable() ? item->IsChecked() : -1 );

                    // successfully handled the event
                    err = noErr;
                }
            }
        } //end if noErr on getting HICommand from event

        // return whether we handled the event or not
        return err;
    }

    // We better have a kEventClassApplication/kEventAppGetDockTileMenu combo here,
    // otherwise something is truly funky
    wxASSERT(eventClass == kEventClassApplication &&
             eventKind == kEventAppGetDockTileMenu);

    // process the right click events
    // NB: This may result in double or even triple-creation of the menus
    // We need to do this for 2.4 compat, however
    wxTaskBarIconEvent downevt(wxEVT_TASKBAR_RIGHT_DOWN, NULL);
    pTB->m_parent->ProcessEvent(downevt);

    wxTaskBarIconEvent upevt(wxEVT_TASKBAR_RIGHT_UP, NULL);
    pTB->m_parent->ProcessEvent(upevt);

    // create popup menu
    wxMenu* menu = pTB->DoCreatePopupMenu();

    OSStatus err = eventNotHandledErr;

    if (menu != NULL)
    {
        // note to self - a MenuRef *is* a MenuHandle
        MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu());

        // When SetEventParameter is called it will decrement
        // the reference count of the menu - we need to make
        // sure it stays around in the wxMenu class here
        RetainMenu(hMenu);

        // set the actual dock menu
        err = SetEventParameter(
            inEvent, kEventParamMenuRef,
            typeMenuRef, sizeof(MenuRef), &hMenu );
        verify_noerr( err );
    }

    return err;
}

//-----------------------------------------------------------------------------
// wxDeepCopyMenu
//
// Performs a top-to-bottom copy of the input menu and all of its
// submenus.
//
// This is mostly needed for 2.4 compatability. However wxPython and others
// still use this way of setting the taskbarmenu.
//-----------------------------------------------------------------------------
wxMenu * wxDeepCopyMenu( wxMenu *menu )
{
    if (menu == NULL)
        return NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -