// MenuItem.cpp : Implementation of CMenuItem
#include "stdafx.h"
#include "CtxTest.h"
#include "MenuItem.h"
#include <string>
#include <assert.h>
/////////////////////////////////////////////////////////////////////////////
// CMenuItem
HRESULT CMenuItem::InvokeCommand ( LPCMINVOKECOMMANDINFO pCmdInfo )
{
// If lpVerb really points to a std::string,
// ignore this function call and bail out.
if ( 0 != HIWORD( pCmdInfo->lpVerb ) ) { return E_INVALIDARG; }
// Get the command index - the only valid one is 0.
switch( LOWORD( pCmdInfo->lpVerb ) )
{
case 0:
{
MessageBox( pCmdInfo->hwnd, file.c_str(),
_T("Context Menu Test"), MB_ICONINFORMATION );
return S_OK;
break;
}
default:
assert( false );
break;
}
return E_INVALIDARG;
}
HRESULT CMenuItem::GetCommandString( UINT idCmd, UINT uFlags,
UINT* pwReserved, LPSTR pszName, UINT cchMax )
{
pwReserved; // Warning C4100 suppression
// Check idCmd, it must be 0 since we have only one menu item.
if ( 0 != idCmd ) { return E_INVALIDARG; }
// If Explorer is asking for a help std::string, copy our std::string
// into the supplied buffer.
if( uFlags & GCS_HELPTEXT )
{
if ( uFlags & GCS_UNICODE )
{
LPWSTR szText = L"Context Menu Test Description";
// We need to cast pszName to a Unicode std::string, and then use the
// Unicode std::string copy API.
lstrcpynW ( reinterpret_cast<LPWSTR>( pszName ), szText, cchMax );
}
else
{
LPSTR szText = "Context Menu Test Description";
// Use the ANSI std::string copy API to return the help std::string.
lstrcpynA ( pszName, szText, cchMax );
}
return S_OK;
}
return E_INVALIDARG;
}
HRESULT CMenuItem::QueryContextMenu( HMENU hmenu, UINT uMenuIndex,
UINT uidFirstCmd, UINT uidLastCmd, UINT uFlags )
{
uidFirstCmd; // Suppression Warning C4100
uidLastCmd; // Suppression Warning C4100
// If the flags include CMF_DEFAULTONLY then we shouldn't do anything.
if( uFlags & CMF_DEFAULTONLY )
{ return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 0 ); }
InsertMenu( hmenu, uMenuIndex, MF_BYPOSITION,
uidFirstCmd, _T("Context Menu Test") );
return MAKE_HRESULT( SEVERITY_SUCCESS, FACILITY_NULL, 1 );
}
STDMETHODIMP CMenuItem::Initialize( LPCITEMIDLIST pidlFolder,
LPDATAOBJECT pDataObj, HKEY hProgID )
{
pidlFolder; // Warning C4100 suppression
hProgID; // Warning C4100 suppression
FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
HDROP hDrop;
// Look for CF_HDROP data in the data object. If there
// is no such data, return an error back to Explorer.
if( FAILED( pDataObj->GetData ( &fmt, &stg ) ))
{ return E_INVALIDARG; }
// Get a pointer to the actual data.
hDrop = static_cast<HDROP>( GlobalLock ( stg.hGlobal ) );
// Make sure it worked.
if( NULL == hDrop )
{ return E_INVALIDARG; }
// Sanity check - make sure there is at least one filename.
UINT uNumFiles = DragQueryFile( hDrop, static_cast<UINT>(-1), NULL, 0 );
if( 0 == uNumFiles )
{
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return E_INVALIDARG;
}
HRESULT hr = S_OK;
// The author has encountered situations where
// MAX_PATH*2 was a bit too small...
TCHAR szFile[ MAX_PATH * 4 + 1 ];
DragQueryFile( static_cast<HDROP>( stg.hGlobal ),
0 /*first file*/, szFile, MAX_PATH * 4 );
file = szFile;
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return hr;
}