Replaced some GetProcAddress() imports by the standard dll import
[wine/gsoc_dplay.git] / dlls / shell32 / shlmenu.c
blobb149967e6c859e6b7a3ef47a2a008840bddef713
1 /*
2 * see www.geocities.com/SiliconValley/4942/filemenu.html
3 */
4 #include <string.h>
6 #include "shlobj.h"
7 #include "wine/obj_base.h"
8 #include "wine/obj_enumidlist.h"
9 #include "wine/obj_shellfolder.h"
10 #include "wine/undocshell.h"
11 #include "shlwapi.h"
12 #include "heap.h"
13 #include "debugtools.h"
14 #include "shell32_main.h"
15 #include "shlguid.h"
17 #include "pidl.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);
22 typedef struct
24 BOOL bInitialized;
25 BOOL bFixedItems;
26 /* create */
27 COLORREF crBorderColor;
28 int nBorderWidth;
29 HBITMAP hBorderBmp;
31 /* insert using pidl */
32 LPITEMIDLIST pidl;
33 UINT uID;
34 UINT uFlags;
35 UINT uEnumFlags;
36 LPFNFMCALLBACK lpfnCallback;
37 } FMINFO, *LPFMINFO;
39 typedef struct
40 { int cchItemText;
41 int iIconIndex;
42 HMENU hMenu;
43 char szItemText[1];
44 } FMITEM, * LPFMITEM;
46 static BOOL bAbortInit;
48 #define CCH_MAXITEMTEXT 256
50 DEFAULT_DEBUG_CHANNEL(shell);
52 LPFMINFO FM_GetMenuInfo(HMENU hmenu)
53 { MENUINFO MenuInfo;
54 LPFMINFO menudata;
56 MenuInfo.cbSize = sizeof(MENUINFO);
57 MenuInfo.fMask = MIM_MENUDATA;
59 if (! GetMenuInfo(hmenu, &MenuInfo))
60 return NULL;
62 menudata = (LPFMINFO)MenuInfo.dwMenuData;
64 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
66 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
67 return 0;
70 return menudata;
73 /*************************************************************************
74 * FM_SetMenuParameter [internal]
77 static LPFMINFO FM_SetMenuParameter(
78 HMENU hmenu,
79 UINT uID,
80 LPCITEMIDLIST pidl,
81 UINT uFlags,
82 UINT uEnumFlags,
83 LPFNFMCALLBACK lpfnCallback)
85 LPFMINFO menudata;
87 TRACE("\n");
89 menudata = FM_GetMenuInfo(hmenu);
91 if ( menudata->pidl)
92 { SHFree(menudata->pidl);
95 menudata->uID = uID;
96 menudata->pidl = ILClone(pidl);
97 menudata->uFlags = uFlags;
98 menudata->uEnumFlags = uEnumFlags;
99 menudata->lpfnCallback = lpfnCallback;
101 return menudata;
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;
113 LPITEMIDLIST pidl;
114 char sTemp[MAX_PATH];
115 int NumberOfItems = 0, iIcon;
116 MENUINFO MenuInfo;
117 LPFMINFO menudata;
119 TRACE("0x%04x %p\n", hmenu, pAlternatePidl);
121 MenuInfo.cbSize = sizeof(MENUINFO);
122 MenuInfo.fMask = MIM_MENUDATA;
124 if (! GetMenuInfo(hmenu, &MenuInfo))
125 return FALSE;
127 menudata = (LPFMINFO)MenuInfo.dwMenuData;
129 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
131 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
132 return 0;
135 if (menudata->bInitialized)
136 return 0;
138 pidl = ((pAlternatePidl) ? pAlternatePidl : menudata->pidl);
139 if (!pidl)
140 return 0;
142 uID = menudata->uID;
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;
160 ULONG ulFetched;
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)
171 LPFMINFO lpFmMi;
172 MENUINFO MenuInfo;
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);
187 else
189 ((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
190 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
194 if (lpfnCallback)
196 TRACE("enter callback\n");
197 lpfnCallback ( pidl, pidlTemp);
198 TRACE("leave callback\n");
201 NumberOfItems++;
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);
212 NumberOfItems++;
215 menudata->bInitialized = TRUE;
216 SetMenuInfo(hmenu, &MenuInfo);
218 return NumberOfItems;
220 /*************************************************************************
221 * FileMenu_Create [SHELL32.114]
223 * NOTES
224 * for non-root menus values are
225 * (ffffffff,00000000,00000000,00000000,00000000)
227 HMENU WINAPI FileMenu_Create (
228 COLORREF crBorderColor,
229 int nBorderWidth,
230 HBITMAP hBorderBmp,
231 int nSelHeight,
232 UINT uFlags)
234 MENUINFO MenuInfo;
235 LPFMINFO menudata;
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);
252 return hMenu;
255 /*************************************************************************
256 * FileMenu_Destroy [SHELL32.118]
258 * NOTES
259 * exported by name
261 void WINAPI FileMenu_Destroy (HMENU hmenu)
263 LPFMINFO menudata;
265 TRACE("0x%08x\n", hmenu);
267 FileMenu_DeleteAllItems (hmenu);
269 menudata = FM_GetMenuInfo(hmenu);
271 if ( menudata->pidl)
272 { SHFree( menudata->pidl);
274 HeapFree(GetProcessHeap(), 0, menudata);
276 DestroyMenu (hmenu);
279 /*************************************************************************
280 * FileMenu_AppendItemAW [SHELL32.115]
283 BOOL WINAPI FileMenu_AppendItemA(
284 HMENU hMenu,
285 LPCSTR lpText,
286 UINT uID,
287 int icon,
288 HMENU hMenuPopup,
289 int nItemHeight)
291 LPSTR lpszText = (LPSTR)lpText;
292 MENUITEMINFOA mii;
293 LPFMITEM myItem;
294 LPFMINFO menudata;
295 MENUINFO MenuInfo;
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;
317 if ( hMenuPopup )
318 { /* sub menu */
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;
327 else
328 { /* normal item */
329 mii.fMask |= MIIM_ID | MIIM_TYPE | MIIM_STATE;
330 mii.fState = MFS_ENABLED | MFS_DEFAULT;
331 mii.fType = MFT_OWNERDRAW;
333 mii.wID = uID;
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))
342 return FALSE;
344 menudata = (LPFMINFO)MenuInfo.dwMenuData;
345 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
347 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
348 return 0;
351 menudata->bFixedItems = TRUE;
352 SetMenuInfo(hMenu, &MenuInfo);
354 return TRUE;
358 /**********************************************************************/
360 BOOL WINAPI FileMenu_AppendItemAW(
361 HMENU hMenu,
362 LPCVOID lpText,
363 UINT uID,
364 int icon,
365 HMENU hMenuPopup,
366 int nItemHeight)
368 BOOL ret;
369 LPSTR lpszText=NULL;
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);
376 if (lpszText)
377 HeapFree( GetProcessHeap(), 0, lpszText );
379 return ret;
381 /*************************************************************************
382 * FileMenu_InsertUsingPidl [SHELL32.110]
384 * NOTES
385 * uEnumFlags any SHCONTF flag
387 int WINAPI FileMenu_InsertUsingPidl (
388 HMENU hmenu,
389 UINT uID,
390 LPCITEMIDLIST pidl,
391 UINT uFlags,
392 UINT uEnumFlags,
393 LPFNFMCALLBACK lpfnCallback)
395 TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
396 hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
398 pdump (pidl);
400 bAbortInit = FALSE;
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(
413 HMENU hmenu,
414 UINT uID,
415 LPCITEMIDLIST pidl,
416 UINT uEnumFlags,
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(
441 HMENU hMenu,
442 LPCITEMIDLIST pidl)
444 FIXME("0x%08x %p\n",hMenu, pidl);
445 return 0;
448 /*************************************************************************
449 * FileMenu_AppendFilesForPidl [SHELL32.124]
451 int WINAPI FileMenu_AppendFilesForPidl(
452 HMENU hmenu,
453 LPCITEMIDLIST pidl,
454 BOOL bAddSeperator)
456 LPFMINFO menudata;
458 menudata = FM_GetMenuInfo(hmenu);
460 menudata->bInitialized = FALSE;
462 FM_InitMenuPopup(hmenu, pidl);
464 if (bAddSeperator)
465 FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
467 TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator);
469 return 0;
471 /*************************************************************************
472 * FileMenu_AddFilesForPidl [SHELL32.125]
474 * NOTES
475 * uEnumFlags any SHCONTF flag
477 int WINAPI FileMenu_AddFilesForPidl (
478 HMENU hmenu,
479 UINT uReserved,
480 UINT uID,
481 LPCITEMIDLIST pidl,
482 UINT uFlags,
483 UINT uEnumFlags,
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 (
498 HMENU hMenu,
499 UINT uFlags,
500 int x,
501 int y,
502 HWND hWnd,
503 LPTPMPARAMS lptpm)
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(
514 UINT uReserved,
515 LPCITEMIDLIST *ppidlFolder,
516 LPCITEMIDLIST *ppidlItem)
518 FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
519 return 0;
522 #define FM_ICON_SIZE 16
523 #define FM_Y_SPACE 4
524 #define FM_SPACE1 4
525 #define FM_SPACE2 2
526 #define FM_LEFTBORDER 2
527 #define FM_RIGHTBORDER 8
528 /*************************************************************************
529 * FileMenu_MeasureItem [SHELL32.112]
531 LRESULT WINAPI FileMenu_MeasureItem(
532 HWND hWnd,
533 LPMEASUREITEMSTRUCT lpmis)
535 LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
536 HDC hdc = GetDC(hWnd);
537 SIZE size;
538 LPFMINFO menuinfo;
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);
554 return 0;
556 /*************************************************************************
557 * FileMenu_DrawItem [SHELL32.105]
559 LRESULT WINAPI FileMenu_DrawItem(
560 HWND hWnd,
561 LPDRAWITEMSTRUCT lpdis)
563 LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData);
564 COLORREF clrPrevText, clrPrevBkgnd;
565 int xi,yi,xt,yt;
566 HIMAGELIST hImageList;
567 RECT TextRect, BorderRect;
568 LPFMINFO menuinfo;
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));
577 else
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;
599 yt = yi;
601 ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
603 Shell_GetImageList(0, &hImageList);
604 ImageList_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);
611 return TRUE;
614 /*************************************************************************
615 * FileMenu_InitMenuPopup [SHELL32.109]
617 * NOTES
618 * The filemenu is a ownerdrawn menu. Call this function responding to
619 * WM_INITPOPUPMENU
622 BOOL WINAPI FileMenu_InitMenuPopup (HMENU hmenu)
624 FM_InitMenuPopup(hmenu, NULL);
625 return TRUE;
628 /*************************************************************************
629 * FileMenu_HandleMenuChar [SHELL32.108]
631 LRESULT WINAPI FileMenu_HandleMenuChar(
632 HMENU hMenu,
633 WPARAM wParam)
635 FIXME("0x%08x 0x%08x\n",hMenu,wParam);
636 return 0;
639 /*************************************************************************
640 * FileMenu_DeleteAllItems [SHELL32.104]
642 * NOTES
643 * exported by name
645 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
647 MENUITEMINFOA mii;
648 LPFMINFO menudata;
650 int i;
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 );
661 if (mii.dwItemData)
662 SHFree((LPFMINFO)mii.dwItemData);
664 if (mii.hSubMenu)
665 FileMenu_Destroy(mii.hSubMenu);
668 while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
670 menudata = FM_GetMenuInfo(hmenu);
672 menudata->bInitialized = FALSE;
674 return TRUE;
677 /*************************************************************************
678 * FileMenu_DeleteItemByCmd [SHELL32.]
681 BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
683 MENUITEMINFOA mii;
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 );
692 if ( mii.hSubMenu )
694 /* FIXME: Do what? */
697 DeleteMenu(hMenu, MF_BYCOMMAND, uID);
698 return TRUE;
701 /*************************************************************************
702 * FileMenu_DeleteItemByIndex [SHELL32.140]
704 BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
706 MENUITEMINFOA mii;
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 );
715 if ( mii.hSubMenu )
717 /* FIXME: Do what? */
720 DeleteMenu(hMenu, MF_BYPOSITION, uPos);
721 return TRUE;
724 /*************************************************************************
725 * FileMenu_DeleteItemByFirstID [SHELL32.141]
727 BOOL WINAPI FileMenu_DeleteItemByFirstID(
728 HMENU hMenu,
729 UINT uID)
731 TRACE("0x%08x 0x%08x\n", hMenu, uID);
732 return 0;
735 /*************************************************************************
736 * FileMenu_DeleteSeparator [SHELL32.142]
738 BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu)
740 TRACE("0x%08x\n", hMenu);
741 return 0;
744 /*************************************************************************
745 * FileMenu_EnableItemByCmd [SHELL32.143]
747 BOOL WINAPI FileMenu_EnableItemByCmd(
748 HMENU hMenu,
749 UINT uID,
750 BOOL bEnable)
752 TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
753 return 0;
756 /*************************************************************************
757 * FileMenu_GetItemExtent [SHELL32.144]
759 * NOTES
760 * if the menu is to big, entrys are getting cut away!!
762 DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos)
763 { RECT rect;
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)
780 { TRACE("\n");
781 bAbortInit = TRUE;
784 /*************************************************************************
785 * SHFind_InitMenuPopup [SHELL32.149]
788 * PARAMETERS
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)
794 * RETURNS
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)
810 MENUITEMINFOA mii;
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))
817 return(FALSE);
820 if (mii.fType & MFT_SEPARATOR)
822 return(TRUE);
825 return(FALSE);
828 /**********************************************************************/
830 HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
831 { int nItem;
832 HMENU hmSubMenu;
833 BOOL bAlreadySeparated;
834 MENUITEMINFOA miiSrc;
835 char szName[256];
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)
842 { return uIDMax;
845 nItem = GetMenuItemCount(hmDst);
847 if (uInsert >= (UINT)nItem) /* insert position inside menu? */
849 uInsert = (UINT)nItem; /* append on the end */
850 bAlreadySeparated = TRUE;
852 else
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))
879 continue;
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)
888 continue;
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 */
899 continue;
901 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
902 uIDMax = miiSrc.wID + 1;
904 else
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);
916 if (uIDMax <= uTemp)
917 uIDMax = uTemp;
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 */
926 continue;
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))
938 return(uIDMax);
942 /* Ensure the correct number of separators at the beginning of the
943 inserted menu items*/
944 if (uInsert == 0)
946 if (bAlreadySeparated)
948 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
951 else
953 if (_SHIsMenuSeparator(hmDst, uInsert-1))
955 if (bAlreadySeparated)
957 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
960 else
962 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
964 /* Add a separator between the menus*/
965 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
969 return(uIDMax);