Author: janderwald
Date: Tue Oct 23 06:00:30 2007
New Revision: 29808
URL:
http://svn.reactos.org/svn/reactos?rev=29808&view=rev
Log:
- 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 :)
Modified:
trunk/reactos/dll/win32/shell32/shlview.c
trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c
trunk/reactos/dll/win32/shell32/shv_item_cmenu.c
Modified: trunk/reactos/dll/win32/shell32/shlview.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlview.…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shlview.c (original)
+++ trunk/reactos/dll/win32/shell32/shlview.c Tue Oct 23 06:00:30 2007
@@ -109,6 +109,7 @@
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 @@
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 @@
if( ShellView_GetSelections(This) )
{
IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl,
(LPCITEMIDLIST*)This->apidl,
- (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
-
- if(pContextMenu)
+ (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&This->pCM);
+
+ if(This->pCM)
{
TRACE("-- pContextMenu\n");
hMenu = CreatePopupMenu();
@@ -977,7 +977,7 @@
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 @@
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 @@
cmi.cbSize = sizeof(cmi);
cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
cmi.hwnd = This->hWndParent;
- IContextMenu2_InvokeCommand(pCM, &cmi);
-
- IContextMenu2_Release(pCM);
+ IContextMenu2_InvokeCommand(This->pCM, &cmi);
+
+ IContextMenu2_Release(This->pCM);
+ This->pCM = NULL;
}
}
@@ -1582,6 +1586,26 @@
}
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 @@
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;
@@ -1726,6 +1753,9 @@
if(This->pAdvSink)
IAdviseSink_Release(This->pAdvSink);
+
+ if (This->pCM)
+ IContextMenu_Release(This->pCM);
HeapFree(GetProcessHeap(),0,This);
}
Modified: trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shv_bg_c…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c (original)
+++ trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c Tue Oct 23 06:00:30 2007
@@ -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 @@
}
-
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
@@ -298,8 +298,8 @@
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;
@@ -467,6 +467,74 @@
break;
}
}
+}
+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 @@
WPARAM wParam,
LPARAM lParam)
{
- BgCmImpl *This = (BgCmImpl *)iface;
-
- FIXME("(%p)->(msg=%x wp=%lx lp=%lx)\n",This, uMsg, wParam, lParam);
+ BgCmImpl *This = (BgCmImpl *)iface;
+ DRAWITEMSTRUCT * lpids = (DRAWITEMSTRUCT*) lParam;
+ MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*) 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;
}
Modified: trunk/reactos/dll/win32/shell32/shv_item_cmenu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shv_item…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shv_item_cmenu.c (original)
+++ trunk/reactos/dll/win32/shell32/shv_item_cmenu.c Tue Oct 23 06:00:30 2007
@@ -56,6 +56,8 @@
IContextMenu ** ecmenu;
UINT esize;
UINT ecount;
+ UINT iIdSHEFirst;
+ UINT iIdSHELast;
} ItemCmImpl;
UINT
@@ -215,6 +217,50 @@
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 @@
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 @@
}
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 @@
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 =