implement owner drawn context menus for winefile
Modified: trunk/reactos/subsys/system/winefile/winefile.c

Modified: trunk/reactos/subsys/system/winefile/winefile.c
--- trunk/reactos/subsys/system/winefile/winefile.c	2005-05-01 22:30:13 UTC (rev 14939)
+++ trunk/reactos/subsys/system/winefile/winefile.c	2005-05-01 23:19:48 UTC (rev 14940)
@@ -3411,6 +3411,59 @@
 }
 
 
+static IContextMenu2* s_pctxmenu2 = NULL;
+
+#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
+static IContextMenu3* s_pctxmenu3 = NULL;
+#endif
+
+static void CtxMenu_reset()
+{
+	s_pctxmenu2 = NULL;
+
+#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
+	s_pctxmenu3 = NULL;
+#endif
+}
+
+IContextMenu* CtxMenu_query_interfaces(IContextMenu* pcm1)
+{
+	IContextMenu* pcm = NULL;
+
+	CtxMenu_reset();
+
+#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
+	if ((*pcm1->lpVtbl->QueryInterface)(pcm1, &IID_IContextMenu3, (void**)&pcm) == NOERROR)
+		s_pctxmenu3 = (LPCONTEXTMENU3)pcm;
+	else
+#endif
+	if ((*pcm1->lpVtbl->QueryInterface)(pcm1, &IID_IContextMenu2, (void**)&pcm) == NOERROR)
+		s_pctxmenu2 = (LPCONTEXTMENU2)pcm;
+
+	if (pcm) {
+		(*pcm1->lpVtbl->Release)(pcm1);
+		return pcm;
+	} else
+		return pcm1;
+}
+
+static BOOL CtxMenu_HandleMenuMsg(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+#ifndef __MINGW32__	// IContextMenu3 missing in MinGW (as of 6.2.2005)
+	if (s_pctxmenu3) {
+		if (SUCCEEDED((*s_pctxmenu3->lpVtbl->HandleMenuMsg)(s_pctxmenu3, nmsg, wparam, lparam)))
+			return TRUE;
+	}
+#endif
+
+	if (s_pctxmenu2)
+		if (SUCCEEDED((*s_pctxmenu2->lpVtbl->HandleMenuMsg)(s_pctxmenu2, nmsg, wparam, lparam)))
+			return TRUE;
+
+	return FALSE;
+}
+
+
 static HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, LPCITEMIDLIST* apidl, int x, int y)
 {
 	IContextMenu* pcm;
@@ -3421,12 +3474,16 @@
 	if (SUCCEEDED(hr)) {
 		HMENU hmenu = CreatePopupMenu();
 
+		pcm = CtxMenu_query_interfaces(pcm);
+
 		if (hmenu) {
 			hr = (*pcm->lpVtbl->QueryContextMenu)(pcm, hmenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
 
 			if (SUCCEEDED(hr)) {
 				UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, hwndParent, NULL);
 
+				CtxMenu_reset();
+
 				if (idCmd) {
 				  CMINVOKECOMMANDINFO cmi;
 
@@ -3466,8 +3523,10 @@
 
 			if (dis->CtlID == IDW_TREE_LEFT)
 				draw_item(&child->left, dis, entry, -1);
+			else if (dis->CtlID == IDW_TREE_RIGHT)
+				draw_item(&child->right, dis, entry, -1);
 			else
-				draw_item(&child->right, dis, entry, -1);
+				goto draw_menu_item;
 
 			return TRUE;}
 
@@ -3746,6 +3805,33 @@
 			break;}
 #endif
 
+		  case WM_MEASUREITEM:
+		  draw_menu_item:
+			if (!wparam)	// Is the message menu-related?
+				if (CtxMenu_HandleMenuMsg(nmsg, wparam, lparam))
+					return TRUE;
+
+			break;
+
+		  case WM_INITMENUPOPUP:
+			if (CtxMenu_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 (s_pctxmenu3) {
+			   LRESULT lResult = 0;
+
+			   (*s_pctxmenu3->lpVtbl->HandleMenuMsg2)(s_pctxmenu3, nmsg, wparam, lparam, &lResult);
+
+			   return lResult;
+		   }
+
+		   break;
+#endif
+
 		case WM_SIZE:
 			if (wparam != SIZE_MINIMIZED)
 				resize_tree(child, LOWORD(lparam), HIWORD(lparam));