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 "winversion.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);
357 BOOL WINAPI FileMenu_AppendItemAW(
368 if (VERSION_OsIsUnicode() && (lpText!=FM_SEPARATOR))
369 lpszText = HEAP_strdupWtoA ( GetProcessHeap(),0, lpText);
371 ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : lpText, uID, icon, hMenuPopup, nItemHeight);
374 HeapFree( GetProcessHeap(), 0, lpszText );
378 /*************************************************************************
379 * FileMenu_InsertUsingPidl [SHELL32.110]
382 * uEnumFlags any SHCONTF flag
384 int WINAPI FileMenu_InsertUsingPidl (
390 LPFNFMCALLBACK lpfnCallback)
392 TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
393 hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
399 FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
401 return FM_InitMenuPopup(hmenu, NULL);
404 /*************************************************************************
405 * FileMenu_ReplaceUsingPidl [SHELL32.113]
407 * FIXME: the static items are deleted but wont be refreshed
409 int WINAPI FileMenu_ReplaceUsingPidl(
414 LPFNFMCALLBACK lpfnCallback)
416 TRACE("0x%08x 0x%08x %p 0x%08x %p\n",
417 hmenu, uID, pidl, uEnumFlags, lpfnCallback);
419 FileMenu_DeleteAllItems (hmenu);
421 FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback);
423 return FM_InitMenuPopup(hmenu, NULL);
426 /*************************************************************************
427 * FileMenu_Invalidate [SHELL32.111]
429 void WINAPI FileMenu_Invalidate (HMENU hMenu)
431 FIXME("0x%08x\n",hMenu);
434 /*************************************************************************
435 * FileMenu_FindSubMenuByPidl [SHELL32.106]
437 HMENU WINAPI FileMenu_FindSubMenuByPidl(
441 FIXME("0x%08x %p\n",hMenu, pidl);
445 /*************************************************************************
446 * FileMenu_AppendFilesForPidl [SHELL32.124]
448 int WINAPI FileMenu_AppendFilesForPidl(
455 menudata = FM_GetMenuInfo(hmenu);
457 menudata->bInitialized = FALSE;
459 FM_InitMenuPopup(hmenu, pidl);
462 FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
464 TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator);
468 /*************************************************************************
469 * FileMenu_AddFilesForPidl [SHELL32.125]
472 * uEnumFlags any SHCONTF flag
474 int WINAPI FileMenu_AddFilesForPidl (
481 LPFNFMCALLBACK lpfnCallback)
483 TRACE("0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
484 hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
486 return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
491 /*************************************************************************
492 * FileMenu_TrackPopupMenuEx [SHELL32.116]
494 BOOL WINAPI FileMenu_TrackPopupMenuEx (
502 TRACE("0x%08x 0x%08x 0x%x 0x%x 0x%08x %p\n",
503 hMenu, uFlags, x, y, hWnd, lptpm);
504 return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm);
507 /*************************************************************************
508 * FileMenu_GetLastSelectedItemPidls [SHELL32.107]
510 BOOL WINAPI FileMenu_GetLastSelectedItemPidls(
512 LPCITEMIDLIST *ppidlFolder,
513 LPCITEMIDLIST *ppidlItem)
515 FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
519 #define FM_ICON_SIZE 16
523 #define FM_LEFTBORDER 2
524 #define FM_RIGHTBORDER 8
525 /*************************************************************************
526 * FileMenu_MeasureItem [SHELL32.112]
528 LRESULT WINAPI FileMenu_MeasureItem(
530 LPMEASUREITEMSTRUCT lpmis)
532 LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
533 HDC hdc = GetDC(hWnd);
537 TRACE("0x%08x %p %s\n", hWnd, lpmis, pMyItem->szItemText);
539 GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
541 lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER;
542 lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE);
544 /* add the menubitmap */
545 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
546 if (menuinfo->nBorderWidth)
547 lpmis->itemWidth += menuinfo->nBorderWidth;
549 TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight);
550 ReleaseDC (hWnd, hdc);
553 /*************************************************************************
554 * FileMenu_DrawItem [SHELL32.105]
556 LRESULT WINAPI FileMenu_DrawItem(
558 LPDRAWITEMSTRUCT lpdis)
560 LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData);
561 COLORREF clrPrevText, clrPrevBkgnd;
563 HIMAGELIST hImageList;
564 RECT TextRect, BorderRect;
567 TRACE("0x%08x %p %s\n", hWnd, lpdis, pMyItem->szItemText);
569 if (lpdis->itemState & ODS_SELECTED)
571 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
572 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
576 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT));
577 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU));
580 CopyRect(&TextRect, &(lpdis->rcItem));
582 /* add the menubitmap */
583 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
584 if (menuinfo->nBorderWidth)
585 TextRect.left += menuinfo->nBorderWidth;
587 BorderRect.right = menuinfo->nBorderWidth;
588 /* FillRect(lpdis->hDC, &BorderRect, CreateSolidBrush( menuinfo->crBorderColor));
590 TextRect.left += FM_LEFTBORDER;
591 xi = TextRect.left + FM_SPACE1;
592 yi = TextRect.top + FM_Y_SPACE/2;
593 TextRect.bottom -= FM_Y_SPACE/2;
595 xt = xi + FM_ICON_SIZE + FM_SPACE2;
598 ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
600 Shell_GetImageList(0, &hImageList);
601 pImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
603 TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom);
605 SetTextColor(lpdis->hDC, clrPrevText);
606 SetBkColor(lpdis->hDC, clrPrevBkgnd);
611 /*************************************************************************
612 * FileMenu_InitMenuPopup [SHELL32.109]
615 * The filemenu is a ownerdrawn menu. Call this function responding to
619 BOOL WINAPI FileMenu_InitMenuPopup (HMENU hmenu)
621 FM_InitMenuPopup(hmenu, NULL);
625 /*************************************************************************
626 * FileMenu_HandleMenuChar [SHELL32.108]
628 LRESULT WINAPI FileMenu_HandleMenuChar(
632 FIXME("0x%08x 0x%08x\n",hMenu,wParam);
636 /*************************************************************************
637 * FileMenu_DeleteAllItems [SHELL32.104]
642 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
649 TRACE("0x%08x\n", hmenu);
651 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
652 mii.cbSize = sizeof(MENUITEMINFOA);
653 mii.fMask = MIIM_SUBMENU|MIIM_DATA;
655 for (i = 0; i < GetMenuItemCount( hmenu ); i++)
656 { GetMenuItemInfoA(hmenu, i, TRUE, &mii );
659 SHFree((LPFMINFO)mii.dwItemData);
662 FileMenu_Destroy(mii.hSubMenu);
665 while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
667 menudata = FM_GetMenuInfo(hmenu);
669 menudata->bInitialized = FALSE;
674 /*************************************************************************
675 * FileMenu_DeleteItemByCmd [SHELL32.]
678 BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
682 TRACE("0x%08x 0x%08x\n", hMenu, uID);
684 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
685 mii.cbSize = sizeof(MENUITEMINFOA);
686 mii.fMask = MIIM_SUBMENU;
688 GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
691 DeleteMenu(hMenu, MF_BYCOMMAND, uID);
695 /*************************************************************************
696 * FileMenu_DeleteItemByIndex [SHELL32.140]
698 BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
702 TRACE("0x%08x 0x%08x\n", hMenu, uPos);
704 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
705 mii.cbSize = sizeof(MENUITEMINFOA);
706 mii.fMask = MIIM_SUBMENU;
708 GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
711 DeleteMenu(hMenu, MF_BYPOSITION, uPos);
715 /*************************************************************************
716 * FileMenu_DeleteItemByFirstID [SHELL32.141]
718 BOOL WINAPI FileMenu_DeleteItemByFirstID(
722 TRACE("0x%08x 0x%08x\n", hMenu, uID);
726 /*************************************************************************
727 * FileMenu_DeleteSeparator [SHELL32.142]
729 BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu)
731 TRACE("0x%08x\n", hMenu);
735 /*************************************************************************
736 * FileMenu_EnableItemByCmd [SHELL32.143]
738 BOOL WINAPI FileMenu_EnableItemByCmd(
743 TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
747 /*************************************************************************
748 * FileMenu_GetItemExtent [SHELL32.144]
751 * if the menu is to big, entrys are getting cut away!!
753 DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos)
756 FIXME("0x%08x 0x%08x\n", hMenu, uPos);
758 if (GetMenuItemRect(0, hMenu, uPos, &rect))
759 { FIXME("0x%04x 0x%04x 0x%04x 0x%04x\n",
760 rect.right, rect.left, rect.top, rect.bottom);
761 return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom);
763 return 0x00100010; /*fixme*/
766 /*************************************************************************
767 * FileMenu_AbortInitMenu [SHELL32.120]
770 void WINAPI FileMenu_AbortInitMenu (void)
775 /*************************************************************************
776 * SHFind_InitMenuPopup [SHELL32.149]
780 * hMenu [in] handle of menu previously created
781 * hWndParent [in] parent window
782 * w [in] no pointer (0x209 over here) perhaps menu IDs ???
783 * x [in] no pointer (0x226 over here)
786 * LPXXXXX pointer to struct containing a func addr at offset 8
787 * or NULL at failure.
789 LPVOID WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, DWORD w, DWORD x)
790 { FIXME("hmenu=0x%08x hwnd=0x%08x 0x%08lx 0x%08lx stub\n",
791 hMenu,hWndParent,w,x);
792 return NULL; /* this is supposed to be a pointer */
795 /*************************************************************************
796 * Shell_MergeMenus [SHELL32.67]
799 BOOL _SHIsMenuSeparator(HMENU hm, int i)
803 mii.cbSize = sizeof(MENUITEMINFOA);
804 mii.fMask = MIIM_TYPE;
805 mii.cch = 0; /* WARNING: We MUST initialize it to 0*/
806 if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
811 if (mii.fType & MFT_SEPARATOR)
819 HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
822 BOOL bAlreadySeparated;
823 MENUITEMINFOA miiSrc;
825 UINT uTemp, uIDMax = uIDAdjust;
827 TRACE("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x 0x%04lx\n",
828 hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
830 if (!hmDst || !hmSrc)
834 nItem = GetMenuItemCount(hmDst);
836 if (uInsert >= (UINT)nItem) /* insert position inside menu? */
838 uInsert = (UINT)nItem; /* append on the end */
839 bAlreadySeparated = TRUE;
843 bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
846 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
848 /* Add a separator between the menus */
849 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
850 bAlreadySeparated = TRUE;
854 /* Go through the menu items and clone them*/
855 for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
857 miiSrc.cbSize = sizeof(MENUITEMINFOA);
858 miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
860 /* We need to reset this every time through the loop in case menus DON'T have IDs*/
861 miiSrc.fType = MFT_STRING;
862 miiSrc.dwTypeData = szName;
863 miiSrc.dwItemData = 0;
864 miiSrc.cch = sizeof(szName);
866 if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
871 /* 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);
873 if (miiSrc.fType & MFT_SEPARATOR)
875 /* This is a separator; don't put two of them in a row */
876 if (bAlreadySeparated)
879 bAlreadySeparated = TRUE;
881 else if (miiSrc.hSubMenu)
883 if (uFlags & MM_SUBMENUSHAVEIDS)
885 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
887 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
890 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
891 uIDMax = miiSrc.wID + 1;
895 miiSrc.fMask &= ~MIIM_ID; /* Don't set IDs for submenus that didn't have them already */
897 hmSubMenu = miiSrc.hSubMenu;
899 miiSrc.hSubMenu = CreatePopupMenu();
901 if (!miiSrc.hSubMenu) return(uIDMax);
903 uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS);
908 bAlreadySeparated = FALSE;
910 else /* normal menu item */
912 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
914 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
917 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
918 uIDMax = miiSrc.wID + 1;
920 bAlreadySeparated = FALSE;
923 /* 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);
925 if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
931 /* Ensure the correct number of separators at the beginning of the
932 inserted menu items*/
935 if (bAlreadySeparated)
937 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
942 if (_SHIsMenuSeparator(hmDst, uInsert-1))
944 if (bAlreadySeparated)
946 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
951 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
953 /* Add a separator between the menus*/
954 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);