2 * see www.geocities.com/SiliconValley/4942/filemenu.html
7 #include "wine/obj_base.h"
8 #include "wine/obj_enumidlist.h"
9 #include "wine/obj_shellfolder.h"
10 #include "wine/undocshell.h"
13 #include "debugtools.h"
14 #include "shell32_main.h"
19 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hMenu);
20 BOOL WINAPI FileMenu_AppendItemA(HMENU hMenu, LPCSTR lpText, UINT uID, int icon, HMENU hMenuPopup, int nItemHeight);
27 COLORREF crBorderColor;
31 /* insert using pidl */
36 LPFNFMCALLBACK lpfnCallback;
46 static BOOL bAbortInit;
48 #define CCH_MAXITEMTEXT 256
50 DEFAULT_DEBUG_CHANNEL(shell);
52 LPFMINFO FM_GetMenuInfo(HMENU hmenu)
56 MenuInfo.cbSize = sizeof(MENUINFO);
57 MenuInfo.fMask = MIM_MENUDATA;
59 if (! GetMenuInfo(hmenu, &MenuInfo))
62 menudata = (LPFMINFO)MenuInfo.dwMenuData;
64 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
66 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
73 /*************************************************************************
74 * FM_SetMenuParameter [internal]
77 static LPFMINFO FM_SetMenuParameter(
83 LPFNFMCALLBACK lpfnCallback)
89 menudata = FM_GetMenuInfo(hmenu);
92 { SHFree(menudata->pidl);
96 menudata->pidl = ILClone(pidl);
97 menudata->uFlags = uFlags;
98 menudata->uEnumFlags = uEnumFlags;
99 menudata->lpfnCallback = lpfnCallback;
104 /*************************************************************************
105 * FM_InitMenuPopup [internal]
108 static int FM_InitMenuPopup(HMENU hmenu, LPITEMIDLIST pAlternatePidl)
109 { IShellFolder *lpsf, *lpsf2;
110 ULONG ulItemAttr = SFGAO_FOLDER;
111 UINT uID, uFlags, uEnumFlags;
112 LPFNFMCALLBACK lpfnCallback;
114 char sTemp[MAX_PATH];
115 int NumberOfItems = 0, iIcon;
119 TRACE("0x%04x %p\n", hmenu, pAlternatePidl);
121 MenuInfo.cbSize = sizeof(MENUINFO);
122 MenuInfo.fMask = MIM_MENUDATA;
124 if (! GetMenuInfo(hmenu, &MenuInfo))
127 menudata = (LPFMINFO)MenuInfo.dwMenuData;
129 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
131 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
135 if (menudata->bInitialized)
138 pidl = ((pAlternatePidl) ? pAlternatePidl : menudata->pidl);
143 uFlags = menudata->uFlags;
144 uEnumFlags = menudata->uEnumFlags;
145 lpfnCallback = menudata->lpfnCallback;
146 menudata->bInitialized = FALSE;
148 SetMenuInfo(hmenu, &MenuInfo);
150 if (SUCCEEDED (SHGetDesktopFolder(&lpsf)))
152 if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
154 IEnumIDList *lpe = NULL;
156 if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe )))
159 LPITEMIDLIST pidlTemp = NULL;
162 while ((!bAbortInit) && (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched)))
164 if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr)))
166 ILGetDisplayName( pidlTemp, sTemp);
167 if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, 0, &iIcon)))
168 iIcon = FM_BLANK_ICON;
169 if ( SFGAO_FOLDER & ulItemAttr)
173 HMENU hMenuPopup = CreatePopupMenu();
175 lpFmMi = (LPFMINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
177 lpFmMi->pidl = ILCombine(pidl, pidlTemp);
178 lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
180 MenuInfo.cbSize = sizeof(MENUINFO);
181 MenuInfo.fMask = MIM_MENUDATA;
182 MenuInfo.dwMenuData = (DWORD) lpFmMi;
183 SetMenuInfo (hMenuPopup, &MenuInfo);
185 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
189 ((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
190 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
196 TRACE("enter callback\n");
197 lpfnCallback ( pidl, pidlTemp);
198 TRACE("leave callback\n");
203 IEnumIDList_Release (lpe);
205 IShellFolder_Release(lpsf2);
207 IShellFolder_Release(lpsf);
210 if ( GetMenuItemCount (hmenu) == 0 )
211 { FileMenu_AppendItemA (hmenu, "(empty)", uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
215 menudata->bInitialized = TRUE;
216 SetMenuInfo(hmenu, &MenuInfo);
218 return NumberOfItems;
220 /*************************************************************************
221 * FileMenu_Create [SHELL32.114]
224 * for non-root menus values are
225 * (ffffffff,00000000,00000000,00000000,00000000)
227 HMENU WINAPI FileMenu_Create (
228 COLORREF crBorderColor,
237 HMENU hMenu = CreatePopupMenu();
239 TRACE("0x%08lx 0x%08x 0x%08x 0x%08x 0x%08x hMenu=0x%08x\n",
240 crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, hMenu);
242 menudata = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
243 menudata->crBorderColor = crBorderColor;
244 menudata->nBorderWidth = nBorderWidth;
245 menudata->hBorderBmp = hBorderBmp;
247 MenuInfo.cbSize = sizeof(MENUINFO);
248 MenuInfo.fMask = MIM_MENUDATA;
249 MenuInfo.dwMenuData = (DWORD) menudata;
250 SetMenuInfo (hMenu, &MenuInfo);
255 /*************************************************************************
256 * FileMenu_Destroy [SHELL32.118]
261 void WINAPI FileMenu_Destroy (HMENU hmenu)
265 TRACE("0x%08x\n", hmenu);
267 FileMenu_DeleteAllItems (hmenu);
269 menudata = FM_GetMenuInfo(hmenu);
272 { SHFree( menudata->pidl);
274 HeapFree(GetProcessHeap(), 0, menudata);
279 /*************************************************************************
280 * FileMenu_AppendItemAW [SHELL32.115]
283 BOOL WINAPI FileMenu_AppendItemA(
291 LPSTR lpszText = (LPSTR)lpText;
298 TRACE("0x%08x %s 0x%08x 0x%08x 0x%08x 0x%08x\n",
299 hMenu, (lpszText!=FM_SEPARATOR) ? lpText: NULL,
300 uID, icon, hMenuPopup, nItemHeight);
302 ZeroMemory (&mii, sizeof(MENUITEMINFOA));
304 mii.cbSize = sizeof(MENUITEMINFOA);
306 if (lpText != FM_SEPARATOR)
307 { int len = strlen (lpText);
308 myItem = (LPFMITEM) SHAlloc( sizeof(FMITEM) + len);
309 strcpy (myItem->szItemText, lpText);
310 myItem->cchItemText = len;
311 myItem->iIconIndex = icon;
312 myItem->hMenu = hMenu;
313 mii.fMask = MIIM_DATA;
314 mii.dwItemData = (DWORD) myItem;
319 mii.fMask |= MIIM_TYPE | MIIM_SUBMENU;
320 mii.fType = MFT_OWNERDRAW;
321 mii.hSubMenu = hMenuPopup;
323 else if (lpText == FM_SEPARATOR )
324 { mii.fMask |= MIIM_ID | MIIM_TYPE;
325 mii.fType = MFT_SEPARATOR;
329 mii.fMask |= MIIM_ID | MIIM_TYPE | MIIM_STATE;
330 mii.fState = MFS_ENABLED | MFS_DEFAULT;
331 mii.fType = MFT_OWNERDRAW;
335 InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
337 /* set bFixedItems to true */
338 MenuInfo.cbSize = sizeof(MENUINFO);
339 MenuInfo.fMask = MIM_MENUDATA;
341 if (! GetMenuInfo(hMenu, &MenuInfo))
344 menudata = (LPFMINFO)MenuInfo.dwMenuData;
345 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
347 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
351 menudata->bFixedItems = TRUE;
352 SetMenuInfo(hMenu, &MenuInfo);
358 /**********************************************************************/
360 BOOL WINAPI FileMenu_AppendItemAW(
371 if (SHELL_OsIsUnicode() && (lpText!=FM_SEPARATOR))
372 lpszText = HEAP_strdupWtoA ( GetProcessHeap(),0, lpText);
374 ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : lpText, uID, icon, hMenuPopup, nItemHeight);
377 HeapFree( GetProcessHeap(), 0, lpszText );
381 /*************************************************************************
382 * FileMenu_InsertUsingPidl [SHELL32.110]
385 * uEnumFlags any SHCONTF flag
387 int WINAPI FileMenu_InsertUsingPidl (
393 LPFNFMCALLBACK lpfnCallback)
395 TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
396 hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
402 FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
404 return FM_InitMenuPopup(hmenu, NULL);
407 /*************************************************************************
408 * FileMenu_ReplaceUsingPidl [SHELL32.113]
410 * FIXME: the static items are deleted but wont be refreshed
412 int WINAPI FileMenu_ReplaceUsingPidl(
417 LPFNFMCALLBACK lpfnCallback)
419 TRACE("0x%08x 0x%08x %p 0x%08x %p\n",
420 hmenu, uID, pidl, uEnumFlags, lpfnCallback);
422 FileMenu_DeleteAllItems (hmenu);
424 FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback);
426 return FM_InitMenuPopup(hmenu, NULL);
429 /*************************************************************************
430 * FileMenu_Invalidate [SHELL32.111]
432 void WINAPI FileMenu_Invalidate (HMENU hMenu)
434 FIXME("0x%08x\n",hMenu);
437 /*************************************************************************
438 * FileMenu_FindSubMenuByPidl [SHELL32.106]
440 HMENU WINAPI FileMenu_FindSubMenuByPidl(
444 FIXME("0x%08x %p\n",hMenu, pidl);
448 /*************************************************************************
449 * FileMenu_AppendFilesForPidl [SHELL32.124]
451 int WINAPI FileMenu_AppendFilesForPidl(
458 menudata = FM_GetMenuInfo(hmenu);
460 menudata->bInitialized = FALSE;
462 FM_InitMenuPopup(hmenu, pidl);
465 FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
467 TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator);
471 /*************************************************************************
472 * FileMenu_AddFilesForPidl [SHELL32.125]
475 * uEnumFlags any SHCONTF flag
477 int WINAPI FileMenu_AddFilesForPidl (
484 LPFNFMCALLBACK lpfnCallback)
486 TRACE("0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
487 hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
489 return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
494 /*************************************************************************
495 * FileMenu_TrackPopupMenuEx [SHELL32.116]
497 BOOL WINAPI FileMenu_TrackPopupMenuEx (
505 TRACE("0x%08x 0x%08x 0x%x 0x%x 0x%08x %p\n",
506 hMenu, uFlags, x, y, hWnd, lptpm);
507 return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm);
510 /*************************************************************************
511 * FileMenu_GetLastSelectedItemPidls [SHELL32.107]
513 BOOL WINAPI FileMenu_GetLastSelectedItemPidls(
515 LPCITEMIDLIST *ppidlFolder,
516 LPCITEMIDLIST *ppidlItem)
518 FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
522 #define FM_ICON_SIZE 16
526 #define FM_LEFTBORDER 2
527 #define FM_RIGHTBORDER 8
528 /*************************************************************************
529 * FileMenu_MeasureItem [SHELL32.112]
531 LRESULT WINAPI FileMenu_MeasureItem(
533 LPMEASUREITEMSTRUCT lpmis)
535 LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
536 HDC hdc = GetDC(hWnd);
540 TRACE("0x%08x %p %s\n", hWnd, lpmis, pMyItem->szItemText);
542 GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
544 lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER;
545 lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE);
547 /* add the menubitmap */
548 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
549 if (menuinfo->nBorderWidth)
550 lpmis->itemWidth += menuinfo->nBorderWidth;
552 TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight);
553 ReleaseDC (hWnd, hdc);
556 /*************************************************************************
557 * FileMenu_DrawItem [SHELL32.105]
559 LRESULT WINAPI FileMenu_DrawItem(
561 LPDRAWITEMSTRUCT lpdis)
563 LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData);
564 COLORREF clrPrevText, clrPrevBkgnd;
566 HIMAGELIST hImageList;
567 RECT TextRect, BorderRect;
570 TRACE("0x%08x %p %s\n", hWnd, lpdis, pMyItem->szItemText);
572 if (lpdis->itemState & ODS_SELECTED)
574 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
575 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
579 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT));
580 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU));
583 CopyRect(&TextRect, &(lpdis->rcItem));
585 /* add the menubitmap */
586 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
587 if (menuinfo->nBorderWidth)
588 TextRect.left += menuinfo->nBorderWidth;
590 BorderRect.right = menuinfo->nBorderWidth;
591 /* FillRect(lpdis->hDC, &BorderRect, CreateSolidBrush( menuinfo->crBorderColor));
593 TextRect.left += FM_LEFTBORDER;
594 xi = TextRect.left + FM_SPACE1;
595 yi = TextRect.top + FM_Y_SPACE/2;
596 TextRect.bottom -= FM_Y_SPACE/2;
598 xt = xi + FM_ICON_SIZE + FM_SPACE2;
601 ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
603 Shell_GetImageList(0, &hImageList);
604 pImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
606 TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom);
608 SetTextColor(lpdis->hDC, clrPrevText);
609 SetBkColor(lpdis->hDC, clrPrevBkgnd);
614 /*************************************************************************
615 * FileMenu_InitMenuPopup [SHELL32.109]
618 * The filemenu is a ownerdrawn menu. Call this function responding to
622 BOOL WINAPI FileMenu_InitMenuPopup (HMENU hmenu)
624 FM_InitMenuPopup(hmenu, NULL);
628 /*************************************************************************
629 * FileMenu_HandleMenuChar [SHELL32.108]
631 LRESULT WINAPI FileMenu_HandleMenuChar(
635 FIXME("0x%08x 0x%08x\n",hMenu,wParam);
639 /*************************************************************************
640 * FileMenu_DeleteAllItems [SHELL32.104]
645 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
652 TRACE("0x%08x\n", hmenu);
654 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
655 mii.cbSize = sizeof(MENUITEMINFOA);
656 mii.fMask = MIIM_SUBMENU|MIIM_DATA;
658 for (i = 0; i < GetMenuItemCount( hmenu ); i++)
659 { GetMenuItemInfoA(hmenu, i, TRUE, &mii );
662 SHFree((LPFMINFO)mii.dwItemData);
665 FileMenu_Destroy(mii.hSubMenu);
668 while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
670 menudata = FM_GetMenuInfo(hmenu);
672 menudata->bInitialized = FALSE;
677 /*************************************************************************
678 * FileMenu_DeleteItemByCmd [SHELL32.]
681 BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
685 TRACE("0x%08x 0x%08x\n", hMenu, uID);
687 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
688 mii.cbSize = sizeof(MENUITEMINFOA);
689 mii.fMask = MIIM_SUBMENU;
691 GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
694 /* FIXME: Do what? */
697 DeleteMenu(hMenu, MF_BYCOMMAND, uID);
701 /*************************************************************************
702 * FileMenu_DeleteItemByIndex [SHELL32.140]
704 BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
708 TRACE("0x%08x 0x%08x\n", hMenu, uPos);
710 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
711 mii.cbSize = sizeof(MENUITEMINFOA);
712 mii.fMask = MIIM_SUBMENU;
714 GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
717 /* FIXME: Do what? */
720 DeleteMenu(hMenu, MF_BYPOSITION, uPos);
724 /*************************************************************************
725 * FileMenu_DeleteItemByFirstID [SHELL32.141]
727 BOOL WINAPI FileMenu_DeleteItemByFirstID(
731 TRACE("0x%08x 0x%08x\n", hMenu, uID);
735 /*************************************************************************
736 * FileMenu_DeleteSeparator [SHELL32.142]
738 BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu)
740 TRACE("0x%08x\n", hMenu);
744 /*************************************************************************
745 * FileMenu_EnableItemByCmd [SHELL32.143]
747 BOOL WINAPI FileMenu_EnableItemByCmd(
752 TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
756 /*************************************************************************
757 * FileMenu_GetItemExtent [SHELL32.144]
760 * if the menu is to big, entrys are getting cut away!!
762 DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos)
765 FIXME("0x%08x 0x%08x\n", hMenu, uPos);
767 if (GetMenuItemRect(0, hMenu, uPos, &rect))
768 { FIXME("0x%04x 0x%04x 0x%04x 0x%04x\n",
769 rect.right, rect.left, rect.top, rect.bottom);
770 return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom);
772 return 0x00100010; /*fixme*/
775 /*************************************************************************
776 * FileMenu_AbortInitMenu [SHELL32.120]
779 void WINAPI FileMenu_AbortInitMenu (void)
784 /*************************************************************************
785 * SHFind_InitMenuPopup [SHELL32.149]
789 * hMenu [in] handle of menu previously created
790 * hWndParent [in] parent window
791 * w [in] no pointer (0x209 over here) perhaps menu IDs ???
792 * x [in] no pointer (0x226 over here)
795 * LPXXXXX pointer to struct containing a func addr at offset 8
796 * or NULL at failure.
798 LPVOID WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, DWORD w, DWORD x)
799 { FIXME("hmenu=0x%08x hwnd=0x%08x 0x%08lx 0x%08lx stub\n",
800 hMenu,hWndParent,w,x);
801 return NULL; /* this is supposed to be a pointer */
804 /*************************************************************************
805 * Shell_MergeMenus [SHELL32.67]
808 BOOL _SHIsMenuSeparator(HMENU hm, int i)
812 mii.cbSize = sizeof(MENUITEMINFOA);
813 mii.fMask = MIIM_TYPE;
814 mii.cch = 0; /* WARNING: We MUST initialize it to 0*/
815 if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
820 if (mii.fType & MFT_SEPARATOR)
828 /**********************************************************************/
830 HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
833 BOOL bAlreadySeparated;
834 MENUITEMINFOA miiSrc;
836 UINT uTemp, uIDMax = uIDAdjust;
838 TRACE("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x 0x%04lx\n",
839 hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
841 if (!hmDst || !hmSrc)
845 nItem = GetMenuItemCount(hmDst);
847 if (uInsert >= (UINT)nItem) /* insert position inside menu? */
849 uInsert = (UINT)nItem; /* append on the end */
850 bAlreadySeparated = TRUE;
854 bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
857 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
859 /* Add a separator between the menus */
860 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
861 bAlreadySeparated = TRUE;
865 /* Go through the menu items and clone them*/
866 for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
868 miiSrc.cbSize = sizeof(MENUITEMINFOA);
869 miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
871 /* We need to reset this every time through the loop in case menus DON'T have IDs*/
872 miiSrc.fType = MFT_STRING;
873 miiSrc.dwTypeData = szName;
874 miiSrc.dwItemData = 0;
875 miiSrc.cch = sizeof(szName);
877 if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
882 /* TRACE("found menu=0x%04x %s id=0x%04x mask=0x%08x smenu=0x%04x\n", hmSrc, debugstr_a(miiSrc.dwTypeData), miiSrc.wID, miiSrc.fMask, miiSrc.hSubMenu);
884 if (miiSrc.fType & MFT_SEPARATOR)
886 /* This is a separator; don't put two of them in a row */
887 if (bAlreadySeparated)
890 bAlreadySeparated = TRUE;
892 else if (miiSrc.hSubMenu)
894 if (uFlags & MM_SUBMENUSHAVEIDS)
896 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
898 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
901 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
902 uIDMax = miiSrc.wID + 1;
906 miiSrc.fMask &= ~MIIM_ID; /* Don't set IDs for submenus that didn't have them already */
908 hmSubMenu = miiSrc.hSubMenu;
910 miiSrc.hSubMenu = CreatePopupMenu();
912 if (!miiSrc.hSubMenu) return(uIDMax);
914 uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS);
919 bAlreadySeparated = FALSE;
921 else /* normal menu item */
923 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
925 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
928 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
929 uIDMax = miiSrc.wID + 1;
931 bAlreadySeparated = FALSE;
934 /* TRACE("inserting menu=0x%04x %s id=0x%04x mask=0x%08x smenu=0x%04x\n", hmDst, debugstr_a(miiSrc.dwTypeData), miiSrc.wID, miiSrc.fMask, miiSrc.hSubMenu);
936 if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
942 /* Ensure the correct number of separators at the beginning of the
943 inserted menu items*/
946 if (bAlreadySeparated)
948 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
953 if (_SHIsMenuSeparator(hmDst, uInsert-1))
955 if (bAlreadySeparated)
957 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
962 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
964 /* Add a separator between the menus*/
965 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);