📄 inboxmenuext.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
#define INITGUID
#include "common.h"
#include <initguid.h>
#include <pimstore.h>
#include <mapiutil.h>
#undef INITGUID
// Global Count of references to this DLL - defined in Main.cpp
extern UINT g_cDLLRefCount;
// These are the texts to be used on the new menu items this menu extension
// will add. In production these would likely be pulled from a resource
// file which could be localized
const TCHAR cszAddSender[] = TEXT("Add Sender to Contacts");
const TCHAR cszMarkAll[] = TEXT("Mark All as Read");
const TCHAR cszDeleteAll[] = TEXT("Delete All");
///////////////////////////////////////////////////////////////////////////////
// GetPOOM
//
// Helper function to CoCreate the IPOutloookApp2 Application
//
// NOTE: POutlook.exe will be running (if it is not already running) after
// this function is called
//
// Arguments:
// [OUT] IPOutlookApp2 **ppPOOM - an unitialized pointer to pointer to the
// Pocket Outlook application object model. (POOM)
//
// Return Values:
// HRESULT - returns S_OK / E_FAIL.
//
//
HRESULT GetPOOM(IPOutlookApp2 **ppPOOM)
{
HRESULT hr = E_FAIL;
IUnknown * pUnknown = NULL;
IPOutlookApp2 * polApp = NULL;
hr = ::CoCreateInstance(CLSID_Application,
NULL, CLSCTX_INPROC_SERVER,
IID_IPOutlookApp2,
(void **)&polApp);
CHR(hr);
CPR(polApp);
hr = polApp->Logon(NULL);
CHR(hr);
*ppPOOM = polApp;
Error:
RELEASE_OBJ(pUnknown);
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// MenuExtension::MenuExtension - Constructor
//
// Initializes member variables and increments the g_cDLLRefCount
//
// Arguments:
// [IN] ExtenstionType extensionType - a value from the enum ExtensionType
// which indicates which type of menu extension to instantiate
//
// Return Values:
// MenuExtension object
//
MenuExtension::MenuExtension(ExtensionType extensionType) :
m_cRef(1),
m_pSite(NULL),
m_pSession(NULL),
m_idc1(0),
m_idc2(0)
{
g_cDLLRefCount++;
m_ExtensionType = extensionType;
}
///////////////////////////////////////////////////////////////////////////////
// MenuExtension::MenuExtension - DeConstructor
//
// Cleans up and de-crements the g_cDLLRefCount
//
// Arguments:
// None
//
// Return Values:
// None
//
MenuExtension::~MenuExtension()
{
RELEASE_OBJ(m_pSite);
ASSERT(0 == m_cRef);
g_cDLLRefCount--;
}
///////////////////////////////////////////////////////////////////////////////
// Initialize
//
// This method should be called after calling the constructor.
//
// Arguments:
// None
//
// Return Values:
// HRESULT - currently always returns S_OK
//
HRESULT MenuExtension::Initialize()
{
// If you have logic in your constructor which MAY cause the constructor
// to fail - you should pull it from the constructor and put it in this
// method, reducing the likelihood of a constructor failure
return(S_OK);
}
///////////////////////////////////////////////////////////////////////////////
// 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.
//
// Arguments:
// [IN] REFIID iid - the interface ID we are testing for
// [OUT] LPVOID *ppv - a pointer the object
//
// Return Values:
// HRESULT - S_OK on success, E_NOINTERFACE if the inteface ID passed in
// using iid is not supported by this object
//
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.
//
// Arguments:
// none
//
// Return Values:
// ULONG - the current reference count to this 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.
//
// Arguments:
// none
//
// Return Values:
// ULONG - the current reference count to this object
//
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, i.e. the menu it will be extending
//
// Arguments:
// [IN] IUnknown* pSite - a pointer to the object in the Application's UI
//
// Return Values:
// HRESULT - always will be S_OK
//
STDMETHODIMP MenuExtension::SetSite(IUnknown* pSite)
{
RELEASE_OBJ(m_pSite);
if(pSite)
{
m_pSite = pSite;
m_pSite->AddRef();
}
return(S_OK);
}
///////////////////////////////////////////////////////////////////////////////
// GetSite - IObjectWithSite interface Method
//
// Retrieves the last site set with SetSite. If there's no known site, the
// this returns a failure code.
//
// Arguments:
// [IN] REFIID iid - the interface ID we are testing the site to see if it
// handles
// [OUT] void** ppvSite - a pointer to the object will be returned
// if the QI is succesful
//
// Return Values:
// HRESULT - S_OK on success else E_FAIL or other HRESULT returned by the
// site's QI method (potentially E_NOINTERFACE)
//
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
//
// Arguments:
// [IN] HMENU hmenu - a handle the menu to insert into
// [IN] UINT indexMenu - the position the item will be inserted after
// [IN] UINT idCmd - the ID of the new item
// [IN] LPCTSTR szText - the menu text of the new item
//
// Return Values:
// HRESULT - S_OK on success else E_FAIL
//
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
//
// Adds the extra menu items to the context menu. This method is called when
// the menu which our menu extension is extended is being created
//
// Arguments:
// [IN] HMENU hmenu - a handle the menu to insert into
// [IN] UINT indexMenu - the position the item will be inserted after
// [IN] UINT idCmdFirst - the lowest possible ID for a new command to use
// [IN] UINT idCmdLast - the highest possible ID for a new command to use
// [IN] LPCTSTR szText - the menu text of the new item
// [IN] UINT uFlags - a set of flags indicating what type of insertion and
// extension is allowed. Please see the QueryContextMenu topic in the
// the SDK documentation for a complete list of these flags
// NOTE: The inbox application will only ever send CMF_NORMAL
//
//
// Return Values:
// HRESULT - S_OK on success else E_FAIL
//
HRESULT STDMETHODCALLTYPE MenuExtension::QueryContextMenu(HMENU hmenu,
UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
HRESULT hr = S_OK;
m_idc1 = idCmdFirst;
m_idc2 = idCmdFirst + 1;
CBR(m_idc2 <= idCmdLast);
BOOL fEnableItem;
TCHAR szItemName[30];
switch(m_ExtensionType)
{
case Context:
// Get item text
hr = GetCommandStringHelper(m_idc1, szItemName, ARRAYSIZE(szItemName));
CHR(hr);
// Insert the item
hr = InsertMenuItem(hmenu, indexMenu, m_idc1, szItemName);
CHR(hr);
// Determine if we are in an appropriate folder and
// have only a SINGLE item selected
// if NOT - then gray out this menu option
fEnableItem = EnableAddSenderToContacts();
::EnableMenuItem(hmenu, m_idc1, fEnableItem ? MF_ENABLED : MF_GRAYED);
break;
case Softkey:
// Get item text
hr = GetCommandStringHelper(m_idc1, szItemName, ARRAYSIZE(szItemName));
CHR(hr);
// Insert the item
hr = InsertMenuItem(hmenu, indexMenu, m_idc1, szItemName);
CHR(hr);
// Get item text
hr = GetCommandStringHelper(m_idc2, szItemName, ARRAYSIZE(szItemName));
CHR(hr);
// Insert the item
hr = InsertMenuItem(hmenu, indexMenu, m_idc2, szItemName);
CHR(hr);
// Determine if there are items in the ListView
// if there are no items - then gray out these menu options
fEnableItem = AreThereMessagesInFolder();
::EnableMenuItem(hmenu, m_idc1, fEnableItem ? MF_ENABLED : MF_GRAYED);
::EnableMenuItem(hmenu, m_idc2, fEnableItem ? MF_ENABLED : MF_GRAYED);
break;
}
Error:
return(hr);
}
///////////////////////////////////////////////////////////////////////////////
// InvokeCommand - IContextMenu interface Method
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -