- add a member to shlview to able to track the current context menu

- make the background menu use owner drawn items to show icon (icon not yet shown)
- let the shell item menu also accept owner drawn images
- this makes winrar shellextension appear however the language is _not_ correct in most cases and executing a command is at your own risk :)

svn path=/trunk/; revision=29808
This commit is contained in:
Johannes Anderwald 2007-10-23 02:00:30 +00:00
parent 4ce5c80551
commit 4da0e180ee
3 changed files with 192 additions and 25 deletions

View file

@ -109,6 +109,7 @@ typedef struct
LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */
UINT cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
POINT ptLastMousePos; /* Mouse position at last DragOver call */
IContextMenu2 *pCM;
} IShellViewImpl;
static const IShellViewVtbl svvt;
@ -948,7 +949,6 @@ static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL
BOOL fExplore = FALSE;
HWND hwndTree = 0;
LPCONTEXTMENU pContextMenu = NULL;
IContextMenu2 *pCM = NULL;
CMINVOKECOMMANDINFO cmi;
TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
@ -957,9 +957,9 @@ static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL
if( ShellView_GetSelections(This) )
{
IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
(REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
(REFIID)&IID_IContextMenu, NULL, (LPVOID *)&This->pCM);
if(pContextMenu)
if(This->pCM)
{
TRACE("-- pContextMenu\n");
hMenu = CreatePopupMenu();
@ -977,7 +977,7 @@ static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL
wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
/* let the ContextMenu merge its items in */
if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
if (SUCCEEDED(IContextMenu_QueryContextMenu( This->pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
{
if (This->FolderSettings.fFlags & FWF_DESKTOP)
SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
@ -1017,16 +1017,19 @@ static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL
DestroyMenu(hMenu);
}
}
if (pContextMenu)
IContextMenu_Release(pContextMenu);
if (This->pCM)
{
IContextMenu_Release(This->pCM);
This->pCM = NULL;
}
}
}
else /* background context menu */
{
hMenu = CreatePopupMenu();
pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
This->pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
IContextMenu2_QueryContextMenu(This->pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
DestroyMenu(hMenu);
@ -1037,9 +1040,10 @@ static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL
cmi.cbSize = sizeof(cmi);
cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
cmi.hwnd = This->hWndParent;
IContextMenu2_InvokeCommand(pCM, &cmi);
IContextMenu2_InvokeCommand(This->pCM, &cmi);
IContextMenu2_Release(pCM);
IContextMenu2_Release(This->pCM);
This->pCM = NULL;
}
}
@ -1582,6 +1586,26 @@ static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, L
}
return TRUE;
}
/**********************************************************
* ShellView_DoMeasureItem
*/
static LRESULT ShellView_DoCustomItem(IShellViewImpl * pThis, HWND hWnd, UINT uMsg, LPARAM lParam)
{
if (!pThis->pCM)
{
/* no menu */
ERR("no menu!!!\n");
return FALSE;
}
if (pThis->pCM->lpVtbl->HandleMenuMsg(pThis->pCM, uMsg, (WPARAM)hWnd, lParam) == S_OK)
return TRUE;
else
return FALSE;
}
/**********************************************************
* ShellView_WndProc
*/
@ -1616,6 +1640,9 @@ static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wPara
case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
return 0;
case WM_DRAWITEM:
case WM_MEASUREITEM:
return ShellView_DoCustomItem(pThis, hWnd, uMessage, lParam);
case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
break;
@ -1727,6 +1754,9 @@ static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
if(This->pAdvSink)
IAdviseSink_Release(This->pAdvSink);
if (This->pCM)
IContextMenu_Release(This->pCM);
HeapFree(GetProcessHeap(),0,This);
}
return refCount;

View file

@ -23,7 +23,7 @@
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
//#define YDEBUG
#define YDEBUG
#include "wine/debug.h"
#include "windef.h"
@ -36,6 +36,7 @@
#include "undocshell.h"
#include "shlwapi.h"
#include "stdio.h"
#include "winuser.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
@ -277,7 +278,6 @@ InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu, BgCmImpl * This)
}
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
@ -298,8 +298,8 @@ InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu, BgCmImpl * This)
InsertMenuItemW(hMenu, -1, TRUE, &mii);
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA; //MIIM_BITMAP;
mii.fType = MFT_STRING;
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
mii.fType = MFT_OWNERDRAW;
mii.fState = MFS_ENABLED;
pCurItem = s_SnHead;
@ -468,6 +468,74 @@ DoShellNewCmd(BgCmImpl * This, LPCMINVOKECOMMANDINFO lpcmi)
}
}
}
HRESULT
DoMeasureItem(BgCmImpl *This, HWND hWnd, MEASUREITEMSTRUCT * lpmis)
{
PSHELLNEW_ITEM pCurItem;
PSHELLNEW_ITEM pItem;
UINT i;
HDC hDC;
SIZE size;
TRACE("DoMeasureItem entered with id %x\n", lpmis->itemID);
pCurItem = s_SnHead;
i = This->iIdShellNewFirst;
pItem = NULL;
while(pCurItem)
{
if (i == lpmis->itemID)
{
pItem = pCurItem;
break;
}
pCurItem = pCurItem->Next;
i++;
}
if (!pItem)
return E_FAIL;
hDC = GetDC(hWnd);
GetTextExtentPoint32W(hDC, pCurItem->szDesc, strlenW(pCurItem->szDesc), &size);
lpmis->itemWidth = size.cx + 32;
lpmis->itemHeight = max(size.cy, 20);
ReleaseDC (hWnd, hDC);
return S_OK;
}
HRESULT
DoDrawItem(BgCmImpl *This, HWND hWnd, DRAWITEMSTRUCT * drawItem)
{
PSHELLNEW_ITEM pCurItem;
PSHELLNEW_ITEM pItem;
UINT i;
pCurItem = s_SnHead;
TRACE("DoDrawItem entered with id %x\n", drawItem->itemID);
i = This->iIdShellNewFirst;
pItem = NULL;
while(pCurItem)
{
if (i == drawItem->itemID)
{
pItem = pCurItem;
break;
}
pCurItem = pCurItem->Next;
i++;
}
if (!pItem)
return E_FAIL;
drawItem->rcItem.left += 20;
DrawTextW(drawItem->hDC, pCurItem->szDesc, wcslen(pCurItem->szDesc), &drawItem->rcItem, 0);
return S_OK;
}
/**************************************************************************
@ -870,9 +938,23 @@ static HRESULT WINAPI ISVBgCm_fnHandleMenuMsg(
WPARAM wParam,
LPARAM lParam)
{
BgCmImpl *This = (BgCmImpl *)iface;
BgCmImpl *This = (BgCmImpl *)iface;
DRAWITEMSTRUCT * lpids = (DRAWITEMSTRUCT*) lParam;
MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*) lParam;
FIXME("(%p)->(msg=%x wp=%lx lp=%lx)\n",This, uMsg, wParam, lParam);
TRACE("ISVBgCm_fnHandleMenuMsg (%p)->(msg=%x wp=%lx lp=%lx)\n",This, uMsg, wParam, lParam);
switch(uMsg)
{
case WM_MEASUREITEM:
if (lpmis->itemID >= This->iIdShellNewFirst && lpmis->itemID <= This->iIdShellNewLast)
return DoMeasureItem(This, (HWND)wParam, lpmis);
break;
case WM_DRAWITEM:
if (lpmis->itemID >= This->iIdShellNewFirst && lpmis->itemID <= This->iIdShellNewLast)
return DoDrawItem(This, (HWND)wParam, lpids);
break;
}
return E_NOTIMPL;
}

View file

@ -56,6 +56,8 @@ typedef struct
IContextMenu ** ecmenu;
UINT esize;
UINT ecount;
UINT iIdSHEFirst;
UINT iIdSHELast;
} ItemCmImpl;
UINT
@ -215,6 +217,50 @@ void WINAPI _InsertMenuItem (
InsertMenuItemA( hmenu, indexMenu, fByPosition, &mii);
}
HRESULT
DoCustomItemAction(ItemCmImpl *This, LPARAM lParam, UINT uMsg)
{
IContextMenu2 * cmenu;
IContextMenu * menu;
MEASUREITEMSTRUCT * lpmis = (MEASUREITEMSTRUCT *)lParam;
DRAWITEMSTRUCT * drawItem = (DRAWITEMSTRUCT *)lParam;
HRESULT hResult;
TRACE("DoCustomItemAction entered with uMsg %x lParam %p\n", uMsg, lParam);
if (uMsg == WM_MEASUREITEM)
{
menu = This->ecmenu[lpmis->itemID - This->iIdSHEFirst];
}
else if (uMsg == WM_DRAWITEM)
{
menu = This->ecmenu[drawItem->itemID - This->iIdSHEFirst];
}
else
{
ERR("unexpected message\n");
return E_FAIL;
}
if (!menu)
{
ERR("item is not valid\n");
return E_FAIL;
}
hResult = menu->lpVtbl->QueryInterface(menu, &IID_IContextMenu2, (void**)&cmenu);
if (hResult != S_OK)
{
ERR("failed to get IID_IContextMenu2 interface\n");
return hResult;
}
hResult = cmenu->lpVtbl->HandleMenuMsg(cmenu, uMsg, (WPARAM)0, lParam);
TRACE("returning hResult %x\n", hResult);
return hResult;
}
BOOL
SH_EnlargeContextMenuArray(ItemCmImpl *This, UINT newsize)
{
@ -253,7 +299,7 @@ SH_LoadContextMenuHandlers(ItemCmImpl *This, IDataObject * pDataObj, HMENU hMenu
HRESULT hResult;
UINT idCmdFirst = 0x5000;
UINT idCmdLast = 0xFFF0;
static const WCHAR szAny[] = { '*',0};
static WCHAR szAny[] = { '*',0};
SH_EnumerateDynamicContextHandlerForKey(szAny, This, pDataObj);
@ -283,17 +329,16 @@ SH_LoadContextMenuHandlers(ItemCmImpl *This, IDataObject * pDataObj, HMENU hMenu
}
TRACE("SH_LoadContextMenuHandlers num extensions %u\n", This->ecount);
This->iIdSHEFirst = idCmdFirst;
for (i = 0; i < This->ecount; i++)
{
cmenu = This->ecmenu[i];
TRACE("Invoking menu %p\n", cmenu);
hResult = cmenu->lpVtbl->QueryContextMenu(hMenu, indexMenu, idCmdFirst, idCmdLast, idCmdLast, CMF_NORMAL);
TRACE("result %x\n",hResult);
hResult = cmenu->lpVtbl->QueryContextMenu(cmenu, hMenu, indexMenu, idCmdFirst, idCmdLast, CMF_NORMAL);
idCmdFirst += (hResult & 0xFFFF);
}
This->iIdSHELast = idCmdFirst;
TRACE("SH_LoadContextMenuHandlers first %x last %x\n", This->iIdSHEFirst, This->iIdSHELast);
}
/**************************************************************************
@ -681,10 +726,20 @@ static HRESULT WINAPI ISvItemCm_fnHandleMenuMsg(
LPARAM lParam)
{
ItemCmImpl *This = (ItemCmImpl *)iface;
LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT) lParam;
TRACE("(%p)->(msg=%x wp=%lx lp=%lx)\n",This, uMsg, wParam, lParam);
return E_NOTIMPL;
switch(uMsg)
{
case WM_MEASUREITEM:
case WM_DRAWITEM:
if (lpmis->itemID >= This->iIdSHEFirst && lpmis->itemID <= This->iIdSHELast)
return DoCustomItemAction(This, lParam, uMsg);
break;
}
return E_NOTIMPL;
}
static const IContextMenu2Vtbl cmvt =