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)
130 pidl = ((pAlternatePidl) ? pAlternatePidl : menudata->pidl);
135 uFlags = menudata->uFlags;
136 uEnumFlags = menudata->uEnumFlags;
137 lpfnCallback = menudata->lpfnCallback;
138 menudata->bInitialized = FALSE;
140 SetMenuInfo(hmenu, &MenuInfo);
142 if (SUCCEEDED (SHGetDesktopFolder(&lpsf)))
144 if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
146 IEnumIDList *lpe = NULL;
148 if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe )))
151 LPITEMIDLIST pidlTemp = NULL;
154 while ((!bAbortInit) && (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched)))
156 if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr)))
158 ILGetDisplayName( pidlTemp, sTemp);
159 if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, &iIcon)))
160 iIcon = FM_BLANK_ICON;
161 if ( SFGAO_FOLDER & ulItemAttr)
165 HMENU hMenuPopup = CreatePopupMenu();
167 lpFmMi = (LPFMINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
169 lpFmMi->pidl = ILCombine(pidl, pidlTemp);
170 lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
172 MenuInfo.cbSize = sizeof(MENUINFO);
173 MenuInfo.fMask = MIM_MENUDATA;
174 MenuInfo.dwMenuData = (DWORD) lpFmMi;
175 SetMenuInfo (hMenuPopup, &MenuInfo);
177 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
181 ((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
182 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
188 TRACE("enter callback\n");
189 lpfnCallback ( pidl, pidlTemp);
190 TRACE("leave callback\n");
195 IEnumIDList_Release (lpe);
197 IShellFolder_Release(lpsf2);
199 IShellFolder_Release(lpsf);
202 if ( GetMenuItemCount (hmenu) == 0 )
203 { FileMenu_AppendItemA (hmenu, "(empty)", uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
207 menudata->bInitialized = TRUE;
208 SetMenuInfo(hmenu, &MenuInfo);
210 return NumberOfItems;
212 /*************************************************************************
213 * FileMenu_Create [SHELL32.114]
216 * for non-root menus values are
217 * (ffffffff,00000000,00000000,00000000,00000000)
219 HMENU WINAPI FileMenu_Create (
220 COLORREF crBorderColor,
229 HMENU hMenu = CreatePopupMenu();
231 TRACE("0x%08lx 0x%08x 0x%08x 0x%08x 0x%08x hMenu=0x%08x\n",
232 crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, hMenu);
234 menudata = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
235 menudata->crBorderColor = crBorderColor;
236 menudata->nBorderWidth = nBorderWidth;
237 menudata->hBorderBmp = hBorderBmp;
239 MenuInfo.cbSize = sizeof(MENUINFO);
240 MenuInfo.fMask = MIM_MENUDATA;
241 MenuInfo.dwMenuData = (DWORD) menudata;
242 SetMenuInfo (hMenu, &MenuInfo);
247 /*************************************************************************
248 * FileMenu_Destroy [SHELL32.118]
253 void WINAPI FileMenu_Destroy (HMENU hmenu)
257 TRACE("0x%08x\n", hmenu);
259 FileMenu_DeleteAllItems (hmenu);
261 menudata = FM_GetMenuInfo(hmenu);
264 { SHFree( menudata->pidl);
266 HeapFree(GetProcessHeap(), 0, menudata);
271 /*************************************************************************
272 * FileMenu_AppendItemAW [SHELL32.115]
275 BOOL WINAPI FileMenu_AppendItemA(
283 LPSTR lpszText = (LPSTR)lpText;
290 TRACE("0x%08x %s 0x%08x 0x%08x 0x%08x 0x%08x\n",
291 hMenu, (lpszText!=FM_SEPARATOR) ? lpText: NULL,
292 uID, icon, hMenuPopup, nItemHeight);
294 ZeroMemory (&mii, sizeof(MENUITEMINFOA));
296 mii.cbSize = sizeof(MENUITEMINFOA);
298 if (lpText != FM_SEPARATOR)
299 { int len = strlen (lpText);
300 myItem = (LPFMITEM) SHAlloc( sizeof(FMITEM) + len);
301 strcpy (myItem->szItemText, lpText);
302 myItem->cchItemText = len;
303 myItem->iIconIndex = icon;
304 myItem->hMenu = hMenu;
305 mii.fMask = MIIM_DATA;
306 mii.dwItemData = (DWORD) myItem;
311 mii.fMask |= MIIM_TYPE | MIIM_SUBMENU;
312 mii.fType = MFT_OWNERDRAW;
313 mii.hSubMenu = hMenuPopup;
315 else if (lpText == FM_SEPARATOR )
316 { mii.fMask |= MIIM_ID | MIIM_TYPE;
317 mii.fType = MFT_SEPARATOR;
321 mii.fMask |= MIIM_ID | MIIM_TYPE | MIIM_STATE;
322 mii.fState = MFS_ENABLED | MFS_DEFAULT;
323 mii.fType = MFT_OWNERDRAW;
327 InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
329 /* set bFixedItems to true */
330 MenuInfo.cbSize = sizeof(MENUINFO);
331 MenuInfo.fMask = MIM_MENUDATA;
333 if (! GetMenuInfo(hMenu, &MenuInfo))
336 menudata = (LPFMINFO)MenuInfo.dwMenuData;
337 assert ((menudata != 0) && (MenuInfo.cbSize == sizeof(MENUINFO)));
338 menudata->bFixedItems = TRUE;
339 SetMenuInfo(hMenu, &MenuInfo);
344 BOOL WINAPI FileMenu_AppendItemAW(
355 if (VERSION_OsIsUnicode() && (lpText!=FM_SEPARATOR))
356 lpszText = HEAP_strdupWtoA ( GetProcessHeap(),0, lpText);
358 ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : lpText, uID, icon, hMenuPopup, nItemHeight);
361 HeapFree( GetProcessHeap(), 0, lpszText );
365 /*************************************************************************
366 * FileMenu_InsertUsingPidl [SHELL32.110]
369 * uEnumFlags any SHCONTF flag
371 int WINAPI FileMenu_InsertUsingPidl (
377 LPFNFMCALLBACK lpfnCallback)
379 TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
380 hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
386 FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
388 return FM_InitMenuPopup(hmenu, NULL);
391 /*************************************************************************
392 * FileMenu_ReplaceUsingPidl [SHELL32.113]
394 * FIXME: the static items are deleted but wont be refreshed
396 int WINAPI FileMenu_ReplaceUsingPidl(
401 LPFNFMCALLBACK lpfnCallback)
403 TRACE("0x%08x 0x%08x %p 0x%08x %p\n",
404 hmenu, uID, pidl, uEnumFlags, lpfnCallback);
406 FileMenu_DeleteAllItems (hmenu);
408 FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback);
410 return FM_InitMenuPopup(hmenu, NULL);
413 /*************************************************************************
414 * FileMenu_Invalidate [SHELL32.111]
416 void WINAPI FileMenu_Invalidate (HMENU hMenu)
418 FIXME("0x%08x\n",hMenu);
421 /*************************************************************************
422 * FileMenu_FindSubMenuByPidl [SHELL32.106]
424 HMENU WINAPI FileMenu_FindSubMenuByPidl(
428 FIXME("0x%08x %p\n",hMenu, pidl);
432 /*************************************************************************
433 * FileMenu_AppendFilesForPidl [SHELL32.124]
435 HMENU WINAPI FileMenu_AppendFilesForPidl(
442 menudata = FM_GetMenuInfo(hmenu);
444 menudata->bInitialized = FALSE;
446 FM_InitMenuPopup(hmenu, pidl);
449 FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
451 TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator);
455 /*************************************************************************
456 * FileMenu_AddFilesForPidl [SHELL32.125]
459 * uEnumFlags any SHCONTF flag
461 int WINAPI FileMenu_AddFilesForPidl (
468 LPFNFMCALLBACK lpfnCallback)
470 TRACE("0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
471 hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
473 return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
478 /*************************************************************************
479 * FileMenu_TrackPopupMenuEx [SHELL32.116]
481 HRESULT WINAPI FileMenu_TrackPopupMenuEx (
489 TRACE("0x%08x 0x%08x 0x%x 0x%x 0x%08x %p\n",
490 hMenu, uFlags, x, y, hWnd, lptpm);
491 return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm);
494 /*************************************************************************
495 * FileMenu_GetLastSelectedItemPidls [SHELL32.107]
497 BOOL WINAPI FileMenu_GetLastSelectedItemPidls(
499 LPCITEMIDLIST *ppidlFolder,
500 LPCITEMIDLIST *ppidlItem)
502 FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
506 #define FM_ICON_SIZE 16
510 #define FM_LEFTBORDER 2
511 #define FM_RIGHTBORDER 8
512 /*************************************************************************
513 * FileMenu_MeasureItem [SHELL32.112]
515 LRESULT WINAPI FileMenu_MeasureItem(
517 LPMEASUREITEMSTRUCT lpmis)
519 LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
520 HDC hdc = GetDC(hWnd);
524 TRACE("0x%08x %p %s\n", hWnd, lpmis, pMyItem->szItemText);
526 GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
528 lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER;
529 lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE);
531 /* add the menubitmap */
532 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
533 if (menuinfo->nBorderWidth)
534 lpmis->itemWidth += menuinfo->nBorderWidth;
536 TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight);
537 ReleaseDC (hWnd, hdc);
540 /*************************************************************************
541 * FileMenu_DrawItem [SHELL32.105]
543 LRESULT WINAPI FileMenu_DrawItem(
545 LPDRAWITEMSTRUCT lpdis)
547 LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData);
548 COLORREF clrPrevText, clrPrevBkgnd;
550 HIMAGELIST hImageList;
551 RECT TextRect, BorderRect;
554 TRACE("0x%08x %p %s\n", hWnd, lpdis, pMyItem->szItemText);
556 if (lpdis->itemState & ODS_SELECTED)
558 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
559 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
563 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT));
564 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU));
567 CopyRect(&TextRect, &(lpdis->rcItem));
569 /* add the menubitmap */
570 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
571 if (menuinfo->nBorderWidth)
572 TextRect.left += menuinfo->nBorderWidth;
574 BorderRect.right = menuinfo->nBorderWidth;
575 /* FillRect(lpdis->hDC, &BorderRect, CreateSolidBrush( menuinfo->crBorderColor));
577 TextRect.left += FM_LEFTBORDER;
578 xi = TextRect.left + FM_SPACE1;
579 yi = TextRect.top + FM_Y_SPACE/2;
580 TextRect.bottom -= FM_Y_SPACE/2;
582 xt = xi + FM_ICON_SIZE + FM_SPACE2;
585 ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
587 Shell_GetImageList(0, &hImageList);
588 pImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
590 TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom);
592 SetTextColor(lpdis->hDC, clrPrevText);
593 SetBkColor(lpdis->hDC, clrPrevBkgnd);
598 /*************************************************************************
599 * FileMenu_InitMenuPopup [SHELL32.109]
602 * The filemenu is a ownerdrawn menu. Call this function responding to
606 BOOL WINAPI FileMenu_InitMenuPopup (HMENU hmenu)
608 FM_InitMenuPopup(hmenu, NULL);
612 /*************************************************************************
613 * FileMenu_HandleMenuChar [SHELL32.108]
615 LRESULT WINAPI FileMenu_HandleMenuChar(
619 FIXME("0x%08x 0x%08x\n",hMenu,wParam);
623 /*************************************************************************
624 * FileMenu_DeleteAllItems [SHELL32.104]
629 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
636 TRACE("0x%08x\n", hmenu);
638 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
639 mii.cbSize = sizeof(MENUITEMINFOA);
640 mii.fMask = MIIM_SUBMENU|MIIM_DATA;
642 for (i = 0; i < GetMenuItemCount( hmenu ); i++)
643 { GetMenuItemInfoA(hmenu, i, TRUE, &mii );
646 SHFree((LPFMINFO)mii.dwItemData);
649 FileMenu_Destroy(mii.hSubMenu);
652 while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
654 menudata = FM_GetMenuInfo(hmenu);
656 menudata->bInitialized = FALSE;
661 /*************************************************************************
662 * FileMenu_DeleteItemByCmd [SHELL32.]
665 BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
669 TRACE("0x%08x 0x%08x\n", hMenu, uID);
671 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
672 mii.cbSize = sizeof(MENUITEMINFOA);
673 mii.fMask = MIIM_SUBMENU;
675 GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
678 DeleteMenu(hMenu, MF_BYCOMMAND, uID);
682 /*************************************************************************
683 * FileMenu_DeleteItemByIndex [SHELL32.140]
685 BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
689 TRACE("0x%08x 0x%08x\n", hMenu, uPos);
691 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
692 mii.cbSize = sizeof(MENUITEMINFOA);
693 mii.fMask = MIIM_SUBMENU;
695 GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
698 DeleteMenu(hMenu, MF_BYPOSITION, uPos);
702 /*************************************************************************
703 * FileMenu_DeleteItemByFirstID [SHELL32.141]
705 BOOL WINAPI FileMenu_DeleteItemByFirstID(
709 TRACE("0x%08x 0x%08x\n", hMenu, uID);
713 /*************************************************************************
714 * FileMenu_DeleteSeparator [SHELL32.142]
716 BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu)
718 TRACE("0x%08x\n", hMenu);
722 /*************************************************************************
723 * FileMenu_EnableItemByCmd [SHELL32.143]
725 BOOL WINAPI FileMenu_EnableItemByCmd(
730 TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
734 /*************************************************************************
735 * FileMenu_GetItemExtent [SHELL32.144]
738 * if the menu is to big, entrys are getting cut away!!
740 DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos)
743 FIXME("0x%08x 0x%08x\n", hMenu, uPos);
745 if (GetMenuItemRect(0, hMenu, uPos, &rect))
746 { FIXME("0x%04x 0x%04x 0x%04x 0x%04x\n",
747 rect.right, rect.left, rect.top, rect.bottom);
748 return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom);
750 return 0x00100010; /*fixme*/
753 /*************************************************************************
754 * FileMenu_AbortInitMenu [SHELL32.120]
757 void WINAPI FileMenu_AbortInitMenu (void)
762 /*************************************************************************
763 * SHFind_InitMenuPopup [SHELL32.149]
767 * hMenu [in] handel of menu previously created
768 * hWndParent [in] parent window
772 HRESULT WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, DWORD w, DWORD x)
773 { FIXME("hmenu=0x%08x hwnd=0x%08x 0x%08lx 0x%08lx stub\n",
774 hMenu,hWndParent,w,x);
778 /*************************************************************************
779 * Shell_MergeMenus [SHELL32.67]
782 BOOL _SHIsMenuSeparator(HMENU hm, int i)
786 mii.cbSize = sizeof(MENUITEMINFOA);
787 mii.fMask = MIIM_TYPE;
788 mii.cch = 0; /* WARNING: We MUST initialize it to 0*/
789 if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
794 if (mii.fType & MFT_SEPARATOR)
802 HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
805 BOOL bAlreadySeparated;
806 MENUITEMINFOA miiSrc;
808 UINT uTemp, uIDMax = uIDAdjust;
810 TRACE("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x 0x%04lx\n",
811 hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
813 if (!hmDst || !hmSrc)
817 nItem = GetMenuItemCount(hmDst);
819 if (uInsert >= (UINT)nItem) /* insert position inside menu? */
821 uInsert = (UINT)nItem; /* append on the end */
822 bAlreadySeparated = TRUE;
826 bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
829 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
831 /* Add a separator between the menus */
832 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
833 bAlreadySeparated = TRUE;
837 /* Go through the menu items and clone them*/
838 for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
840 miiSrc.cbSize = sizeof(MENUITEMINFOA);
841 miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
843 /* We need to reset this every time through the loop in case menus DON'T have IDs*/
844 miiSrc.fType = MFT_STRING;
845 miiSrc.dwTypeData = szName;
846 miiSrc.dwItemData = 0;
847 miiSrc.cch = sizeof(szName);
849 if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
854 /* 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);
856 if (miiSrc.fType & MFT_SEPARATOR)
858 /* This is a separator; don't put two of them in a row */
859 if (bAlreadySeparated)
862 bAlreadySeparated = TRUE;
864 else if (miiSrc.hSubMenu)
866 if (uFlags & MM_SUBMENUSHAVEIDS)
868 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
870 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
873 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
874 uIDMax = miiSrc.wID + 1;
878 miiSrc.fMask &= ~MIIM_ID; /* Don't set IDs for submenus that didn't have them already */
880 hmSubMenu = miiSrc.hSubMenu;
882 miiSrc.hSubMenu = CreatePopupMenu();
884 if (!miiSrc.hSubMenu) return(uIDMax);
886 uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS);
891 bAlreadySeparated = FALSE;
893 else /* normal menu item */
895 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
897 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
900 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
901 uIDMax = miiSrc.wID + 1;
903 bAlreadySeparated = FALSE;
906 /* 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);
908 if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
914 /* Ensure the correct number of separators at the beginning of the
915 inserted menu items*/
918 if (bAlreadySeparated)
920 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
925 if (_SHIsMenuSeparator(hmDst, uInsert-1))
927 if (bAlreadySeparated)
929 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
934 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
936 /* Add a separator between the menus*/
937 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);