generic support for owner drawn context menus
Modified: trunk/reactos/subsys/system/explorer/desktop/desktop.cpp
Modified: trunk/reactos/subsys/system/explorer/desktop/desktop.h
Modified: trunk/reactos/subsys/system/explorer/doc/TODO.txt
Modified: trunk/reactos/subsys/system/explorer/shell/entries.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/entries.h
Modified: trunk/reactos/subsys/system/explorer/shell/filechild.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/filechild.h
Modified: trunk/reactos/subsys/system/explorer/shell/mainframe.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/mainframe.h
Modified: trunk/reactos/subsys/system/explorer/shell/pane.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/shellbrowser.h
Modified: trunk/reactos/subsys/system/explorer/shell/shellfs.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/shellfs.h
Modified: trunk/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp
Modified: trunk/reactos/subsys/system/explorer/taskbar/quicklaunch.h
Modified: trunk/reactos/subsys/system/explorer/taskbar/startmenu.cpp
Modified: trunk/reactos/subsys/system/explorer/taskbar/startmenu.h
Modified: trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp
Modified: trunk/reactos/subsys/system/explorer/utility/shellclasses.h

Modified: trunk/reactos/subsys/system/explorer/desktop/desktop.cpp
--- trunk/reactos/subsys/system/explorer/desktop/desktop.cpp	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/desktop/desktop.cpp	2005-02-06 13:02:48 UTC (rev 13437)
@@ -473,11 +473,6 @@
  :	super(hwnd),
 	_pShellView(pShellView)
 {
-	_pctxmenu2 = NULL;
-#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
-	_pctxmenu3 = NULL;
-#endif
-
 	_hwndListView = ::GetNextWindow(hwnd, GW_CHILD);
 
 	SetWindowStyle(_hwndListView, GetWindowStyle(_hwndListView)&~LVS_ALIGNMASK);//|LVS_ALIGNTOP|LVS_AUTOARRANGE);
@@ -531,7 +526,7 @@
 {
 	switch(nmsg) {
 	  case WM_CONTEXTMENU:
-		if (!DoContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)))
+		if (!DoContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam), _cm_ifs))
 			DoDesktopContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam));
 		break;
 
@@ -546,36 +541,6 @@
 	  case PM_DISPLAY_VERSION:
 		return SendMessage(_hwndListView, nmsg, wparam, lparam);
 
-#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
-	  case WM_MENUCHAR:	// only supported by IContextMenu3
-	   if (_pctxmenu3) {
-		   LRESULT lResult = 0;
-
-		   _pctxmenu3->HandleMenuMsg2(nmsg, wparam, lparam, &lResult);
-
-		   return lResult;
-	   }
-	   break;
-#endif
-
-	  case WM_DRAWITEM:
-	  case WM_MEASUREITEM:
-		if (wparam)
-		  break; // If wParam != 0 then the message is not menu-related.
-
-		// fall through
-
-	  case WM_INITMENUPOPUP:
-#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
-		if (_pctxmenu3)
-		   _pctxmenu3->HandleMenuMsg(nmsg, wparam, lparam);
-		else
-#endif
-		if (_pctxmenu2)
-		   _pctxmenu2->HandleMenuMsg(nmsg, wparam, lparam);
-
-		return nmsg==WM_INITMENUPOPUP? 0: TRUE;	// Inform caller that we handled WM_INITPOPUPMENU by ourself.
-
 	  default:
 		return super::WndProc(nmsg, wparam, lparam);
 	}
@@ -593,7 +558,7 @@
 	return super::Notify(id, pnmh);
 }
 
-bool DesktopShellView::DoContextMenu(int x, int y)
+bool DesktopShellView::DoContextMenu(int x, int y, CtxMenuInterfaces& cm_ifs)
 {
 	IDataObject* selection;
 
@@ -623,7 +588,7 @@
 	for(int i=pida->cidl; i>0; --i)
 		apidl[i-1] = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[i]);
 
-	hr = ShellFolderContextMenu(ShellFolder(parent_pidl), _hwnd, pida->cidl, apidl, x, y);
+	hr = ShellFolderContextMenu(ShellFolder(parent_pidl), _hwnd, pida->cidl, apidl, x, y, cm_ifs);
 
 	selection->Release();
 
@@ -635,28 +600,12 @@
 HRESULT DesktopShellView::DoDesktopContextMenu(int x, int y)
 {
 	IContextMenu* pcm1;
-	IContextMenu* pcm;
 
 	HRESULT hr = DesktopFolder()->GetUIObjectOf(_hwnd, 0, NULL, IID_IContextMenu, NULL, (LPVOID*)&pcm1);
 
 	if (SUCCEEDED(hr)) {
-		 // Get the higher version context menu interfaces.
-		_pctxmenu2 = NULL;
-#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
-		_pctxmenu3 = NULL;
+		IContextMenu* pcm = _cm_ifs.query_interfaces(pcm1);
 
-		if (pcm1->QueryInterface(IID_IContextMenu3, (void**)&pcm) == NOERROR)
-			_pctxmenu3 = (LPCONTEXTMENU3)pcm;
-		else
-#endif
-		if (pcm1->QueryInterface (IID_IContextMenu2, (void**)&pcm) == NOERROR)
-			_pctxmenu2 = (LPCONTEXTMENU2)pcm;
-
-		if (pcm)
-			pcm1->Release();
-		else
-			pcm = pcm1;
-
 		HMENU hmenu = CreatePopupMenu();
 
 		if (hmenu) {
@@ -668,10 +617,7 @@
 
 				UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, _hwnd, NULL);
 
-				_pctxmenu2 = NULL;
-#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
-				_pctxmenu3 = NULL;
-#endif
+				_cm_ifs.reset();
 
 				if (idCmd == FCIDM_SHVIEWLAST-1) {
 					explorer_about(_hwnd);

Modified: trunk/reactos/subsys/system/explorer/desktop/desktop.h
--- trunk/reactos/subsys/system/explorer/desktop/desktop.h	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/desktop/desktop.h	2005-02-06 13:02:48 UTC (rev 13437)
@@ -165,9 +165,9 @@
 
 
  /// subclassed ShellView window
-struct DesktopShellView : public SubclassedWindow
+struct DesktopShellView : public ExtContextMenuHandlerT<SubclassedWindow>
 {
-	typedef SubclassedWindow super;
+	typedef ExtContextMenuHandlerT<SubclassedWindow> super;
 
 	DesktopShellView(HWND hwnd, IShellView* pShellView);
 
@@ -180,16 +180,11 @@
 	int		Command(int id, int code);
 	int		Notify(int id, NMHDR* pnmh);
 
-	bool	DoContextMenu(int x, int y);
+	bool	DoContextMenu(int x, int y, CtxMenuInterfaces& cm_ifs);
 	HRESULT DoDesktopContextMenu(int x, int y);
 	void	PositionIcons(int dir=1);
 
 	DesktopDropTarget* _pDropTarget;
 	HWND	_hwndListView;
 	int		_icon_algo;
-
-	IContextMenu2*	_pctxmenu2;
-#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
-	IContextMenu3*	_pctxmenu3;
-#endif
 };

Modified: trunk/reactos/subsys/system/explorer/doc/TODO.txt
--- trunk/reactos/subsys/system/explorer/doc/TODO.txt	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/doc/TODO.txt	2005-02-06 13:02:48 UTC (rev 13437)
@@ -24,4 +24,7 @@
 - hide desktop bar when showing full screen applications
 - new start menu entry "Filemanager" close to "Explore" -> display C: and D: drive in MDI window
 - Startmenu: You can open the start menu by pressing Win-key, but can't close with another hit of Win-key.
+- Export von Bookmarks f³r IE (+ Mozilla)
 
+- Search Programs -> performance monitor.msv -> Abort
+

Modified: trunk/reactos/subsys/system/explorer/shell/entries.cpp
--- trunk/reactos/subsys/system/explorer/shell/entries.cpp	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/shell/entries.cpp	2005-02-06 13:02:48 UTC (rev 13437)
@@ -401,7 +401,7 @@
 }
 
 
-HRESULT Entry::do_context_menu(HWND hwnd, const POINT& pos)
+HRESULT Entry::do_context_menu(HWND hwnd, const POINT& pos, CtxMenuInterfaces& cm_ifs)
 {
 	ShellPath shell_path = create_absolute_pidl();
 	LPCITEMIDLIST pidl_abs = shell_path;
@@ -419,7 +419,7 @@
 		HRESULT hr = (*SHBindToParent)(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast);
 
 		if (SUCCEEDED(hr)) {
-			hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pos.x, pos.y);
+			hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pos.x, pos.y, cm_ifs);
 
 			parentFolder->Release();
 		}
@@ -442,7 +442,7 @@
 		ShellFolder parent_folder = parent_path;
 		return ShellFolderContextMenu(parent_folder, hwnd, 1, &pidl, pos.x, pos.y);
 		*/
-		return ShellFolderContextMenu(GetDesktopFolder(), hwnd, 1, &pidl_abs, pos.x, pos.y);
+		return ShellFolderContextMenu(GetDesktopFolder(), hwnd, 1, &pidl_abs, pos.x, pos.y, cm_ifs);
 	}
 }
 

Modified: trunk/reactos/subsys/system/explorer/shell/entries.h
--- trunk/reactos/subsys/system/explorer/shell/entries.h	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/shell/entries.h	2005-02-06 13:02:48 UTC (rev 13437)
@@ -112,7 +112,7 @@
 	virtual ShellPath	create_absolute_pidl() const {return (LPCITEMIDLIST)NULL;}
 	virtual HRESULT		GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
 	virtual BOOL		launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
-	virtual HRESULT		do_context_menu(HWND hwnd, const POINT& pos);
+	virtual HRESULT		do_context_menu(HWND hwnd, const POINT& pos, CtxMenuInterfaces& cm_ifs);
 };
 
 

Modified: trunk/reactos/subsys/system/explorer/shell/filechild.cpp
--- trunk/reactos/subsys/system/explorer/shell/filechild.cpp	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/shell/filechild.cpp	2005-02-06 13:02:48 UTC (rev 13437)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -123,7 +123,7 @@
  // FileChildWindow
 
 FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info)
- :	ChildWindow(hwnd, info)
+ :	super(hwnd, info)
 {
 	CONTEXT("FileChildWindow::FileChildWindow()");
 
@@ -433,7 +433,7 @@
 
 			if (dis->CtlID == IDW_TREE_LEFT)
 				_left->draw_item(dis, entry);
-			else
+			else if (dis->CtlID == IDW_TREE_RIGHT)
 				_right->draw_item(dis, entry);
 
 			return TRUE;}
@@ -507,7 +507,7 @@
 			if (idx != -1) {
 				Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx);
 
-				CHECKERROR(entry->do_context_menu(_hwnd, pt_screen));
+				CHECKERROR(entry->do_context_menu(_hwnd, pt_screen, _cm_ifs));
 			}
 			break;}
 

Modified: trunk/reactos/subsys/system/explorer/shell/filechild.h
--- trunk/reactos/subsys/system/explorer/shell/filechild.h	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/shell/filechild.h	2005-02-06 13:02:48 UTC (rev 13437)
@@ -85,9 +85,9 @@
 
 
  /// MDI child window displaying file lists
-struct FileChildWindow : public ChildWindow
+struct FileChildWindow : public ExtContextMenuHandlerT<ChildWindow>
 {
-	typedef ChildWindow super;
+	typedef ExtContextMenuHandlerT<ChildWindow> super;
 
 	FileChildWindow(HWND hwnd, const FileChildWndInfo& info);
 

Modified: trunk/reactos/subsys/system/explorer/shell/mainframe.cpp
--- trunk/reactos/subsys/system/explorer/shell/mainframe.cpp	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/shell/mainframe.cpp	2005-02-06 13:02:48 UTC (rev 13437)
@@ -1564,7 +1564,7 @@
 	}
 
 	_shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
-												_shellpath_info, _himlSmall, this));
+												_shellpath_info, _himlSmall, this, _cm_ifs));
 
 	_shellBrowser->Init(_hwnd);
 

Modified: trunk/reactos/subsys/system/explorer/shell/mainframe.h
--- trunk/reactos/subsys/system/explorer/shell/mainframe.h	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/shell/mainframe.h	2005-02-06 13:02:48 UTC (rev 13437)
@@ -124,9 +124,13 @@
 #endif
 
 
-struct SDIMainFrame : public ShellBrowserChildT<MainFrameBase>
+struct SDIMainFrame : public ExtContextMenuHandlerT<
+				ShellBrowserChildT<MainFrameBase>
+			>
 {
-	typedef ShellBrowserChildT<MainFrameBase> super;
+	typedef ExtContextMenuHandlerT<
+				ShellBrowserChildT<MainFrameBase>
+			> super;
 
 	SDIMainFrame(HWND hwnd);
 

Modified: trunk/reactos/subsys/system/explorer/shell/pane.cpp
--- trunk/reactos/subsys/system/explorer/shell/pane.cpp	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/shell/pane.cpp	2005-02-06 13:02:48 UTC (rev 13437)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -491,9 +491,9 @@
 	 // output type/class name
 	if (visible_cols & COL_TYPE) {
 		if (calcWidthCol == -1)
-			_out_wrkr.output_text(dis, _positions, col, entry->_type_name&&entry->_type_name!=LPSTR_TEXTCALLBACK? entry->_type_name: TEXT(""), 0);
+			_out_wrkr.output_text(dis, _positions, col, entry->_type_name? entry->_type_name: TEXT(""), 0);
 		else if (calcWidthCol==col || calcWidthCol==COLUMNS)
-			calc_width(dis, col, entry->_type_name&&entry->_type_name!=LPSTR_TEXTCALLBACK? entry->_type_name: TEXT(""));
+			calc_width(dis, col, entry->_type_name? entry->_type_name: TEXT(""));
 	}
 	++col;
 
@@ -623,9 +623,9 @@
 	 // output content / symbolic link target / comment
 	if (visible_cols & COL_CONTENT) {
 		if (calcWidthCol == -1)
-			_out_wrkr.output_text(dis, _positions, col, entry->_content&&entry->_content!=LPSTR_TEXTCALLBACK? entry->_content: TEXT(""), 0);
+			_out_wrkr.output_text(dis, _positions, col, entry->_content? entry->_content: TEXT(""), 0);
 		else if (calcWidthCol==col || calcWidthCol==COLUMNS)
-			calc_width(dis, col, entry->_content&&entry->_content!=LPSTR_TEXTCALLBACK? entry->_content: TEXT(""));
+			calc_width(dis, col, entry->_content? entry->_content: TEXT(""));
 	}
 }
 

Modified: trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp
--- trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp	2005-02-06 13:02:48 UTC (rev 13437)
@@ -31,13 +31,15 @@
 #include "../explorer_intres.h"
 
 
-ShellBrowser::ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, HIMAGELIST himl, BrowserCallback* cb)
+ShellBrowser::ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info,
+							HIMAGELIST himl, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs)
  :	_hwnd(hwnd),
 	_left_hwnd(left_hwnd),
 	_right_hwnd(right_hwnd),
 	_create_info(create_info),
 	_himl(himl),
-	_callback(cb)
+	_callback(cb),
+	_cm_ifs(cm_ifs)
 {
 	_pShellView = NULL;
 	_pDropTarget = NULL;
@@ -204,7 +206,7 @@
 			Entry* entry = (Entry*)itemData;
 			ClientToScreen(_left_hwnd, &tvhti.pt);
 
-			CHECKERROR(entry->do_context_menu(_hwnd, tvhti.pt));
+			CHECKERROR(entry->do_context_menu(_hwnd, tvhti.pt, _cm_ifs));
 		}
 	}
 }
@@ -574,7 +576,7 @@
 	}
 
 	_shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
-												_shellpath_info, _himlSmall, this));
+												_shellpath_info, _himlSmall, this, _cm_ifs));
 
 	_shellBrowser->Init(_hwndFrame);
 }

Modified: trunk/reactos/subsys/system/explorer/shell/shellbrowser.h
--- trunk/reactos/subsys/system/explorer/shell/shellbrowser.h	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/shell/shellbrowser.h	2005-02-06 13:02:48 UTC (rev 13437)
@@ -57,7 +57,8 @@
  /// Implementation of IShellBrowserImpl interface in explorer child windows
 struct ShellBrowser : public IShellBrowserImpl
 {
-	ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, HIMAGELIST himl, BrowserCallback* cb);
+	ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info,
+					HIMAGELIST himl, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs);
 	virtual ~ShellBrowser();
 
 	//IOleWindow
@@ -153,6 +154,8 @@
 	Root	_root;
 	ShellDirectory*	_cur_dir;
 
+	CtxMenuInterfaces& _cm_ifs;
+
 	void	InitializeTree(HIMAGELIST himl);
 	bool	InitDragDrop();
 
@@ -231,9 +234,13 @@
 
 #ifndef _NO_MDI
 
-struct MDIShellBrowserChild : public ShellBrowserChildT<ChildWindow>
+struct MDIShellBrowserChild : public ExtContextMenuHandlerT<
+				ShellBrowserChildT<ChildWindow>
+			>
 {
-	typedef ShellBrowserChildT<ChildWindow> super;
+	typedef ExtContextMenuHandlerT<
+				ShellBrowserChildT<ChildWindow>
+			> super;
 
 	MDIShellBrowserChild(HWND hwnd, const ShellChildWndInfo& info);
 

Modified: trunk/reactos/subsys/system/explorer/shell/shellfs.cpp
--- trunk/reactos/subsys/system/explorer/shell/shellfs.cpp	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/shell/shellfs.cpp	2005-02-06 13:02:48 UTC (rev 13437)
@@ -202,14 +202,14 @@
 }
 
 
-HRESULT ShellEntry::do_context_menu(HWND hwnd, LPPOINT pptScreen)
+HRESULT ShellEntry::do_context_menu(HWND hwnd, LPPOINT pptScreen, CtxMenuInterfaces& cm_ifs)
 {
 	ShellDirectory* dir = static_cast<ShellDirectory*>(_up);
 
 	ShellFolder folder = dir? dir->_folder: GetDesktopFolder();
 	LPCITEMIDLIST pidl = _pidl;
 
-	return ShellFolderContextMenu(folder, hwnd, 1, &pidl, pptScreen->x, pptScreen->y);
+	return ShellFolderContextMenu(folder, hwnd, 1, &pidl, pptScreen->x, pptScreen->y, cm_ifs);
 }
 
 

Modified: trunk/reactos/subsys/system/explorer/shell/shellfs.h
--- trunk/reactos/subsys/system/explorer/shell/shellfs.h	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/shell/shellfs.h	2005-02-06 13:02:48 UTC (rev 13437)
@@ -36,7 +36,7 @@
 	virtual ShellPath	create_absolute_pidl() const;
 	virtual HRESULT		GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
 	virtual BOOL		launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
-	virtual HRESULT		do_context_menu(HWND hwnd, LPPOINT pptScreen);
+	virtual HRESULT		do_context_menu(HWND hwnd, LPPOINT pptScreen, CtxMenuInterfaces& cm_ifs);
 
 	IShellFolder*		get_parent_folder() const;
 

Modified: trunk/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp
--- trunk/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp	2005-02-06 13:02:48 UTC (rev 13437)
@@ -247,7 +247,7 @@
 		}
 
 		if (entry)	// entry is NULL for desktop switch buttons
-			CHECKERROR(entry->do_context_menu(_hwnd, screen_pt));
+			CHECKERROR(entry->do_context_menu(_hwnd, screen_pt, _cm_ifs));
 		else
 			goto def;
 		break;}

Modified: trunk/reactos/subsys/system/explorer/taskbar/quicklaunch.h
--- trunk/reactos/subsys/system/explorer/taskbar/quicklaunch.h	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/taskbar/quicklaunch.h	2005-02-06 13:02:48 UTC (rev 13437)
@@ -57,9 +57,9 @@
 
 
  /// quick launch bar window
-struct QuickLaunchBar : public SubclassedWindow
+struct QuickLaunchBar : public ExtContextMenuHandlerT<SubclassedWindow>
 {
-	typedef SubclassedWindow super;
+	typedef ExtContextMenuHandlerT<SubclassedWindow> super;
 
 	QuickLaunchBar(HWND hwnd);
 	~QuickLaunchBar();

Modified: trunk/reactos/subsys/system/explorer/taskbar/startmenu.cpp
--- trunk/reactos/subsys/system/explorer/taskbar/startmenu.cpp	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/taskbar/startmenu.cpp	2005-02-06 13:02:48 UTC (rev 13437)
@@ -442,7 +442,7 @@
 				Entry* entry = *it;
 
 				if (entry) {
-					CHECKERROR(entry->do_context_menu(_hwnd, screen_pt));	// may close start menu because of focus loss
+					CHECKERROR(entry->do_context_menu(_hwnd, screen_pt, _cm_ifs));	// may close start menu because of focus loss
 					break;	///@todo handle context menu for more than one entry
 				}
 			}

Modified: trunk/reactos/subsys/system/explorer/taskbar/startmenu.h
--- trunk/reactos/subsys/system/explorer/taskbar/startmenu.h	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/taskbar/startmenu.h	2005-02-06 13:02:48 UTC (rev 13437)
@@ -202,15 +202,15 @@
  */
 struct StartMenu :
 #ifdef _LIGHT_STARTMENU
-	public OwnerDrawParent<Window>
+	public ExtContextMenuHandlerT<OwnerDrawParent<Window> >
 #else
-	public OwnerDrawParent<DialogWindow>
+	public ExtContextMenuHandlerT<OwnerDrawParent<DialogWindow> >
 #endif
 {
 #ifdef _LIGHT_STARTMENU
-	typedef OwnerDrawParent<Window> super;
+	typedef ExtContextMenuHandlerT<OwnerDrawParent<Window> > super;
 #else
-	typedef OwnerDrawParent<DialogWindow> super;
+	typedef ExtContextMenuHandlerT<OwnerDrawParent<DialogWindow> > super;
 #endif
 
 	StartMenu(HWND hwnd);

Modified: trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp
--- trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp	2005-02-06 13:02:48 UTC (rev 13437)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -472,14 +472,65 @@
 }
 
 
-HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, LPCITEMIDLIST* apidl, int x, int y)
+void CtxMenuInterfaces::reset()
 {
-	IContextMenu* pcm;
+	_pctxmenu2 = NULL;
 
-	HRESULT hr = shell_folder->GetUIObjectOf(hwndParent, cidl, apidl, IID_IContextMenu, NULL, (LPVOID*)&pcm);
-//	HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm);
+#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
+	_pctxmenu3 = NULL;
+#endif
+}
 
+bool CtxMenuInterfaces::HandleMenuMsg(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
+	if (_pctxmenu3) {
+		if (SUCCEEDED(_pctxmenu3->HandleMenuMsg(nmsg, wparam, lparam)))
+			return true;
+	}
+#endif
+
+	if (_pctxmenu2)
+		if (SUCCEEDED(_pctxmenu2->HandleMenuMsg(nmsg, wparam, lparam)))
+			return true;
+
+	return false;
+}
+
+IContextMenu* CtxMenuInterfaces::query_interfaces(IContextMenu* pcm1)
+{
+	IContextMenu* pcm = NULL;
+
+	reset();
+
+	 // Get the higher version context menu interfaces.
+#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
+	if (pcm1->QueryInterface(IID_IContextMenu3, (void**)&pcm) == NOERROR)
+		_pctxmenu3 = (LPCONTEXTMENU3)pcm;
+	else
+#endif
+	if (pcm1->QueryInterface (IID_IContextMenu2, (void**)&pcm) == NOERROR)
+		_pctxmenu2 = (LPCONTEXTMENU2)pcm;
+
+	if (pcm) {
+		pcm1->Release();
+		return pcm;
+	} else
+		return pcm1;
+}
+
+
+HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl,
+								LPCITEMIDLIST* apidl, int x, int y, CtxMenuInterfaces& cm_ifs)
+{
+	IContextMenu* pcm1;
+
+	HRESULT hr = shell_folder->GetUIObjectOf(hwndParent, cidl, apidl, IID_IContextMenu, NULL, (LPVOID*)&pcm1);
+//	HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm1);
+
 	if (SUCCEEDED(hr)) {
+		IContextMenu* pcm = cm_ifs.query_interfaces(pcm1);
+
 		HMENU hmenu = CreatePopupMenu();
 
 		if (hmenu) {
@@ -488,6 +539,8 @@
 			if (SUCCEEDED(hr)) {
 				UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, hwndParent, NULL);
 
+				cm_ifs.reset();
+
 				if (idCmd) {
 				  CMINVOKECOMMANDINFO cmi;
 

Modified: trunk/reactos/subsys/system/explorer/utility/shellclasses.h
--- trunk/reactos/subsys/system/explorer/utility/shellclasses.h	2005-02-06 12:39:41 UTC (rev 13436)
+++ trunk/reactos/subsys/system/explorer/utility/shellclasses.h	2005-02-06 13:02:48 UTC (rev 13437)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -1003,4 +1003,77 @@
 	LPIDA _pIDList;
 };
 
-extern HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, LPCITEMIDLIST* ppidl, int x, int y);
+
+struct CtxMenuInterfaces
+{
+	CtxMenuInterfaces()
+	{
+		reset();
+	}
+
+	void	reset();
+	bool	HandleMenuMsg(UINT nmsg, WPARAM wparam, LPARAM lparam);
+	IContextMenu* query_interfaces(IContextMenu* pcm1);
+
+	IContextMenu2*	_pctxmenu2;
+
+#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
+	IContextMenu3*	_pctxmenu3;
+#endif
+};
+
+template<typename BASE> struct ExtContextMenuHandlerT
+ : public BASE
+{
+	typedef BASE super;
+
+	ExtContextMenuHandlerT(HWND hwnd)
+	 :	super(hwnd)
+	{
+	}
+
+	template<typename PARA> ExtContextMenuHandlerT(HWND hwnd, const PARA& info)
+	 :	super(hwnd, info)
+	{
+	}
+
+	LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
+	{
+		switch(nmsg) {
+		  case WM_DRAWITEM:
+		  case WM_MEASUREITEM:
+			if (!wparam)	// Is the message menu-related?
+				if (_cm_ifs.HandleMenuMsg(nmsg, wparam, lparam))
+					return TRUE;
+
+			break;
+
+		  case WM_INITMENUPOPUP:
+			if (_cm_ifs.HandleMenuMsg(nmsg, wparam, lparam))
+				return 0;
+
+			break;
+
+#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
+		  case WM_MENUCHAR:	// only supported by IContextMenu3
+		   if (_cm_ifs._pctxmenu3) {
+			   LRESULT lResult = 0;
+
+			   _cm_ifs._pctxmenu3->HandleMenuMsg2(nmsg, wparam, lparam, &lResult);
+
+			   return lResult;
+		   }
+
+		   return 0;
+#endif
+		}
+
+		return super::WndProc(nmsg, wparam, lparam);
+	}
+
+protected:
+	CtxMenuInterfaces _cm_ifs;
+};
+
+extern HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl,
+										LPCITEMIDLIST* ppidl, int x, int y, CtxMenuInterfaces& cm_ifs);