Bugfix: exit() replaced by ExitProcess().
[wine/testsucceed.git] / dlls / shell32 / shlmenu.c
blobd803c5efd70c45ddf5dd328a06a511eff4be17a4
1 /*
2 * see www.geocities.com/SiliconValley/4942/filemenu.html
3 */
4 #include <assert.h>
5 #include <string.h>
7 #include "wine/obj_base.h"
8 #include "wine/obj_enumidlist.h"
9 #include "wine/obj_shellfolder.h"
11 #include "heap.h"
12 #include "debugtools.h"
13 #include "winversion.h"
14 #include "shell32_main.h"
16 #include "pidl.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);
21 typedef struct
22 { BOOL bInitialized;
23 BOOL bIsMagic;
25 /* create */
26 COLORREF crBorderColor;
27 int nBorderWidth;
28 HBITMAP hBorderBmp;
30 /* insert using pidl */
31 LPITEMIDLIST pidl;
32 UINT uID;
33 UINT uFlags;
34 UINT uEnumFlags;
35 LPFNFMCALLBACK lpfnCallback;
36 } FMINFO, *LPFMINFO;
38 typedef struct
39 { int cchItemText;
40 int iIconIndex;
41 HMENU hMenu;
42 char szItemText[1];
43 } FMITEM, * LPFMITEM;
45 static BOOL bAbortInit;
47 #define CCH_MAXITEMTEXT 256
49 DEFAULT_DEBUG_CHANNEL(shell)
51 LPFMINFO FM_GetMenuInfo(HMENU hmenu)
52 { MENUINFO MenuInfo;
53 LPFMINFO menudata;
55 MenuInfo.cbSize = sizeof(MENUINFO);
56 MenuInfo.fMask = MIM_MENUDATA;
58 if (! GetMenuInfo(hmenu, &MenuInfo))
59 return NULL;
61 menudata = (LPFMINFO)MenuInfo.dwMenuData;
63 assert ((menudata != 0) && (MenuInfo.cbSize == sizeof(MENUINFO)));
65 return menudata;
68 /*************************************************************************
69 * FM_SetMenuParameter [internal]
72 static LPFMINFO FM_SetMenuParameter(
73 HMENU hmenu,
74 UINT uID,
75 LPCITEMIDLIST pidl,
76 UINT uFlags,
77 UINT uEnumFlags,
78 LPFNFMCALLBACK lpfnCallback)
80 LPFMINFO menudata;
82 TRACE("\n");
84 menudata = FM_GetMenuInfo(hmenu);
86 if ( menudata->pidl)
87 { SHFree(menudata->pidl);
90 menudata->uID = uID;
91 menudata->pidl = ILClone(pidl);
92 menudata->uFlags = uFlags;
93 menudata->uEnumFlags = uEnumFlags;
94 menudata->lpfnCallback = lpfnCallback;
96 return menudata;
99 /*************************************************************************
100 * FM_InitMenuPopup [internal]
103 static int FM_InitMenuPopup(HMENU hmenu, LPITEMIDLIST pAlternatePidl)
104 { IShellFolder *lpsf, *lpsf2;
105 ULONG ulItemAttr;
106 UINT uID, uFlags, uEnumFlags;
107 LPFNFMCALLBACK lpfnCallback;
108 LPITEMIDLIST pidl;
109 char sTemp[MAX_PATH];
110 int NumberOfItems = 0, iIcon;
111 MENUINFO MenuInfo;
112 LPFMINFO menudata;
114 TRACE("\n");
116 MenuInfo.cbSize = sizeof(MENUINFO);
117 MenuInfo.fMask = MIM_MENUDATA;
119 if (! GetMenuInfo(hmenu, &MenuInfo))
120 return FALSE;
122 menudata = (LPFMINFO)MenuInfo.dwMenuData;
124 assert ((menudata != 0) && (MenuInfo.cbSize == sizeof(MENUINFO)));
126 if (menudata->bInitialized)
127 return 0;
129 uID = menudata->uID;
130 pidl = ((pAlternatePidl) ? pAlternatePidl : menudata->pidl);
131 uFlags = menudata->uFlags;
132 uEnumFlags = menudata->uEnumFlags;
133 lpfnCallback = menudata->lpfnCallback;
135 menudata->bInitialized = FALSE;
136 SetMenuInfo(hmenu, &MenuInfo);
138 if (SUCCEEDED (SHGetDesktopFolder(&lpsf)))
140 if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
142 IEnumIDList *lpe = NULL;
144 if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe )))
147 LPITEMIDLIST pidlTemp = NULL;
148 ULONG ulFetched;
150 while ((!bAbortInit) && (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched)))
152 if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr)))
154 ILGetDisplayName( pidlTemp, sTemp);
155 if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, &iIcon)))
156 iIcon = FM_BLANK_ICON;
157 if ( SFGAO_FOLDER & ulItemAttr)
159 LPFMINFO lpFmMi;
160 MENUINFO MenuInfo;
161 HMENU hMenuPopup = CreatePopupMenu();
163 lpFmMi = (LPFMINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
165 lpFmMi->pidl = ILCombine(pidl, pidlTemp);
166 lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
168 MenuInfo.cbSize = sizeof(MENUINFO);
169 MenuInfo.fMask = MIM_MENUDATA;
170 MenuInfo.dwMenuData = (DWORD) lpFmMi;
171 SetMenuInfo (hMenuPopup, &MenuInfo);
173 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
175 else
177 ((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
178 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
182 if (lpfnCallback)
184 TRACE("enter callback\n");
185 lpfnCallback ( pidl, pidlTemp);
186 TRACE("leave callback\n");
189 NumberOfItems++;
191 IEnumIDList_Release (lpe);
193 IShellFolder_Release(lpsf2);
195 IShellFolder_Release(lpsf);
198 if ( GetMenuItemCount (hmenu) == 0 )
199 FileMenu_AppendItemA (hmenu, "(empty)", uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
201 menudata->bInitialized = TRUE;
202 SetMenuInfo(hmenu, &MenuInfo);
204 return NumberOfItems;
206 /*************************************************************************
207 * FileMenu_Create [SHELL32.114]
210 HMENU WINAPI FileMenu_Create (
211 COLORREF crBorderColor,
212 int nBorderWidth,
213 HBITMAP hBorderBmp,
214 int nSelHeight,
215 UINT uFlags)
217 MENUINFO MenuInfo;
218 LPFMINFO menudata;
220 HMENU hMenu = CreatePopupMenu();
222 TRACE("0x%08lx 0x%08x 0x%08x 0x%08x 0x%08x hMenu=0x%08x\n",
223 crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, hMenu);
225 menudata = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
226 menudata->bIsMagic = TRUE;
227 menudata->crBorderColor = crBorderColor;
228 menudata->nBorderWidth = nBorderWidth;
229 menudata->hBorderBmp = hBorderBmp;
231 MenuInfo.cbSize = sizeof(MENUINFO);
232 MenuInfo.fMask = MIM_MENUDATA;
233 MenuInfo.dwMenuData = (DWORD) menudata;
234 SetMenuInfo (hMenu, &MenuInfo);
236 return hMenu;
239 /*************************************************************************
240 * FileMenu_Destroy [SHELL32.118]
242 * NOTES
243 * exported by name
245 void WINAPI FileMenu_Destroy (HMENU hmenu)
247 LPFMINFO menudata;
249 TRACE("0x%08x\n", hmenu);
251 FileMenu_DeleteAllItems (hmenu);
253 menudata = FM_GetMenuInfo(hmenu);
255 if ( menudata->pidl)
256 { SHFree( menudata->pidl);
258 HeapFree(GetProcessHeap(), 0, menudata);
260 DestroyMenu (hmenu);
263 /*************************************************************************
264 * FileMenu_AppendItemAW [SHELL32.115]
267 BOOL WINAPI FileMenu_AppendItemA(
268 HMENU hMenu,
269 LPCSTR lpText,
270 UINT uID,
271 int icon,
272 HMENU hMenuPopup,
273 int nItemHeight)
275 LPSTR lpszText = (LPSTR)lpText;
276 MENUITEMINFOA mii;
277 LPFMITEM myItem;
279 TRACE("0x%08x %s 0x%08x 0x%08x 0x%08x 0x%08x\n",
280 hMenu, (lpszText!=FM_SEPARATOR) ? lpText: NULL,
281 uID, icon, hMenuPopup, nItemHeight);
283 ZeroMemory (&mii, sizeof(MENUITEMINFOA));
285 mii.cbSize = sizeof(MENUITEMINFOA);
287 if (lpText != FM_SEPARATOR)
288 { int len = strlen (lpText);
289 myItem = (LPFMITEM) SHAlloc( sizeof(FMITEM) + len);
290 strcpy (myItem->szItemText, lpText);
291 myItem->cchItemText = len;
292 myItem->iIconIndex = icon;
293 myItem->hMenu = hMenu;
294 mii.fMask = MIIM_DATA;
295 mii.dwItemData = (DWORD) myItem;
298 if ( hMenuPopup )
299 { /* sub menu */
300 mii.fMask |= MIIM_TYPE | MIIM_SUBMENU;
301 mii.fType = MFT_OWNERDRAW;
302 mii.hSubMenu = hMenuPopup;
304 else if (lpText == FM_SEPARATOR )
305 { mii.fMask |= MIIM_ID | MIIM_TYPE;
306 mii.fType = MFT_SEPARATOR;
308 else
309 { /* normal item */
310 mii.fMask |= MIIM_ID | MIIM_TYPE | MIIM_STATE;
311 mii.fState = MFS_ENABLED | MFS_DEFAULT;
312 mii.fType = MFT_OWNERDRAW;
314 mii.wID = uID;
316 InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
318 return TRUE;
321 BOOL WINAPI FileMenu_AppendItemAW(
322 HMENU hMenu,
323 LPCVOID lpText,
324 UINT uID,
325 int icon,
326 HMENU hMenuPopup,
327 int nItemHeight)
329 BOOL ret;
330 LPSTR lpszText=NULL;
332 if (VERSION_OsIsUnicode() && (lpText!=FM_SEPARATOR))
333 lpszText = HEAP_strdupWtoA ( GetProcessHeap(),0, lpText);
335 ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : lpText, uID, icon, hMenuPopup, nItemHeight);
337 if (lpszText)
338 HeapFree( GetProcessHeap(), 0, lpszText );
340 return ret;
342 /*************************************************************************
343 * FileMenu_InsertUsingPidl [SHELL32.110]
345 * NOTES
346 * uEnumFlags any SHCONTF flag
348 int WINAPI FileMenu_InsertUsingPidl (
349 HMENU hmenu,
350 UINT uID,
351 LPCITEMIDLIST pidl,
352 UINT uFlags,
353 UINT uEnumFlags,
354 LPFNFMCALLBACK lpfnCallback)
356 TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
357 hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
359 pdump (pidl);
361 bAbortInit = FALSE;
363 FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
365 return FM_InitMenuPopup(hmenu, NULL);
368 /*************************************************************************
369 * FileMenu_ReplaceUsingPidl [SHELL32.113]
372 int WINAPI FileMenu_ReplaceUsingPidl(
373 HMENU hmenu,
374 UINT uID,
375 LPCITEMIDLIST pidl,
376 UINT uEnumFlags,
377 LPFNFMCALLBACK lpfnCallback)
379 TRACE("0x%08x 0x%08x %p 0x%08x %p\n",
380 hmenu, uID, pidl, uEnumFlags, lpfnCallback);
382 FileMenu_DeleteAllItems (hmenu);
384 FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback);
386 return FM_InitMenuPopup(hmenu, NULL);
389 /*************************************************************************
390 * FileMenu_Invalidate [SHELL32.111]
392 void WINAPI FileMenu_Invalidate (HMENU hMenu)
394 FIXME("0x%08x\n",hMenu);
397 /*************************************************************************
398 * FileMenu_FindSubMenuByPidl [SHELL32.106]
400 HMENU WINAPI FileMenu_FindSubMenuByPidl(
401 HMENU hMenu,
402 LPCITEMIDLIST pidl)
404 FIXME("0x%08x %p\n",hMenu, pidl);
405 return 0;
408 /*************************************************************************
409 * FileMenu_AppendFilesForPidl [SHELL32.124]
411 HMENU WINAPI FileMenu_AppendFilesForPidl(
412 HMENU hmenu,
413 LPCITEMIDLIST pidl,
414 BOOL bAddSeperator)
416 LPFMINFO menudata;
418 menudata = FM_GetMenuInfo(hmenu);
420 menudata->bInitialized = FALSE;
422 FM_InitMenuPopup(hmenu, pidl);
424 if (bAddSeperator)
425 FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
427 TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator);
429 return 0;
431 /*************************************************************************
432 * FileMenu_AddFilesForPidl [SHELL32.125]
434 * NOTES
435 * uEnumFlags any SHCONTF flag
437 int WINAPI FileMenu_AddFilesForPidl (
438 HMENU hmenu,
439 UINT uReserved,
440 UINT uID,
441 LPCITEMIDLIST pidl,
442 UINT uFlags,
443 UINT uEnumFlags,
444 LPFNFMCALLBACK lpfnCallback)
446 TRACE("0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
447 hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
449 return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
454 /*************************************************************************
455 * FileMenu_TrackPopupMenuEx [SHELL32.116]
457 HRESULT WINAPI FileMenu_TrackPopupMenuEx (
458 HMENU hMenu,
459 UINT uFlags,
460 int x,
461 int y,
462 HWND hWnd,
463 LPTPMPARAMS lptpm)
465 TRACE("0x%08x 0x%08x 0x%x 0x%x 0x%08x %p\n",
466 hMenu, uFlags, x, y, hWnd, lptpm);
467 return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm);
470 /*************************************************************************
471 * FileMenu_GetLastSelectedItemPidls [SHELL32.107]
473 BOOL WINAPI FileMenu_GetLastSelectedItemPidls(
474 UINT uReserved,
475 LPCITEMIDLIST *ppidlFolder,
476 LPCITEMIDLIST *ppidlItem)
478 FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
479 return 0;
482 #define FM_ICON_SIZE 16
483 #define FM_Y_SPACE 4
484 #define FM_SPACE1 4
485 #define FM_SPACE2 2
486 #define FM_LEFTBORDER 2
487 #define FM_RIGHTBORDER 8
488 /*************************************************************************
489 * FileMenu_MeasureItem [SHELL32.112]
491 LRESULT WINAPI FileMenu_MeasureItem(
492 HWND hWnd,
493 LPMEASUREITEMSTRUCT lpmis)
495 LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
496 HDC hdc = GetDC(hWnd);
497 SIZE size;
498 LPFMINFO menuinfo;
500 TRACE("0x%08x %p %s\n", hWnd, lpmis, pMyItem->szItemText);
502 GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
504 lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER;
505 lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE);
507 /* add the menubitmap */
508 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
509 if (menuinfo->bIsMagic)
510 lpmis->itemWidth += menuinfo->nBorderWidth;
512 TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight);
513 ReleaseDC (hWnd, hdc);
514 return 0;
516 /*************************************************************************
517 * FileMenu_DrawItem [SHELL32.105]
519 LRESULT WINAPI FileMenu_DrawItem(
520 HWND hWnd,
521 LPDRAWITEMSTRUCT lpdis)
523 LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData);
524 COLORREF clrPrevText, clrPrevBkgnd;
525 int xi,yi,xt,yt;
526 HIMAGELIST hImageList;
527 RECT TextRect, BorderRect;
528 LPFMINFO menuinfo;
530 TRACE("0x%08x %p %s\n", hWnd, lpdis, pMyItem->szItemText);
532 if (lpdis->itemState & ODS_SELECTED)
534 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
535 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
537 else
539 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT));
540 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU));
543 CopyRect(&TextRect, &(lpdis->rcItem));
545 /* add the menubitmap */
546 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
547 if (menuinfo->bIsMagic)
548 TextRect.left += menuinfo->nBorderWidth;
550 BorderRect.right = menuinfo->nBorderWidth;
551 /* FillRect(lpdis->hDC, &BorderRect, CreateSolidBrush( menuinfo->crBorderColor));
553 TextRect.left += FM_LEFTBORDER;
554 xi = TextRect.left + FM_SPACE1;
555 yi = TextRect.top + FM_Y_SPACE/2;
556 TextRect.bottom -= FM_Y_SPACE/2;
558 xt = xi + FM_ICON_SIZE + FM_SPACE2;
559 yt = yi;
561 ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
563 Shell_GetImageList(0, &hImageList);
564 pImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
566 TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom);
568 SetTextColor(lpdis->hDC, clrPrevText);
569 SetBkColor(lpdis->hDC, clrPrevBkgnd);
571 return TRUE;
574 /*************************************************************************
575 * FileMenu_InitMenuPopup [SHELL32.109]
577 * NOTES
578 * The filemenu is a ownerdrawn menu. Call this function responding to
579 * WM_INITPOPUPMENU
582 BOOL WINAPI FileMenu_InitMenuPopup (HMENU hmenu)
584 FM_InitMenuPopup(hmenu, NULL);
585 return TRUE;
588 /*************************************************************************
589 * FileMenu_HandleMenuChar [SHELL32.108]
591 LRESULT WINAPI FileMenu_HandleMenuChar(
592 HMENU hMenu,
593 WPARAM wParam)
595 FIXME("0x%08x 0x%08x\n",hMenu,wParam);
596 return 0;
599 /*************************************************************************
600 * FileMenu_DeleteAllItems [SHELL32.104]
602 * NOTES
603 * exported by name
605 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
607 MENUITEMINFOA mii;
608 LPFMINFO menudata;
610 int i;
612 TRACE("0x%08x\n", hmenu);
614 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
615 mii.cbSize = sizeof(MENUITEMINFOA);
616 mii.fMask = MIIM_SUBMENU|MIIM_DATA;
618 for (i = 0; i < GetMenuItemCount( hmenu ); i++)
619 { GetMenuItemInfoA(hmenu, i, TRUE, &mii );
621 if (mii.dwItemData)
622 SHFree((LPFMINFO)mii.dwItemData);
624 if (mii.hSubMenu)
625 FileMenu_Destroy(mii.hSubMenu);
628 while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
630 menudata = FM_GetMenuInfo(hmenu);
632 menudata->bInitialized = FALSE;
634 return TRUE;
637 /*************************************************************************
638 * FileMenu_DeleteItemByCmd [SHELL32.]
641 BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
643 MENUITEMINFOA mii;
645 TRACE("0x%08x 0x%08x\n", hMenu, uID);
647 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
648 mii.cbSize = sizeof(MENUITEMINFOA);
649 mii.fMask = MIIM_SUBMENU;
651 GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
652 if ( mii.hSubMenu );
654 DeleteMenu(hMenu, MF_BYCOMMAND, uID);
655 return TRUE;
658 /*************************************************************************
659 * FileMenu_DeleteItemByIndex [SHELL32.140]
661 BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
663 MENUITEMINFOA mii;
665 TRACE("0x%08x 0x%08x\n", hMenu, uPos);
667 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
668 mii.cbSize = sizeof(MENUITEMINFOA);
669 mii.fMask = MIIM_SUBMENU;
671 GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
672 if ( mii.hSubMenu );
674 DeleteMenu(hMenu, MF_BYPOSITION, uPos);
675 return TRUE;
678 /*************************************************************************
679 * FileMenu_DeleteItemByFirstID [SHELL32.141]
681 BOOL WINAPI FileMenu_DeleteItemByFirstID(
682 HMENU hMenu,
683 UINT uID)
685 TRACE("0x%08x 0x%08x\n", hMenu, uID);
686 return 0;
689 /*************************************************************************
690 * FileMenu_DeleteSeparator [SHELL32.142]
692 BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu)
694 TRACE("0x%08x\n", hMenu);
695 return 0;
698 /*************************************************************************
699 * FileMenu_EnableItemByCmd [SHELL32.143]
701 BOOL WINAPI FileMenu_EnableItemByCmd(
702 HMENU hMenu,
703 UINT uID,
704 BOOL bEnable)
706 TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
707 return 0;
710 /*************************************************************************
711 * FileMenu_GetItemExtent [SHELL32.144]
713 * NOTES
714 * if the menu is to big, entrys are getting cut away!!
716 DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos)
717 { RECT rect;
719 FIXME("0x%08x 0x%08x\n", hMenu, uPos);
721 if (GetMenuItemRect(0, hMenu, uPos, &rect))
722 { FIXME("0x%04x 0x%04x 0x%04x 0x%04x\n",
723 rect.right, rect.left, rect.top, rect.bottom);
724 return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom);
726 return 0x00100010; /*fixme*/
729 /*************************************************************************
730 * FileMenu_AbortInitMenu [SHELL32.120]
733 void WINAPI FileMenu_AbortInitMenu (void)
734 { TRACE("\n");
735 bAbortInit = TRUE;
738 /*************************************************************************
739 * SHFind_InitMenuPopup [SHELL32.149]
742 * PARAMETERS
743 * hMenu [in] handel of menu previously created
744 * hWndParent [in] parent window
745 * w [in] no pointer
746 * x [in] no pointer
748 HRESULT WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, DWORD w, DWORD x)
749 { FIXME("hmenu=0x%08x hwnd=0x%08x 0x%08lx 0x%08lx stub\n",
750 hMenu,hWndParent,w,x);
751 return TRUE;
754 /*************************************************************************
755 * Shell_MergeMenus [SHELL32.67]
758 BOOL _SHIsMenuSeparator(HMENU hm, int i)
760 MENUITEMINFOA mii;
762 mii.cbSize = sizeof(MENUITEMINFOA);
763 mii.fMask = MIIM_TYPE;
764 mii.cch = 0; /* WARNING: We MUST initialize it to 0*/
765 if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
766 { return(FALSE);
769 if (mii.fType & MFT_SEPARATOR)
770 { return(TRUE);
773 return(FALSE);
775 #define MM_ADDSEPARATOR 0x00000001L
776 #define MM_SUBMENUSHAVEIDS 0x00000002L
777 HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
778 { int nItem;
779 HMENU hmSubMenu;
780 BOOL bAlreadySeparated;
781 MENUITEMINFOA miiSrc;
782 char szName[256];
783 UINT uTemp, uIDMax = uIDAdjust;
785 FIXME("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x 0x%04lx stub\n",
786 hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
788 if (!hmDst || !hmSrc)
789 { return uIDMax;
792 nItem = GetMenuItemCount(hmDst);
793 if (uInsert >= (UINT)nItem)
794 { uInsert = (UINT)nItem;
795 bAlreadySeparated = TRUE;
797 else
798 { bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
800 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
801 { /* Add a separator between the menus */
802 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
803 bAlreadySeparated = TRUE;
807 /* Go through the menu items and clone them*/
808 for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
809 { miiSrc.cbSize = sizeof(MENUITEMINFOA);
810 miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
811 /* We need to reset this every time through the loop in case
812 menus DON'T have IDs*/
813 miiSrc.fType = MFT_STRING;
814 miiSrc.dwTypeData = szName;
815 miiSrc.dwItemData = 0;
816 miiSrc.cch = sizeof(szName);
818 if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
819 { continue;
821 if (miiSrc.fType & MFT_SEPARATOR)
822 { /* This is a separator; don't put two of them in a row*/
823 if (bAlreadySeparated)
824 { continue;
826 bAlreadySeparated = TRUE;
828 else if (miiSrc.hSubMenu)
829 { if (uFlags & MM_SUBMENUSHAVEIDS)
830 { /* Adjust the ID and check it*/
831 miiSrc.wID += uIDAdjust;
832 if (miiSrc.wID > uIDAdjustMax)
833 { continue;
835 if (uIDMax <= miiSrc.wID)
836 { uIDMax = miiSrc.wID + 1;
839 else
840 { /* Don't set IDs for submenus that didn't have them already */
841 miiSrc.fMask &= ~MIIM_ID;
843 hmSubMenu = miiSrc.hSubMenu;
844 miiSrc.hSubMenu = CreatePopupMenu();
845 if (!miiSrc.hSubMenu)
846 { return(uIDMax);
848 uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags&MM_SUBMENUSHAVEIDS);
849 if (uIDMax <= uTemp)
850 { uIDMax = uTemp;
852 bAlreadySeparated = FALSE;
854 else
855 { /* Adjust the ID and check it*/
856 miiSrc.wID += uIDAdjust;
857 if (miiSrc.wID > uIDAdjustMax)
858 { continue;
860 if (uIDMax <= miiSrc.wID)
861 { uIDMax = miiSrc.wID + 1;
863 bAlreadySeparated = FALSE;
865 if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
866 { return(uIDMax);
870 /* Ensure the correct number of separators at the beginning of the
871 inserted menu items*/
872 if (uInsert == 0)
873 { if (bAlreadySeparated)
874 { DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
877 else
878 { if (_SHIsMenuSeparator(hmDst, uInsert-1))
879 { if (bAlreadySeparated)
880 { DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
883 else
884 { if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
885 { /* Add a separator between the menus*/
886 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
890 return(uIDMax);