readviewmenuext.cpp

来自「WIndows mobile 5.0 pocket pc sdk sample 」· C++ 代码 · 共 612 行 · 第 1/2 页

CPP
612
字号
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

#define INITGUID
#include "common.h"
#include <initguid.h>
#include <mapidefs.h>
#include <mapiutil.h>
#undef INITGUID

// Label for the menu extension
const TCHAR cszReplyUsing[] = TEXT("Reply using Outlook E-mail");

// Global Count of references to this DLL - defined in Main.cpp
extern UINT g_cDLLRefCount;


MenuExtension::MenuExtension() : 
    m_cRef(1), 
    m_pSite(NULL),
    m_pSession(NULL),
    m_idc(0)
{
    g_cDLLRefCount++;
}

MenuExtension::~MenuExtension()
{    
    RELEASE_OBJ(m_pSite);
    RELEASE_OBJ(m_pSession);

    ASSERT(0 == m_cRef);
    g_cDLLRefCount--;
}

HRESULT MenuExtension::Initialize() 
{
    HRESULT hr = S_OK;

    if (!m_pSession)
    {
        // Logon to MAPI if m_pSession has not been opened
        hr = MAPILogonEx(0, NULL, NULL, 0, &m_pSession);
    }

    return hr;
}


///////////////////////////////////////////////////////////////////////////////
// QueryInterface - IUnknown interface Method
//
//  Returns a pointer to a specified interface on an object to which a client 
//  currently holds an interface pointer. This method must call IUnknown::AddRef 
//  on the pointer it returns.
//
STDMETHODIMP MenuExtension::QueryInterface(REFIID iid, LPVOID * ppv)
{   HRESULT hr = S_OK;

    *ppv = NULL;

    if(IID_IUnknown == iid)
    {
        *ppv = static_cast<IObjectWithSite*>(this);
    }        
    else if(IID_IObjectWithSite == iid)
    {
        *ppv = static_cast<IObjectWithSite*>(this);
    }
    else if(IID_IContextMenu == iid)
    {
        *ppv = static_cast<IContextMenu*>(this);
    }
    else
    {
        CHR(E_NOINTERFACE); 
    }
    
    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();

Error:
    return(hr);
}


///////////////////////////////////////////////////////////////////////////////
// AddRef - IUnknown interface Method
//
//  Increments the reference count for an interface on an object. It should be 
//  called for every new copy of a pointer to an interface on a specified object.
//
STDMETHODIMP_(ULONG) MenuExtension::AddRef() 
{
    return ::InterlockedIncrement(&m_cRef);
}


///////////////////////////////////////////////////////////////////////////////
// Release - IUnknown interface Method
//
//  Decrements the reference count for the calling interface on a object. If 
//  the reference count on the object falls to 0, the object is freed from 
//  memory.
//
STDMETHODIMP_(ULONG) MenuExtension::Release() 
{
    if(0 == ::InterlockedDecrement(&m_cRef)) 
    {
        delete this; 
        return(0);
    } 
    return(m_cRef);
}


///////////////////////////////////////////////////////////////////////////////
// SetSite - IObjectWithSite interface Method
//
//  Provides the site's IUnknown pointer to the object.
// 
//  This method is how the context menu extension gets a pointer to its context.
//  The "site" is a pointer to the object in the UI that the menu extension 
//  will be acting on.
//
STDMETHODIMP MenuExtension::SetSite(IUnknown* pSite)
{
    RELEASE_OBJ(m_pSite);

    if(pSite)
    {
        m_pSite = pSite;
        m_pSite->AddRef();
    }
    return(S_OK);
}

///////////////////////////////////////////////////////////////////////////////
// GetSite - IObjectWithSite interface Method
//
//  Implements the required interface method.
//  Retrieves the last site set with IObjectWithSite::SetSite. If there's no 
//  known site, the object returns a failure code.
// 
STDMETHODIMP MenuExtension::GetSite(REFIID riid, void** ppvSite)
{
    HRESULT hr = S_OK;
    if(m_pSite) 
    {
        hr = m_pSite->QueryInterface(riid, ppvSite);
        CHR(hr);       
    }
    else
    {    
        CHR(E_FAIL); 
    }
    
Error:
    return(hr);
}


///////////////////////////////////////////////////////////////////////////////
// InsertMenuItem
//      NOTE: in WinCE there is only InsertMenu
//
//  Simply insert the item in the menu
//
HRESULT MenuExtension::InsertMenuItem(HMENU hmenu, UINT indexMenu, UINT idCmd, LPCTSTR szText)
{
    HRESULT hr = S_OK;

    if(!::InsertMenu(hmenu, indexMenu, MF_BYPOSITION | MF_STRING, idCmd, szText))
    {
        hr = E_FAIL;
    }

    return hr;
}


///////////////////////////////////////////////////////////////////////////////
// QueryContextMenu - IContextMenu interface Method
//
//  Inserts the ReplyUsing item into the menu of the read view.
//  Properly enables the menu item based on the type of message being read.
// 
HRESULT STDMETHODCALLTYPE MenuExtension::QueryContextMenu(HMENU hmenu,
    UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
    HRESULT hr = S_OK;
    BOOL fEnableItem; 
    TCHAR szItemName[30];

    CBR(idCmdFirst <= idCmdLast);
    m_idc = idCmdFirst;

    // Get item text 
    hr = StringCchCopy(szItemName, ARRAYSIZE(szItemName), cszReplyUsing);
    CHR(hr);

    // Insert the item
    hr = InsertMenuItem(hmenu, indexMenu, m_idc, szItemName);
    CHR(hr);

    // Determine if this is a read view for an email account other than "Outlook E-mail"
    //  if it is not - then gray out this menu option
    fEnableItem = IsReplyUsingEnabled();
    ::EnableMenuItem(hmenu, m_idc, fEnableItem ? MF_ENABLED : MF_GRAYED);   

Error:
    return(hr);
}


///////////////////////////////////////////////////////////////////////////////
// InvokeCommand - IContextMenu interface Method
//
//  Called when the user actions upon an item implemented by a MenuExtension.
//  If the lpVerb matches the name of our menu extension, take the appropriate action.
// 
HRESULT STDMETHODCALLTYPE MenuExtension::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
    HRESULT hr = S_OK;

    if (lpici->lpVerb)
    {
        if (!_tcscmp(cszReplyUsing, (LPCTSTR)lpici->lpVerb))
        {
            hr = ReplyUsing();
            CHR(hr);                    
        }
        else
        {
            CHR(E_INVALIDARG);
        }
    }    

Error:
    return hr;

}


///////////////////////////////////////////////////////////////////////////////
// GetCommandString - IContextMenu interface Method
//
//  Returns the only command string associated with this MenuExtension
// 
HRESULT STDMETHODCALLTYPE MenuExtension::GetCommandString(UINT_PTR idCmd,
        UINT uType, UINT* pwReserved, LPSTR pszBad, UINT cchMax)
{
    return StringCchCopy((TCHAR *)pszBad, cchMax, cszReplyUsing);
}



///////////////////////////////////////////////////////////////////////////////
//  Create (Static method)
//
//  When the applications's menu is rendered, it checks to see if there are any 
//  menu extensions registered.  If so, DllGetClassObject (Main.cpp) will be 
//  called for each extension.  DllGetClassObject instantiates MyClassFactory 
//  (ClassFactory.cpp) which will call MyClassFactory::CreateInstance which 
//  will in turn call this method.
//
//  Creates and then initializes the MenuExtension.
// 
HRESULT MenuExtension::Create(IObjectWithSite** ppNew)
{
    HRESULT hr = S_OK;
    MenuExtension* pte = NULL;

    pte = new MenuExtension();
    CPR(pte);

    hr = pte->Initialize();
    CHR(hr);

    *ppNew = pte;
    pte = NULL;

Error:    
    delete pte;
    return hr;    
}


///////////////////////////////////////////////////////////////////////////////
// IsReplyUsingEnabled
//
//  Returns TRUE if the current context menu is in a read view for a message
//  whose service is neither SMS nor ActiveSync.
//
BOOL MenuExtension::IsReplyUsingEnabled()
{
    HRESULT hr = S_OK;
    BOOL fIsEnabled = FALSE;

⌨️ 快捷键说明

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