MENU.CPP

//******************************************************************************************* 
//
// Filename : Menu.cpp
//
//Implementations for CCabItemMenu methods
//
// Copyright 1994 - 1998 Microsoft Corporation. All rights reserved
//
//*******************************************************************************************

#include "pch.h"

#include "thisdll.h"

#include "resource.h"

#include "folder.h"
#include "menu.h"

#include "cabitms.h"

CCabItemMenu::CCabItemMenu(HWND hwndOwner, CCabFolder*pcf, LPCABITEM *apit, UINT cpit)
: m_lSel(8)
{
m_hwndOwner = hwndOwner;
m_pcfHere = pcf;
pcf->AddRef();

// No need to check return value here; check in QueryInterface
m_lSel.AddItems(apit, cpit);
}

CCabItemMenu::~CCabItemMenu()
{
m_pcfHere->Release();
}

// *** IUnknown methods ***
STDMETHODIMP CCabItemMenu::QueryInterface(
REFIID riid,
LPVOID FAR* ppvObj)
{
*ppvObj = NULL;

if (m_lSel.GetState() == CCabItemList::State_OutOfMem)
{
return(E_OUTOFMEMORY);
}

LPUNKNOWN pObj;

if (riid == IID_IUnknown)
{
pObj = (LPUNKNOWN)(IUnknown*)((IContextMenu*)this);
// The (IShellFolder*) ^^^ up there is to disambiguate :) the reference
}
else if (riid == IID_IContextMenu)
{
pObj = (LPUNKNOWN)(IContextMenu*)this;
}
else
{
return(E_NOINTERFACE);
}

pObj->AddRef();
*ppvObj = pObj;

return(NOERROR);
}


STDMETHODIMP_(ULONG) CCabItemMenu::AddRef(void)
{
return(m_cRef.AddRef());
}


STDMETHODIMP_(ULONG) CCabItemMenu::Release(void)
{
if (!m_cRef.Release())
{
delete this;
return(0);
}

return(m_cRef.GetRef());
}


// *** IContextMenu methods ***
STDMETHODIMP CCabItemMenu::QueryContextMenu(
HMENU hmenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
HMENU hmMerge = LoadPopupMenu(MENU_ITEMCONTEXT, 0);

if (!hmMerge)
{
return(E_OUTOFMEMORY);
}

UINT idMax = Cab_MergeMenus(hmenu, hmMerge, indexMenu, idCmdFirst, idCmdLast,
MM_ADDSEPARATOR);

DestroyMenu(hmMerge);

SetMenuDefaultItem(hmenu, IDC_ITEM_EXTRACT+idCmdFirst, FALSE);

return(ResultFromShort(idMax - idCmdFirst));
}

STDMETHODIMP CCabItemMenu::InvokeCommand(
LPCMINVOKECOMMANDINFO lpici)
{
if (HIWORD(lpici->lpVerb))
{
// Deal with string commands
return(E_INVALIDARG);
}

switch ((UINT)LOWORD((DWORD)lpici->lpVerb))
{
case IDC_ITEM_EXTRACT:
{
char szHere[MAX_PATH];
if (!m_pcfHere->GetPath(szHere))
{
return(E_UNEXPECTED);
}

CCabExtract ceHere(szHere);

ceHere.ExtractItems(m_hwndOwner, NULL, ShouldExtract, (LPARAM)this);

break;
}

default:
return(E_INVALIDARG);
}

return(NOERROR);
}

STDMETHODIMP CCabItemMenu::GetCommandString(
UINT idCmd,
UINT uType,
UINT * pwReserved,
LPSTR pszName,
UINT cchMax)
{
return(E_NOTIMPL);
}


HGLOBAL * CALLBACK CCabItemMenu::ShouldExtract(LPCSTR pszFile, DWORD dwSize, UINT date,
UINT time, UINT attribs, LPARAM lParam)
{
CCabItemMenu *pThis = (CCabItemMenu*)lParam;

if (pThis->m_lSel.IsInList(pszFile, dwSize, date, time, attribs))
{
return(EXTRACT_TRUE);
}

// Copy nothing for now
return(EXTRACT_FALSE);
}


HMENU CCabItemMenu::LoadPopupMenu(UINT id, UINT uSubMenu)
{
HMENU hmParent = LoadMenu(g_ThisDll.GetInstance(), MAKEINTRESOURCE(id));
if (!hmParent)
{
return(NULL);
}

HMENU hmPopup = GetSubMenu(hmParent, 0);
RemoveMenu(hmParent, uSubMenu, MF_BYPOSITION);
DestroyMenu(hmParent);

return(hmPopup);
}