mirror of
https://github.com/reactos/reactos.git
synced 2024-10-15 13:45:58 +00:00
- 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:
parent
4ce5c80551
commit
4da0e180ee
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 =
|
||||
|
|
Loading…
Reference in a new issue