All 19 FileMenu_* functions, some as stubs, some implemented.
[wine/testsucceed.git] / dlls / shell32 / shlmenu.c
blob35077e5fcfc1bdfae1a8784461cfdcdc46363e0f
1 /*
3 */
4 #include <string.h>
6 #include "wine/obj_base.h"
7 #include "wine/obj_enumidlist.h"
8 #include "wine/obj_shellfolder.h"
10 #include "heap.h"
11 #include "debug.h"
12 #include "winversion.h"
13 #include "shell32_main.h"
15 #include "pidl.h"
17 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hMenu);
19 /*************************************************************************
20 * FileMenu_Create [SHELL32.114]
23 HMENU WINAPI FileMenu_Create (
24 COLORREF crBorderColor,
25 int nBorderWidth,
26 HBITMAP hBorderBmp,
27 int nSelHeight,
28 UINT uFlags)
30 HMENU ret = CreatePopupMenu();
32 FIXME(shell,"0x%08lx 0x%08x 0x%08x 0x%08x 0x%08x ret=0x%08x\n",
33 crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, ret);
35 return ret;
38 /*************************************************************************
39 * FileMenu_Destroy [SHELL32.118]
41 * NOTES
42 * exported by name
44 void WINAPI FileMenu_Destroy (HMENU hMenu)
46 TRACE(shell,"0x%08x\n", hMenu);
47 FileMenu_DeleteAllItems (hMenu);
48 DestroyMenu (hMenu);
51 /*************************************************************************
52 * FileMenu_AppendItemAW [SHELL32.115]
55 BOOL WINAPI FileMenu_AppendItemAW(
56 HMENU hMenu,
57 LPCVOID lpText,
58 UINT uID,
59 int icon,
60 HMENU hMenuPopup,
61 int nItemHeight)
63 LPSTR lpszText = (LPSTR)lpText;
64 MENUITEMINFOA mii;
65 ZeroMemory (&mii, sizeof(MENUITEMINFOA));
67 if (VERSION_OsIsUnicode() && (lpszText!=FM_SEPARATOR))
68 lpszText = HEAP_strdupWtoA ( GetProcessHeap(),0, lpText);
70 FIXME(shell,"0x%08x %s 0x%08x 0x%08x 0x%08x 0x%08x\n",
71 hMenu, (lpszText!=FM_SEPARATOR) ? lpszText: NULL,
72 uID, icon, hMenuPopup, nItemHeight);
74 mii.cbSize = sizeof(mii);
76 if ( hMenuPopup )
77 { /* sub menu */
78 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;;
79 mii.hSubMenu = hMenuPopup;
80 mii.fType = MFT_STRING;
81 mii.dwTypeData = lpszText;
83 else if (lpText == FM_SEPARATOR )
84 { mii.fMask = MIIM_ID | MIIM_TYPE;
85 mii.fType = MFT_SEPARATOR;
87 else
88 { /* normal item */
89 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
90 mii.dwTypeData = lpszText;
91 mii.fState = MFS_ENABLED | MFS_DEFAULT;
92 mii.fType = MFT_STRING;
94 mii.wID = uID;
96 InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
98 if (VERSION_OsIsUnicode())
99 HeapFree( GetProcessHeap(), 0, lpszText );
101 return TRUE;
105 /*************************************************************************
106 * FileMenu_InsertUsingPidl [SHELL32.110]
108 * NOTES
109 * uEnumFlags any SHCONTF flag
111 int WINAPI FileMenu_InsertUsingPidl (
112 HMENU hMenu,
113 UINT uID,
114 LPCITEMIDLIST pidl,
115 UINT uFlags,
116 UINT uEnumFlags,
117 LPFNFMCALLBACK lpfnCallback)
119 IShellFolder *lpsf, *lpsf2;
120 IEnumIDList *lpe=0;
121 ULONG ulFetched;
122 LPITEMIDLIST pidlTemp=0;
123 ULONG ulItemAttr;
124 char sTemp[MAX_PATH];
125 int NumberOfItems = 0;
127 FIXME(shell,"0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
128 hMenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
129 pdump (pidl);
131 if (SUCCEEDED (SHGetDesktopFolder(&lpsf)))
132 { if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
133 { if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe )))
134 { while (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched))
135 { if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr)))
136 { ILGetDisplayName( pidlTemp, sTemp);
137 if ( SFGAO_FOLDER & ulItemAttr)
138 { FileMenu_AppendItemAW (hMenu, sTemp, uID, FM_BLANK_ICON, CreatePopupMenu(), FM_DEFAULT_HEIGHT);
140 else
141 { FileMenu_AppendItemAW (hMenu, sTemp, uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
144 TRACE(shell,"enter callback\n");
145 lpfnCallback ( pidl, pidlTemp);
146 TRACE(shell,"leave callback\n");
147 NumberOfItems++;
149 IEnumIDList_Release (lpe);
151 IShellFolder_Release(lpsf2);
153 IShellFolder_Release(lpsf);
156 return NumberOfItems;
159 /*************************************************************************
160 * FileMenu_ReplaceUsingPidl [SHELL32.113]
163 int WINAPI FileMenu_ReplaceUsingPidl(
164 HMENU hMenu,
165 UINT uID,
166 LPCITEMIDLIST pidl,
167 UINT uEnumFlags,
168 LPFNFMCALLBACK lpfnCallback)
170 FIXME(shell,"0x%08x 0x%08x %p 0x%08x %p\n",
171 hMenu, uID, pidl, uEnumFlags, lpfnCallback);
172 return 0;
175 /*************************************************************************
176 * FileMenu_Invalidate [SHELL32.111]
178 void WINAPI FileMenu_Invalidate (HMENU hMenu)
180 FIXME(shell,"0x%08x\n",hMenu);
183 /*************************************************************************
184 * FileMenu_FindSubMenuByPidl [SHELL32.106]
186 HMENU WINAPI FileMenu_FindSubMenuByPidl(
187 HMENU hMenu,
188 LPCITEMIDLIST pidl)
190 FIXME(shell,"0x%08x %p\n",hMenu, pidl);
191 return 0;
194 /*************************************************************************
195 * FileMenu_AppendFilesForPidl [SHELL32.124]
197 HMENU WINAPI FileMenu_AppendFilesForPidl(
198 HMENU hMenu,
199 LPCITEMIDLIST pidl,
200 BOOL bAddSeperator)
202 FIXME(shell,"0x%08x %p 0x%08x\n",hMenu, pidl,bAddSeperator);
203 return 0;
205 /*************************************************************************
206 * FileMenu_AddFilesForPidl [SHELL32.125]
208 * NOTES
209 * uEnumFlags any SHCONTF flag
211 int WINAPI FileMenu_AddFilesForPidl (
212 HMENU hMenu,
213 UINT uReserved,
214 UINT uID,
215 LPCITEMIDLIST pidl,
216 UINT uFlags,
217 UINT uEnumFlags,
218 LPFNFMCALLBACK lpfnCallback)
220 FIXME(shell,"0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
221 hMenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
222 pdump (pidl);
223 return 0;
228 /*************************************************************************
229 * FileMenu_TrackPopupMenuEx [SHELL32.116]
231 HRESULT WINAPI FileMenu_TrackPopupMenuEx (
232 HMENU hMenu,
233 UINT uFlags,
234 int x,
235 int y,
236 HWND hWnd,
237 LPTPMPARAMS lptpm)
239 FIXME(shell,"0x%08x 0x%08x 0x%x 0x%x 0x%08x %p stub\n",
240 hMenu, uFlags, x, y, hWnd, lptpm);
241 return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm);
244 /*************************************************************************
245 * FileMenu_GetLastSelectedItemPidls [SHELL32.107]
247 BOOL WINAPI FileMenu_GetLastSelectedItemPidls(
248 UINT uReserved,
249 LPCITEMIDLIST *ppidlFolder,
250 LPCITEMIDLIST *ppidlItem)
252 FIXME(shell,"0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
253 return 0;
256 /*************************************************************************
257 * FileMenu_MeasureItem [SHELL32.112]
259 LRESULT WINAPI FileMenu_MeasureItem(
260 HWND hWnd,
261 LPMEASUREITEMSTRUCT lpmis)
263 FIXME(shell,"0x%08x %p\n", hWnd, lpmis);
264 return 0;
267 /*************************************************************************
268 * FileMenu_DrawItem [SHELL32.105]
270 LRESULT WINAPI FileMenu_DrawItem(
271 HWND hWnd,
272 LPDRAWITEMSTRUCT lpdis)
274 FIXME(shell,"0x%08x %p\n", hWnd, lpdis);
275 return 0;
278 /*************************************************************************
279 * FileMenu_InitMenuPopup [SHELL32.109]
281 * NOTES
282 * The filemenu is a ownerdrawn menu. Call this function responding to
283 * WM_INITPOPUPMENU
286 HRESULT WINAPI FileMenu_InitMenuPopup (DWORD hmenu)
287 { FIXME(shell,"hmenu=0x%lx stub\n",hmenu);
288 return 0;
291 /*************************************************************************
292 * FileMenu_HandleMenuChar [SHELL32.108]
294 LRESULT WINAPI FileMenu_HandleMenuChar(
295 HMENU hMenu,
296 WPARAM wParam)
298 FIXME(shell,"0x%08x 0x%08x\n",hMenu,wParam);
299 return 0;
302 /*************************************************************************
303 * FileMenu_DeleteAllItems [SHELL32.104]
305 * NOTES
306 * exported by name
308 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hMenu)
310 FIXME(shell,"0x%08x stub\n", hMenu);
311 DestroyMenu (hMenu);
312 return TRUE;
315 /*************************************************************************
316 * FileMenu_DeleteItemByCmd [SHELL32.]
319 BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
321 TRACE(shell,"0x%08x 0x%08x\n", hMenu, uID);
323 DeleteMenu(hMenu, MF_BYCOMMAND, uID);
324 return TRUE;
327 /*************************************************************************
328 * FileMenu_DeleteItemByIndex [SHELL32.140]
330 BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
332 TRACE(shell,"0x%08x 0x%08x\n", hMenu, uPos);
334 DeleteMenu(hMenu, MF_BYPOSITION, uPos);
335 return TRUE;
338 /*************************************************************************
339 * FileMenu_DeleteItemByFirstID [SHELL32.141]
341 BOOL WINAPI FileMenu_DeleteItemByFirstID(
342 HMENU hMenu,
343 UINT uID)
345 TRACE(shell,"0x%08x 0x%08x\n", hMenu, uID);
346 return 0;
349 /*************************************************************************
350 * FileMenu_DeleteSeparator [SHELL32.142]
352 BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu)
354 TRACE(shell,"0x%08x\n", hMenu);
355 return 0;
358 /*************************************************************************
359 * FileMenu_EnableItemByCmd [SHELL32.143]
361 BOOL WINAPI FileMenu_EnableItemByCmd(
362 HMENU hMenu,
363 UINT uID,
364 BOOL bEnable)
366 TRACE(shell,"0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
367 return 0;
370 /*************************************************************************
371 * FileMenu_GetItemExtent [SHELL32.144]
374 DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos)
375 { RECT rect;
377 FIXME (shell,"0x%08x 0x%08x\n", hMenu, uPos);
379 if (GetMenuItemRect(0, hMenu, uPos, &rect))
380 { FIXME (shell,"0x%04x 0x%04x 0x%04x 0x%04x\n",
381 rect.right, rect.left, rect.top, rect.bottom);
382 return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom);
384 return 0x00200020; /*fixme*/
387 /*************************************************************************
388 * FileMenu_AbortInitMenu [SHELL32.120]
391 void WINAPI FileMenu_AbortInitMenu (void)
392 { TRACE(shell,"\n");
405 /*************************************************************************
406 * SHFind_InitMenuPopup [SHELL32.149]
409 * PARAMETERS
410 * hMenu [in] handel of menu previously created
411 * hWndParent [in] parent window
412 * w [in] no pointer
413 * x [in] no pointer
415 HRESULT WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, DWORD w, DWORD x)
416 { FIXME(shell,"hmenu=0x%08x hwnd=0x%08x 0x%08lx 0x%08lx stub\n",
417 hMenu,hWndParent,w,x);
418 return TRUE;
421 /*************************************************************************
422 * Shell_MergeMenus [SHELL32.67]
425 BOOL _SHIsMenuSeparator(HMENU hm, int i)
427 MENUITEMINFOA mii;
429 mii.cbSize = sizeof(MENUITEMINFOA);
430 mii.fMask = MIIM_TYPE;
431 mii.cch = 0; /* WARNING: We MUST initialize it to 0*/
432 if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
433 { return(FALSE);
436 if (mii.fType & MFT_SEPARATOR)
437 { return(TRUE);
440 return(FALSE);
442 #define MM_ADDSEPARATOR 0x00000001L
443 #define MM_SUBMENUSHAVEIDS 0x00000002L
444 HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
445 { int nItem;
446 HMENU hmSubMenu;
447 BOOL bAlreadySeparated;
448 MENUITEMINFOA miiSrc;
449 char szName[256];
450 UINT uTemp, uIDMax = uIDAdjust;
452 FIXME(shell,"hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x 0x%04lx stub\n",
453 hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
455 if (!hmDst || !hmSrc)
456 { return uIDMax;
459 nItem = GetMenuItemCount(hmDst);
460 if (uInsert >= (UINT)nItem)
461 { uInsert = (UINT)nItem;
462 bAlreadySeparated = TRUE;
464 else
465 { bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
467 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
468 { /* Add a separator between the menus */
469 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
470 bAlreadySeparated = TRUE;
474 /* Go through the menu items and clone them*/
475 for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
476 { miiSrc.cbSize = sizeof(MENUITEMINFOA);
477 miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
478 /* We need to reset this every time through the loop in case
479 menus DON'T have IDs*/
480 miiSrc.fType = MFT_STRING;
481 miiSrc.dwTypeData = szName;
482 miiSrc.dwItemData = 0;
483 miiSrc.cch = sizeof(szName);
485 if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
486 { continue;
488 if (miiSrc.fType & MFT_SEPARATOR)
489 { /* This is a separator; don't put two of them in a row*/
490 if (bAlreadySeparated)
491 { continue;
493 bAlreadySeparated = TRUE;
495 else if (miiSrc.hSubMenu)
496 { if (uFlags & MM_SUBMENUSHAVEIDS)
497 { /* Adjust the ID and check it*/
498 miiSrc.wID += uIDAdjust;
499 if (miiSrc.wID > uIDAdjustMax)
500 { continue;
502 if (uIDMax <= miiSrc.wID)
503 { uIDMax = miiSrc.wID + 1;
506 else
507 { /* Don't set IDs for submenus that didn't have them already */
508 miiSrc.fMask &= ~MIIM_ID;
510 hmSubMenu = miiSrc.hSubMenu;
511 miiSrc.hSubMenu = CreatePopupMenu();
512 if (!miiSrc.hSubMenu)
513 { return(uIDMax);
515 uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags&MM_SUBMENUSHAVEIDS);
516 if (uIDMax <= uTemp)
517 { uIDMax = uTemp;
519 bAlreadySeparated = FALSE;
521 else
522 { /* Adjust the ID and check it*/
523 miiSrc.wID += uIDAdjust;
524 if (miiSrc.wID > uIDAdjustMax)
525 { continue;
527 if (uIDMax <= miiSrc.wID)
528 { uIDMax = miiSrc.wID + 1;
530 bAlreadySeparated = FALSE;
532 if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
533 { return(uIDMax);
537 /* Ensure the correct number of separators at the beginning of the
538 inserted menu items*/
539 if (uInsert == 0)
540 { if (bAlreadySeparated)
541 { DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
544 else
545 { if (_SHIsMenuSeparator(hmDst, uInsert-1))
546 { if (bAlreadySeparated)
547 { DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
550 else
551 { if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
552 { /* Add a separator between the menus*/
553 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
557 return(uIDMax);