2 * see www.geocities.com/SiliconValley/4942/filemenu.html
6 #include "wine/obj_base.h"
7 #include "wine/obj_enumidlist.h"
8 #include "wine/obj_shellfolder.h"
9 #include "wine/undocshell.h"
12 #include "debugtools.h"
13 #include "shell32_main.h"
18 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hMenu);
19 BOOL WINAPI FileMenu_AppendItemA(HMENU hMenu, LPCSTR lpText, UINT uID, int icon, HMENU hMenuPopup, int nItemHeight);
26 COLORREF crBorderColor;
30 /* insert using pidl */
35 LPFNFMCALLBACK lpfnCallback;
45 static BOOL bAbortInit;
47 #define CCH_MAXITEMTEXT 256
49 DEFAULT_DEBUG_CHANNEL(shell)
51 LPFMINFO FM_GetMenuInfo(HMENU hmenu)
55 MenuInfo.cbSize = sizeof(MENUINFO);
56 MenuInfo.fMask = MIM_MENUDATA;
58 if (! GetMenuInfo(hmenu, &MenuInfo))
61 menudata = (LPFMINFO)MenuInfo.dwMenuData;
63 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
65 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
72 /*************************************************************************
73 * FM_SetMenuParameter [internal]
76 static LPFMINFO FM_SetMenuParameter(
82 LPFNFMCALLBACK lpfnCallback)
88 menudata = FM_GetMenuInfo(hmenu);
91 { SHFree(menudata->pidl);
95 menudata->pidl = ILClone(pidl);
96 menudata->uFlags = uFlags;
97 menudata->uEnumFlags = uEnumFlags;
98 menudata->lpfnCallback = lpfnCallback;
103 /*************************************************************************
104 * FM_InitMenuPopup [internal]
107 static int FM_InitMenuPopup(HMENU hmenu, LPITEMIDLIST pAlternatePidl)
108 { IShellFolder *lpsf, *lpsf2;
109 ULONG ulItemAttr = SFGAO_FOLDER;
110 UINT uID, uFlags, uEnumFlags;
111 LPFNFMCALLBACK lpfnCallback;
113 char sTemp[MAX_PATH];
114 int NumberOfItems = 0, iIcon;
118 TRACE("0x%04x %p\n", hmenu, pAlternatePidl);
120 MenuInfo.cbSize = sizeof(MENUINFO);
121 MenuInfo.fMask = MIM_MENUDATA;
123 if (! GetMenuInfo(hmenu, &MenuInfo))
126 menudata = (LPFMINFO)MenuInfo.dwMenuData;
128 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
130 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
134 if (menudata->bInitialized)
137 pidl = ((pAlternatePidl) ? pAlternatePidl : menudata->pidl);
142 uFlags = menudata->uFlags;
143 uEnumFlags = menudata->uEnumFlags;
144 lpfnCallback = menudata->lpfnCallback;
145 menudata->bInitialized = FALSE;
147 SetMenuInfo(hmenu, &MenuInfo);
149 if (SUCCEEDED (SHGetDesktopFolder(&lpsf)))
151 if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
153 IEnumIDList *lpe = NULL;
155 if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe )))
158 LPITEMIDLIST pidlTemp = NULL;
161 while ((!bAbortInit) && (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched)))
163 if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr)))
165 ILGetDisplayName( pidlTemp, sTemp);
166 if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, 0, &iIcon)))
167 iIcon = FM_BLANK_ICON;
168 if ( SFGAO_FOLDER & ulItemAttr)
172 HMENU hMenuPopup = CreatePopupMenu();
174 lpFmMi = (LPFMINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
176 lpFmMi->pidl = ILCombine(pidl, pidlTemp);
177 lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
179 MenuInfo.cbSize = sizeof(MENUINFO);
180 MenuInfo.fMask = MIM_MENUDATA;
181 MenuInfo.dwMenuData = (DWORD) lpFmMi;
182 SetMenuInfo (hMenuPopup, &MenuInfo);
184 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
188 ((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
189 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
195 TRACE("enter callback\n");
196 lpfnCallback ( pidl, pidlTemp);
197 TRACE("leave callback\n");
202 IEnumIDList_Release (lpe);
204 IShellFolder_Release(lpsf2);
206 IShellFolder_Release(lpsf);
209 if ( GetMenuItemCount (hmenu) == 0 )
210 { FileMenu_AppendItemA (hmenu, "(empty)", uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
214 menudata->bInitialized = TRUE;
215 SetMenuInfo(hmenu, &MenuInfo);
217 return NumberOfItems;
219 /*************************************************************************
220 * FileMenu_Create [SHELL32.114]
223 * for non-root menus values are
224 * (ffffffff,00000000,00000000,00000000,00000000)
226 HMENU WINAPI FileMenu_Create (
227 COLORREF crBorderColor,
236 HMENU hMenu = CreatePopupMenu();
238 TRACE("0x%08lx 0x%08x 0x%08x 0x%08x 0x%08x hMenu=0x%08x\n",
239 crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, hMenu);
241 menudata = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
242 menudata->crBorderColor = crBorderColor;
243 menudata->nBorderWidth = nBorderWidth;
244 menudata->hBorderBmp = hBorderBmp;
246 MenuInfo.cbSize = sizeof(MENUINFO);
247 MenuInfo.fMask = MIM_MENUDATA;
248 MenuInfo.dwMenuData = (DWORD) menudata;
249 SetMenuInfo (hMenu, &MenuInfo);
254 /*************************************************************************
255 * FileMenu_Destroy [SHELL32.118]
260 void WINAPI FileMenu_Destroy (HMENU hmenu)
264 TRACE("0x%08x\n", hmenu);
266 FileMenu_DeleteAllItems (hmenu);
268 menudata = FM_GetMenuInfo(hmenu);
271 { SHFree( menudata->pidl);
273 HeapFree(GetProcessHeap(), 0, menudata);
278 /*************************************************************************
279 * FileMenu_AppendItemAW [SHELL32.115]
282 BOOL WINAPI FileMenu_AppendItemA(
290 LPSTR lpszText = (LPSTR)lpText;
297 TRACE("0x%08x %s 0x%08x 0x%08x 0x%08x 0x%08x\n",
298 hMenu, (lpszText!=FM_SEPARATOR) ? lpText: NULL,
299 uID, icon, hMenuPopup, nItemHeight);
301 ZeroMemory (&mii, sizeof(MENUITEMINFOA));
303 mii.cbSize = sizeof(MENUITEMINFOA);
305 if (lpText != FM_SEPARATOR)
306 { int len = strlen (lpText);
307 myItem = (LPFMITEM) SHAlloc( sizeof(FMITEM) + len);
308 strcpy (myItem->szItemText, lpText);
309 myItem->cchItemText = len;
310 myItem->iIconIndex = icon;
311 myItem->hMenu = hMenu;
312 mii.fMask = MIIM_DATA;
313 mii.dwItemData = (DWORD) myItem;
318 mii.fMask |= MIIM_TYPE | MIIM_SUBMENU;
319 mii.fType = MFT_OWNERDRAW;
320 mii.hSubMenu = hMenuPopup;
322 else if (lpText == FM_SEPARATOR )
323 { mii.fMask |= MIIM_ID | MIIM_TYPE;
324 mii.fType = MFT_SEPARATOR;
328 mii.fMask |= MIIM_ID | MIIM_TYPE | MIIM_STATE;
329 mii.fState = MFS_ENABLED | MFS_DEFAULT;
330 mii.fType = MFT_OWNERDRAW;
334 InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
336 /* set bFixedItems to true */
337 MenuInfo.cbSize = sizeof(MENUINFO);
338 MenuInfo.fMask = MIM_MENUDATA;
340 if (! GetMenuInfo(hMenu, &MenuInfo))
343 menudata = (LPFMINFO)MenuInfo.dwMenuData;
344 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
346 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
350 menudata->bFixedItems = TRUE;
351 SetMenuInfo(hMenu, &MenuInfo);
356 BOOL WINAPI FileMenu_AppendItemAW(
367 if (SHELL_OsIsUnicode() && (lpText!=FM_SEPARATOR))
368 lpszText = HEAP_strdupWtoA ( GetProcessHeap(),0, lpText);
370 ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : lpText, uID, icon, hMenuPopup, nItemHeight);
373 HeapFree( GetProcessHeap(), 0, lpszText );
377 /*************************************************************************
378 * FileMenu_InsertUsingPidl [SHELL32.110]
381 * uEnumFlags any SHCONTF flag
383 int WINAPI FileMenu_InsertUsingPidl (
389 LPFNFMCALLBACK lpfnCallback)
391 TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
392 hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
398 FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
400 return FM_InitMenuPopup(hmenu, NULL);
403 /*************************************************************************
404 * FileMenu_ReplaceUsingPidl [SHELL32.113]
406 * FIXME: the static items are deleted but wont be refreshed
408 int WINAPI FileMenu_ReplaceUsingPidl(
413 LPFNFMCALLBACK lpfnCallback)
415 TRACE("0x%08x 0x%08x %p 0x%08x %p\n",
416 hmenu, uID, pidl, uEnumFlags, lpfnCallback);
418 FileMenu_DeleteAllItems (hmenu);
420 FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback);
422 return FM_InitMenuPopup(hmenu, NULL);
425 /*************************************************************************
426 * FileMenu_Invalidate [SHELL32.111]
428 void WINAPI FileMenu_Invalidate (HMENU hMenu)
430 FIXME("0x%08x\n",hMenu);
433 /*************************************************************************
434 * FileMenu_FindSubMenuByPidl [SHELL32.106]
436 HMENU WINAPI FileMenu_FindSubMenuByPidl(
440 FIXME("0x%08x %p\n",hMenu, pidl);
444 /*************************************************************************
445 * FileMenu_AppendFilesForPidl [SHELL32.124]
447 int WINAPI FileMenu_AppendFilesForPidl(
454 menudata = FM_GetMenuInfo(hmenu);
456 menudata->bInitialized = FALSE;
458 FM_InitMenuPopup(hmenu, pidl);
461 FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
463 TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator);
467 /*************************************************************************
468 * FileMenu_AddFilesForPidl [SHELL32.125]
471 * uEnumFlags any SHCONTF flag
473 int WINAPI FileMenu_AddFilesForPidl (
480 LPFNFMCALLBACK lpfnCallback)
482 TRACE("0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
483 hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
485 return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
490 /*************************************************************************
491 * FileMenu_TrackPopupMenuEx [SHELL32.116]
493 BOOL WINAPI FileMenu_TrackPopupMenuEx (
501 TRACE("0x%08x 0x%08x 0x%x 0x%x 0x%08x %p\n",
502 hMenu, uFlags, x, y, hWnd, lptpm);
503 return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm);
506 /*************************************************************************
507 * FileMenu_GetLastSelectedItemPidls [SHELL32.107]
509 BOOL WINAPI FileMenu_GetLastSelectedItemPidls(
511 LPCITEMIDLIST *ppidlFolder,
512 LPCITEMIDLIST *ppidlItem)
514 FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
518 #define FM_ICON_SIZE 16
522 #define FM_LEFTBORDER 2
523 #define FM_RIGHTBORDER 8
524 /*************************************************************************
525 * FileMenu_MeasureItem [SHELL32.112]
527 LRESULT WINAPI FileMenu_MeasureItem(
529 LPMEASUREITEMSTRUCT lpmis)
531 LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
532 HDC hdc = GetDC(hWnd);
536 TRACE("0x%08x %p %s\n", hWnd, lpmis, pMyItem->szItemText);
538 GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
540 lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER;
541 lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE);
543 /* add the menubitmap */
544 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
545 if (menuinfo->nBorderWidth)
546 lpmis->itemWidth += menuinfo->nBorderWidth;
548 TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight);
549 ReleaseDC (hWnd, hdc);
552 /*************************************************************************
553 * FileMenu_DrawItem [SHELL32.105]
555 LRESULT WINAPI FileMenu_DrawItem(
557 LPDRAWITEMSTRUCT lpdis)
559 LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData);
560 COLORREF clrPrevText, clrPrevBkgnd;
562 HIMAGELIST hImageList;
563 RECT TextRect, BorderRect;
566 TRACE("0x%08x %p %s\n", hWnd, lpdis, pMyItem->szItemText);
568 if (lpdis->itemState & ODS_SELECTED)
570 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
571 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
575 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT));
576 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU));
579 CopyRect(&TextRect, &(lpdis->rcItem));
581 /* add the menubitmap */
582 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
583 if (menuinfo->nBorderWidth)
584 TextRect.left += menuinfo->nBorderWidth;
586 BorderRect.right = menuinfo->nBorderWidth;
587 /* FillRect(lpdis->hDC, &BorderRect, CreateSolidBrush( menuinfo->crBorderColor));
589 TextRect.left += FM_LEFTBORDER;
590 xi = TextRect.left + FM_SPACE1;
591 yi = TextRect.top + FM_Y_SPACE/2;
592 TextRect.bottom -= FM_Y_SPACE/2;
594 xt = xi + FM_ICON_SIZE + FM_SPACE2;
597 ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
599 Shell_GetImageList(0, &hImageList);
600 pImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
602 TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom);
604 SetTextColor(lpdis->hDC, clrPrevText);
605 SetBkColor(lpdis->hDC, clrPrevBkgnd);
610 /*************************************************************************
611 * FileMenu_InitMenuPopup [SHELL32.109]
614 * The filemenu is a ownerdrawn menu. Call this function responding to
618 BOOL WINAPI FileMenu_InitMenuPopup (HMENU hmenu)
620 FM_InitMenuPopup(hmenu, NULL);
624 /*************************************************************************
625 * FileMenu_HandleMenuChar [SHELL32.108]
627 LRESULT WINAPI FileMenu_HandleMenuChar(
631 FIXME("0x%08x 0x%08x\n",hMenu,wParam);
635 /*************************************************************************
636 * FileMenu_DeleteAllItems [SHELL32.104]
641 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
648 TRACE("0x%08x\n", hmenu);
650 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
651 mii.cbSize = sizeof(MENUITEMINFOA);
652 mii.fMask = MIIM_SUBMENU|MIIM_DATA;
654 for (i = 0; i < GetMenuItemCount( hmenu ); i++)
655 { GetMenuItemInfoA(hmenu, i, TRUE, &mii );
658 SHFree((LPFMINFO)mii.dwItemData);
661 FileMenu_Destroy(mii.hSubMenu);
664 while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
666 menudata = FM_GetMenuInfo(hmenu);
668 menudata->bInitialized = FALSE;
673 /*************************************************************************
674 * FileMenu_DeleteItemByCmd [SHELL32.]
677 BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
681 TRACE("0x%08x 0x%08x\n", hMenu, uID);
683 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
684 mii.cbSize = sizeof(MENUITEMINFOA);
685 mii.fMask = MIIM_SUBMENU;
687 GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
690 DeleteMenu(hMenu, MF_BYCOMMAND, uID);
694 /*************************************************************************
695 * FileMenu_DeleteItemByIndex [SHELL32.140]
697 BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
701 TRACE("0x%08x 0x%08x\n", hMenu, uPos);
703 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
704 mii.cbSize = sizeof(MENUITEMINFOA);
705 mii.fMask = MIIM_SUBMENU;
707 GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
710 DeleteMenu(hMenu, MF_BYPOSITION, uPos);
714 /*************************************************************************
715 * FileMenu_DeleteItemByFirstID [SHELL32.141]
717 BOOL WINAPI FileMenu_DeleteItemByFirstID(
721 TRACE("0x%08x 0x%08x\n", hMenu, uID);
725 /*************************************************************************
726 * FileMenu_DeleteSeparator [SHELL32.142]
728 BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu)
730 TRACE("0x%08x\n", hMenu);
734 /*************************************************************************
735 * FileMenu_EnableItemByCmd [SHELL32.143]
737 BOOL WINAPI FileMenu_EnableItemByCmd(
742 TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
746 /*************************************************************************
747 * FileMenu_GetItemExtent [SHELL32.144]
750 * if the menu is to big, entrys are getting cut away!!
752 DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos)
755 FIXME("0x%08x 0x%08x\n", hMenu, uPos);
757 if (GetMenuItemRect(0, hMenu, uPos, &rect))
758 { FIXME("0x%04x 0x%04x 0x%04x 0x%04x\n",
759 rect.right, rect.left, rect.top, rect.bottom);
760 return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom);
762 return 0x00100010; /*fixme*/
765 /*************************************************************************
766 * FileMenu_AbortInitMenu [SHELL32.120]
769 void WINAPI FileMenu_AbortInitMenu (void)
774 /*************************************************************************
775 * SHFind_InitMenuPopup [SHELL32.149]
779 * hMenu [in] handle of menu previously created
780 * hWndParent [in] parent window
781 * w [in] no pointer (0x209 over here) perhaps menu IDs ???
782 * x [in] no pointer (0x226 over here)
785 * LPXXXXX pointer to struct containing a func addr at offset 8
786 * or NULL at failure.
788 LPVOID WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, DWORD w, DWORD x)
789 { FIXME("hmenu=0x%08x hwnd=0x%08x 0x%08lx 0x%08lx stub\n",
790 hMenu,hWndParent,w,x);
791 return NULL; /* this is supposed to be a pointer */
794 /*************************************************************************
795 * Shell_MergeMenus [SHELL32.67]
798 BOOL _SHIsMenuSeparator(HMENU hm, int i)
802 mii.cbSize = sizeof(MENUITEMINFOA);
803 mii.fMask = MIIM_TYPE;
804 mii.cch = 0; /* WARNING: We MUST initialize it to 0*/
805 if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
810 if (mii.fType & MFT_SEPARATOR)
818 HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
821 BOOL bAlreadySeparated;
822 MENUITEMINFOA miiSrc;
824 UINT uTemp, uIDMax = uIDAdjust;
826 TRACE("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x 0x%04lx\n",
827 hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
829 if (!hmDst || !hmSrc)
833 nItem = GetMenuItemCount(hmDst);
835 if (uInsert >= (UINT)nItem) /* insert position inside menu? */
837 uInsert = (UINT)nItem; /* append on the end */
838 bAlreadySeparated = TRUE;
842 bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
845 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
847 /* Add a separator between the menus */
848 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
849 bAlreadySeparated = TRUE;
853 /* Go through the menu items and clone them*/
854 for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
856 miiSrc.cbSize = sizeof(MENUITEMINFOA);
857 miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
859 /* We need to reset this every time through the loop in case menus DON'T have IDs*/
860 miiSrc.fType = MFT_STRING;
861 miiSrc.dwTypeData = szName;
862 miiSrc.dwItemData = 0;
863 miiSrc.cch = sizeof(szName);
865 if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
870 /* 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);
872 if (miiSrc.fType & MFT_SEPARATOR)
874 /* This is a separator; don't put two of them in a row */
875 if (bAlreadySeparated)
878 bAlreadySeparated = TRUE;
880 else if (miiSrc.hSubMenu)
882 if (uFlags & MM_SUBMENUSHAVEIDS)
884 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
886 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
889 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
890 uIDMax = miiSrc.wID + 1;
894 miiSrc.fMask &= ~MIIM_ID; /* Don't set IDs for submenus that didn't have them already */
896 hmSubMenu = miiSrc.hSubMenu;
898 miiSrc.hSubMenu = CreatePopupMenu();
900 if (!miiSrc.hSubMenu) return(uIDMax);
902 uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS);
907 bAlreadySeparated = FALSE;
909 else /* normal menu item */
911 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
913 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
916 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
917 uIDMax = miiSrc.wID + 1;
919 bAlreadySeparated = FALSE;
922 /* 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);
924 if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
930 /* Ensure the correct number of separators at the beginning of the
931 inserted menu items*/
934 if (bAlreadySeparated)
936 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
941 if (_SHIsMenuSeparator(hmDst, uInsert-1))
943 if (bAlreadySeparated)
945 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
950 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
952 /* Add a separator between the menus*/
953 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);