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 "winversion.h"
15 #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 assert ((menudata != 0) && (MenuInfo.cbSize == sizeof(MENUINFO)));
69 /*************************************************************************
70 * FM_SetMenuParameter [internal]
73 static LPFMINFO FM_SetMenuParameter(
79 LPFNFMCALLBACK lpfnCallback)
85 menudata = FM_GetMenuInfo(hmenu);
88 { SHFree(menudata->pidl);
92 menudata->pidl = ILClone(pidl);
93 menudata->uFlags = uFlags;
94 menudata->uEnumFlags = uEnumFlags;
95 menudata->lpfnCallback = lpfnCallback;
100 /*************************************************************************
101 * FM_InitMenuPopup [internal]
104 static int FM_InitMenuPopup(HMENU hmenu, LPITEMIDLIST pAlternatePidl)
105 { IShellFolder *lpsf, *lpsf2;
107 UINT uID, uFlags, uEnumFlags;
108 LPFNFMCALLBACK lpfnCallback;
110 char sTemp[MAX_PATH];
111 int NumberOfItems = 0, iIcon;
115 TRACE("0x%04x %p\n", hmenu, pAlternatePidl);
117 MenuInfo.cbSize = sizeof(MENUINFO);
118 MenuInfo.fMask = MIM_MENUDATA;
120 if (! GetMenuInfo(hmenu, &MenuInfo))
123 menudata = (LPFMINFO)MenuInfo.dwMenuData;
125 assert ((menudata != 0) && (MenuInfo.cbSize == sizeof(MENUINFO)));
127 if (menudata->bInitialized)
131 pidl = ((pAlternatePidl) ? pAlternatePidl : menudata->pidl);
132 uFlags = menudata->uFlags;
133 uEnumFlags = menudata->uEnumFlags;
134 lpfnCallback = menudata->lpfnCallback;
136 menudata->bInitialized = FALSE;
137 SetMenuInfo(hmenu, &MenuInfo);
139 if (SUCCEEDED (SHGetDesktopFolder(&lpsf)))
141 if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
143 IEnumIDList *lpe = NULL;
145 if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe )))
148 LPITEMIDLIST pidlTemp = NULL;
151 while ((!bAbortInit) && (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched)))
153 if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr)))
155 ILGetDisplayName( pidlTemp, sTemp);
156 if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, &iIcon)))
157 iIcon = FM_BLANK_ICON;
158 if ( SFGAO_FOLDER & ulItemAttr)
162 HMENU hMenuPopup = CreatePopupMenu();
164 lpFmMi = (LPFMINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
166 lpFmMi->pidl = ILCombine(pidl, pidlTemp);
167 lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
169 MenuInfo.cbSize = sizeof(MENUINFO);
170 MenuInfo.fMask = MIM_MENUDATA;
171 MenuInfo.dwMenuData = (DWORD) lpFmMi;
172 SetMenuInfo (hMenuPopup, &MenuInfo);
174 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
178 ((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
179 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
185 TRACE("enter callback\n");
186 lpfnCallback ( pidl, pidlTemp);
187 TRACE("leave callback\n");
192 IEnumIDList_Release (lpe);
194 IShellFolder_Release(lpsf2);
196 IShellFolder_Release(lpsf);
199 if ( GetMenuItemCount (hmenu) == 0 )
200 { FileMenu_AppendItemA (hmenu, "(empty)", uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
204 menudata->bInitialized = TRUE;
205 SetMenuInfo(hmenu, &MenuInfo);
207 return NumberOfItems;
209 /*************************************************************************
210 * FileMenu_Create [SHELL32.114]
213 HMENU WINAPI FileMenu_Create (
214 COLORREF crBorderColor,
223 HMENU hMenu = CreatePopupMenu();
225 TRACE("0x%08lx 0x%08x 0x%08x 0x%08x 0x%08x hMenu=0x%08x\n",
226 crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, hMenu);
228 menudata = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
229 menudata->bIsMagic = TRUE;
230 menudata->crBorderColor = crBorderColor;
231 menudata->nBorderWidth = nBorderWidth;
232 menudata->hBorderBmp = hBorderBmp;
234 MenuInfo.cbSize = sizeof(MENUINFO);
235 MenuInfo.fMask = MIM_MENUDATA;
236 MenuInfo.dwMenuData = (DWORD) menudata;
237 SetMenuInfo (hMenu, &MenuInfo);
242 /*************************************************************************
243 * FileMenu_Destroy [SHELL32.118]
248 void WINAPI FileMenu_Destroy (HMENU hmenu)
252 TRACE("0x%08x\n", hmenu);
254 FileMenu_DeleteAllItems (hmenu);
256 menudata = FM_GetMenuInfo(hmenu);
259 { SHFree( menudata->pidl);
261 HeapFree(GetProcessHeap(), 0, menudata);
266 /*************************************************************************
267 * FileMenu_AppendItemAW [SHELL32.115]
270 BOOL WINAPI FileMenu_AppendItemA(
278 LPSTR lpszText = (LPSTR)lpText;
282 TRACE("0x%08x %s 0x%08x 0x%08x 0x%08x 0x%08x\n",
283 hMenu, (lpszText!=FM_SEPARATOR) ? lpText: NULL,
284 uID, icon, hMenuPopup, nItemHeight);
286 ZeroMemory (&mii, sizeof(MENUITEMINFOA));
288 mii.cbSize = sizeof(MENUITEMINFOA);
290 if (lpText != FM_SEPARATOR)
291 { int len = strlen (lpText);
292 myItem = (LPFMITEM) SHAlloc( sizeof(FMITEM) + len);
293 strcpy (myItem->szItemText, lpText);
294 myItem->cchItemText = len;
295 myItem->iIconIndex = icon;
296 myItem->hMenu = hMenu;
297 mii.fMask = MIIM_DATA;
298 mii.dwItemData = (DWORD) myItem;
303 mii.fMask |= MIIM_TYPE | MIIM_SUBMENU;
304 mii.fType = MFT_OWNERDRAW;
305 mii.hSubMenu = hMenuPopup;
307 else if (lpText == FM_SEPARATOR )
308 { mii.fMask |= MIIM_ID | MIIM_TYPE;
309 mii.fType = MFT_SEPARATOR;
313 mii.fMask |= MIIM_ID | MIIM_TYPE | MIIM_STATE;
314 mii.fState = MFS_ENABLED | MFS_DEFAULT;
315 mii.fType = MFT_OWNERDRAW;
319 InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
324 BOOL WINAPI FileMenu_AppendItemAW(
335 if (VERSION_OsIsUnicode() && (lpText!=FM_SEPARATOR))
336 lpszText = HEAP_strdupWtoA ( GetProcessHeap(),0, lpText);
338 ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : lpText, uID, icon, hMenuPopup, nItemHeight);
341 HeapFree( GetProcessHeap(), 0, lpszText );
345 /*************************************************************************
346 * FileMenu_InsertUsingPidl [SHELL32.110]
349 * uEnumFlags any SHCONTF flag
351 int WINAPI FileMenu_InsertUsingPidl (
357 LPFNFMCALLBACK lpfnCallback)
359 TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
360 hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
366 FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
368 return FM_InitMenuPopup(hmenu, NULL);
371 /*************************************************************************
372 * FileMenu_ReplaceUsingPidl [SHELL32.113]
375 int WINAPI FileMenu_ReplaceUsingPidl(
380 LPFNFMCALLBACK lpfnCallback)
382 TRACE("0x%08x 0x%08x %p 0x%08x %p\n",
383 hmenu, uID, pidl, uEnumFlags, lpfnCallback);
385 FileMenu_DeleteAllItems (hmenu);
387 FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback);
389 return FM_InitMenuPopup(hmenu, NULL);
392 /*************************************************************************
393 * FileMenu_Invalidate [SHELL32.111]
395 void WINAPI FileMenu_Invalidate (HMENU hMenu)
397 FIXME("0x%08x\n",hMenu);
400 /*************************************************************************
401 * FileMenu_FindSubMenuByPidl [SHELL32.106]
403 HMENU WINAPI FileMenu_FindSubMenuByPidl(
407 FIXME("0x%08x %p\n",hMenu, pidl);
411 /*************************************************************************
412 * FileMenu_AppendFilesForPidl [SHELL32.124]
414 HMENU WINAPI FileMenu_AppendFilesForPidl(
421 menudata = FM_GetMenuInfo(hmenu);
423 menudata->bInitialized = FALSE;
425 FM_InitMenuPopup(hmenu, pidl);
428 FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
430 TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator);
434 /*************************************************************************
435 * FileMenu_AddFilesForPidl [SHELL32.125]
438 * uEnumFlags any SHCONTF flag
440 int WINAPI FileMenu_AddFilesForPidl (
447 LPFNFMCALLBACK lpfnCallback)
449 TRACE("0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
450 hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
452 return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
457 /*************************************************************************
458 * FileMenu_TrackPopupMenuEx [SHELL32.116]
460 HRESULT WINAPI FileMenu_TrackPopupMenuEx (
468 TRACE("0x%08x 0x%08x 0x%x 0x%x 0x%08x %p\n",
469 hMenu, uFlags, x, y, hWnd, lptpm);
470 return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm);
473 /*************************************************************************
474 * FileMenu_GetLastSelectedItemPidls [SHELL32.107]
476 BOOL WINAPI FileMenu_GetLastSelectedItemPidls(
478 LPCITEMIDLIST *ppidlFolder,
479 LPCITEMIDLIST *ppidlItem)
481 FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
485 #define FM_ICON_SIZE 16
489 #define FM_LEFTBORDER 2
490 #define FM_RIGHTBORDER 8
491 /*************************************************************************
492 * FileMenu_MeasureItem [SHELL32.112]
494 LRESULT WINAPI FileMenu_MeasureItem(
496 LPMEASUREITEMSTRUCT lpmis)
498 LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
499 HDC hdc = GetDC(hWnd);
503 TRACE("0x%08x %p %s\n", hWnd, lpmis, pMyItem->szItemText);
505 GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
507 lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER;
508 lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE);
510 /* add the menubitmap */
511 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
512 if (menuinfo->bIsMagic)
513 lpmis->itemWidth += menuinfo->nBorderWidth;
515 TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight);
516 ReleaseDC (hWnd, hdc);
519 /*************************************************************************
520 * FileMenu_DrawItem [SHELL32.105]
522 LRESULT WINAPI FileMenu_DrawItem(
524 LPDRAWITEMSTRUCT lpdis)
526 LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData);
527 COLORREF clrPrevText, clrPrevBkgnd;
529 HIMAGELIST hImageList;
530 RECT TextRect, BorderRect;
533 TRACE("0x%08x %p %s\n", hWnd, lpdis, pMyItem->szItemText);
535 if (lpdis->itemState & ODS_SELECTED)
537 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
538 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
542 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT));
543 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU));
546 CopyRect(&TextRect, &(lpdis->rcItem));
548 /* add the menubitmap */
549 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
550 if (menuinfo->bIsMagic)
551 TextRect.left += menuinfo->nBorderWidth;
553 BorderRect.right = menuinfo->nBorderWidth;
554 /* FillRect(lpdis->hDC, &BorderRect, CreateSolidBrush( menuinfo->crBorderColor));
556 TextRect.left += FM_LEFTBORDER;
557 xi = TextRect.left + FM_SPACE1;
558 yi = TextRect.top + FM_Y_SPACE/2;
559 TextRect.bottom -= FM_Y_SPACE/2;
561 xt = xi + FM_ICON_SIZE + FM_SPACE2;
564 ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
566 Shell_GetImageList(0, &hImageList);
567 pImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
569 TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom);
571 SetTextColor(lpdis->hDC, clrPrevText);
572 SetBkColor(lpdis->hDC, clrPrevBkgnd);
577 /*************************************************************************
578 * FileMenu_InitMenuPopup [SHELL32.109]
581 * The filemenu is a ownerdrawn menu. Call this function responding to
585 BOOL WINAPI FileMenu_InitMenuPopup (HMENU hmenu)
587 FM_InitMenuPopup(hmenu, NULL);
591 /*************************************************************************
592 * FileMenu_HandleMenuChar [SHELL32.108]
594 LRESULT WINAPI FileMenu_HandleMenuChar(
598 FIXME("0x%08x 0x%08x\n",hMenu,wParam);
602 /*************************************************************************
603 * FileMenu_DeleteAllItems [SHELL32.104]
608 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
615 TRACE("0x%08x\n", hmenu);
617 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
618 mii.cbSize = sizeof(MENUITEMINFOA);
619 mii.fMask = MIIM_SUBMENU|MIIM_DATA;
621 for (i = 0; i < GetMenuItemCount( hmenu ); i++)
622 { GetMenuItemInfoA(hmenu, i, TRUE, &mii );
625 SHFree((LPFMINFO)mii.dwItemData);
628 FileMenu_Destroy(mii.hSubMenu);
631 while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
633 menudata = FM_GetMenuInfo(hmenu);
635 menudata->bInitialized = FALSE;
640 /*************************************************************************
641 * FileMenu_DeleteItemByCmd [SHELL32.]
644 BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
648 TRACE("0x%08x 0x%08x\n", hMenu, uID);
650 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
651 mii.cbSize = sizeof(MENUITEMINFOA);
652 mii.fMask = MIIM_SUBMENU;
654 GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
657 DeleteMenu(hMenu, MF_BYCOMMAND, uID);
661 /*************************************************************************
662 * FileMenu_DeleteItemByIndex [SHELL32.140]
664 BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
668 TRACE("0x%08x 0x%08x\n", hMenu, uPos);
670 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
671 mii.cbSize = sizeof(MENUITEMINFOA);
672 mii.fMask = MIIM_SUBMENU;
674 GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
677 DeleteMenu(hMenu, MF_BYPOSITION, uPos);
681 /*************************************************************************
682 * FileMenu_DeleteItemByFirstID [SHELL32.141]
684 BOOL WINAPI FileMenu_DeleteItemByFirstID(
688 TRACE("0x%08x 0x%08x\n", hMenu, uID);
692 /*************************************************************************
693 * FileMenu_DeleteSeparator [SHELL32.142]
695 BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu)
697 TRACE("0x%08x\n", hMenu);
701 /*************************************************************************
702 * FileMenu_EnableItemByCmd [SHELL32.143]
704 BOOL WINAPI FileMenu_EnableItemByCmd(
709 TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
713 /*************************************************************************
714 * FileMenu_GetItemExtent [SHELL32.144]
717 * if the menu is to big, entrys are getting cut away!!
719 DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos)
722 FIXME("0x%08x 0x%08x\n", hMenu, uPos);
724 if (GetMenuItemRect(0, hMenu, uPos, &rect))
725 { FIXME("0x%04x 0x%04x 0x%04x 0x%04x\n",
726 rect.right, rect.left, rect.top, rect.bottom);
727 return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom);
729 return 0x00100010; /*fixme*/
732 /*************************************************************************
733 * FileMenu_AbortInitMenu [SHELL32.120]
736 void WINAPI FileMenu_AbortInitMenu (void)
741 /*************************************************************************
742 * SHFind_InitMenuPopup [SHELL32.149]
746 * hMenu [in] handel of menu previously created
747 * hWndParent [in] parent window
751 HRESULT WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, DWORD w, DWORD x)
752 { FIXME("hmenu=0x%08x hwnd=0x%08x 0x%08lx 0x%08lx stub\n",
753 hMenu,hWndParent,w,x);
757 /*************************************************************************
758 * Shell_MergeMenus [SHELL32.67]
761 BOOL _SHIsMenuSeparator(HMENU hm, int i)
765 mii.cbSize = sizeof(MENUITEMINFOA);
766 mii.fMask = MIIM_TYPE;
767 mii.cch = 0; /* WARNING: We MUST initialize it to 0*/
768 if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
773 if (mii.fType & MFT_SEPARATOR)
781 HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
784 BOOL bAlreadySeparated;
785 MENUITEMINFOA miiSrc;
787 UINT uTemp, uIDMax = uIDAdjust;
789 TRACE("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x 0x%04lx\n",
790 hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
792 if (!hmDst || !hmSrc)
796 nItem = GetMenuItemCount(hmDst);
798 if (uInsert >= (UINT)nItem) /* insert position inside menu? */
800 uInsert = (UINT)nItem; /* append on the end */
801 bAlreadySeparated = TRUE;
805 bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
808 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
810 /* Add a separator between the menus */
811 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
812 bAlreadySeparated = TRUE;
816 /* Go through the menu items and clone them*/
817 for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
819 miiSrc.cbSize = sizeof(MENUITEMINFOA);
820 miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
822 /* We need to reset this every time through the loop in case menus DON'T have IDs*/
823 miiSrc.fType = MFT_STRING;
824 miiSrc.dwTypeData = szName;
825 miiSrc.dwItemData = 0;
826 miiSrc.cch = sizeof(szName);
828 if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
833 /* 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);
835 if (miiSrc.fType & MFT_SEPARATOR)
837 /* This is a separator; don't put two of them in a row */
838 if (bAlreadySeparated)
841 bAlreadySeparated = TRUE;
843 else if (miiSrc.hSubMenu)
845 if (uFlags & MM_SUBMENUSHAVEIDS)
847 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
849 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
852 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
853 uIDMax = miiSrc.wID + 1;
857 miiSrc.fMask &= ~MIIM_ID; /* Don't set IDs for submenus that didn't have them already */
859 hmSubMenu = miiSrc.hSubMenu;
861 miiSrc.hSubMenu = CreatePopupMenu();
863 if (!miiSrc.hSubMenu) return(uIDMax);
865 uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS);
870 bAlreadySeparated = FALSE;
872 else /* normal menu item */
874 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
876 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
879 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
880 uIDMax = miiSrc.wID + 1;
882 bAlreadySeparated = FALSE;
885 /* 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);
887 if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
893 /* Ensure the correct number of separators at the beginning of the
894 inserted menu items*/
897 if (bAlreadySeparated)
899 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
904 if (_SHIsMenuSeparator(hmDst, uInsert-1))
906 if (bAlreadySeparated)
908 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
913 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
915 /* Add a separator between the menus*/
916 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);