source: trunk/src/shell32/shlmenu.c@ 6823

Last change on this file since 6823 was 6709, checked in by sandervl, 24 years ago

restored old version

File size: 23.1 KB
Line 
1/*
2 * see www.geocities.com/SiliconValley/4942/filemenu.html
3 */
4#include <string.h>
5
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"
16
17#include "pidl.h"
18
19BOOL WINAPI FileMenu_DeleteAllItems (HMENU hMenu);
20BOOL WINAPI FileMenu_AppendItemA(HMENU hMenu, LPCSTR lpText, UINT uID, int icon, HMENU hMenuPopup, int nItemHeight);
21
22typedef struct
23{
24 BOOL bInitialized;
25 BOOL bFixedItems;
26 /* create */
27 COLORREF crBorderColor;
28 int nBorderWidth;
29 HBITMAP hBorderBmp;
30
31 /* insert using pidl */
32 LPITEMIDLIST pidl;
33 UINT uID;
34 UINT uFlags;
35 UINT uEnumFlags;
36 LPFNFMCALLBACK lpfnCallback;
37} FMINFO, *LPFMINFO;
38
39typedef struct
40{ int cchItemText;
41 int iIconIndex;
42 HMENU hMenu;
43 char szItemText[1];
44} FMITEM, * LPFMITEM;
45
46static BOOL bAbortInit;
47
48#define CCH_MAXITEMTEXT 256
49
50DEFAULT_DEBUG_CHANNEL(shell);
51
52LPFMINFO FM_GetMenuInfo(HMENU hmenu)
53{ MENUINFO MenuInfo;
54 LPFMINFO menudata;
55
56 MenuInfo.cbSize = sizeof(MENUINFO);
57 MenuInfo.fMask = MIM_MENUDATA;
58
59 if (! GetMenuInfo(hmenu, &MenuInfo))
60 return NULL;
61
62 menudata = (LPFMINFO)MenuInfo.dwMenuData;
63
64 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
65 {
66 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
67 return 0;
68 }
69
70 return menudata;
71
72}
73/*************************************************************************
74 * FM_SetMenuParameter [internal]
75 *
76 */
77static LPFMINFO FM_SetMenuParameter(
78 HMENU hmenu,
79 UINT uID,
80 LPCITEMIDLIST pidl,
81 UINT uFlags,
82 UINT uEnumFlags,
83 LPFNFMCALLBACK lpfnCallback)
84{
85 LPFMINFO menudata;
86
87 TRACE("\n");
88
89 menudata = FM_GetMenuInfo(hmenu);
90
91 if ( menudata->pidl)
92 { SHFree(menudata->pidl);
93 }
94
95 menudata->uID = uID;
96 menudata->pidl = ILClone(pidl);
97 menudata->uFlags = uFlags;
98 menudata->uEnumFlags = uEnumFlags;
99 menudata->lpfnCallback = lpfnCallback;
100
101 return menudata;
102}
103
104/*************************************************************************
105 * FM_InitMenuPopup [internal]
106 *
107 */
108static 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;
118
119 TRACE("0x%04x %p\n", hmenu, pAlternatePidl);
120
121 MenuInfo.cbSize = sizeof(MENUINFO);
122 MenuInfo.fMask = MIM_MENUDATA;
123
124 if (! GetMenuInfo(hmenu, &MenuInfo))
125 return FALSE;
126
127 menudata = (LPFMINFO)MenuInfo.dwMenuData;
128
129 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
130 {
131 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
132 return 0;
133 }
134
135 if (menudata->bInitialized)
136 return 0;
137
138 pidl = ((pAlternatePidl) ? pAlternatePidl : menudata->pidl);
139 if (!pidl)
140 return 0;
141
142 uID = menudata->uID;
143 uFlags = menudata->uFlags;
144 uEnumFlags = menudata->uEnumFlags;
145 lpfnCallback = menudata->lpfnCallback;
146 menudata->bInitialized = FALSE;
147
148 SetMenuInfo(hmenu, &MenuInfo);
149
150 if (SUCCEEDED (SHGetDesktopFolder(&lpsf)))
151 {
152 if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
153 {
154 IEnumIDList *lpe = NULL;
155
156 if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe )))
157 {
158
159 LPITEMIDLIST pidlTemp = NULL;
160 ULONG ulFetched;
161
162 while ((!bAbortInit) && (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched)))
163 {
164 if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr)))
165 {
166 ILGetDisplayName( pidlTemp, sTemp);
167 if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, 0, &iIcon)))
168 iIcon = FM_BLANK_ICON;
169 if ( SFGAO_FOLDER & ulItemAttr)
170 {
171 LPFMINFO lpFmMi;
172 MENUINFO MenuInfo;
173 HMENU hMenuPopup = CreatePopupMenu();
174
175 lpFmMi = (LPFMINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
176
177 lpFmMi->pidl = ILCombine(pidl, pidlTemp);
178 lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
179
180 MenuInfo.cbSize = sizeof(MENUINFO);
181 MenuInfo.fMask = MIM_MENUDATA;
182 MenuInfo.dwMenuData = (DWORD) lpFmMi;
183 SetMenuInfo (hMenuPopup, &MenuInfo);
184
185 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
186 }
187 else
188 {
189 ((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
190 FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
191 }
192 }
193
194 if (lpfnCallback)
195 {
196 TRACE("enter callback\n");
197 lpfnCallback ( pidl, pidlTemp);
198 TRACE("leave callback\n");
199 }
200
201 NumberOfItems++;
202 }
203 IEnumIDList_Release (lpe);
204 }
205 IShellFolder_Release(lpsf2);
206 }
207 IShellFolder_Release(lpsf);
208 }
209
210 if ( GetMenuItemCount (hmenu) == 0 )
211 { FileMenu_AppendItemA (hmenu, "(empty)", uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
212 NumberOfItems++;
213 }
214
215 menudata->bInitialized = TRUE;
216 SetMenuInfo(hmenu, &MenuInfo);
217
218 return NumberOfItems;
219}
220/*************************************************************************
221 * FileMenu_Create [SHELL32.114]
222 *
223 * NOTES
224 * for non-root menus values are
225 * (ffffffff,00000000,00000000,00000000,00000000)
226 */
227HMENU WINAPI FileMenu_Create (
228 COLORREF crBorderColor,
229 int nBorderWidth,
230 HBITMAP hBorderBmp,
231 int nSelHeight,
232 UINT uFlags)
233{
234 MENUINFO MenuInfo;
235 LPFMINFO menudata;
236
237 HMENU hMenu = CreatePopupMenu();
238
239 TRACE("0x%08lx 0x%08x 0x%08x 0x%08x 0x%08x hMenu=0x%08x\n",
240 crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, hMenu);
241
242 menudata = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
243 menudata->crBorderColor = crBorderColor;
244 menudata->nBorderWidth = nBorderWidth;
245 menudata->hBorderBmp = hBorderBmp;
246
247 MenuInfo.cbSize = sizeof(MENUINFO);
248 MenuInfo.fMask = MIM_MENUDATA;
249 MenuInfo.dwMenuData = (DWORD) menudata;
250 SetMenuInfo (hMenu, &MenuInfo);
251
252 return hMenu;
253}
254
255/*************************************************************************
256 * FileMenu_Destroy [SHELL32.118]
257 *
258 * NOTES
259 * exported by name
260 */
261void WINAPI FileMenu_Destroy (HMENU hmenu)
262{
263 LPFMINFO menudata;
264
265 TRACE("0x%08x\n", hmenu);
266
267 FileMenu_DeleteAllItems (hmenu);
268
269 menudata = FM_GetMenuInfo(hmenu);
270
271 if ( menudata->pidl)
272 { SHFree( menudata->pidl);
273 }
274 HeapFree(GetProcessHeap(), 0, menudata);
275
276 DestroyMenu (hmenu);
277}
278
279/*************************************************************************
280 * FileMenu_AppendItemAW [SHELL32.115]
281 *
282 */
283BOOL WINAPI FileMenu_AppendItemA(
284 HMENU hMenu,
285 LPCSTR lpText,
286 UINT uID,
287 int icon,
288 HMENU hMenuPopup,
289 int nItemHeight)
290{
291 LPSTR lpszText = (LPSTR)lpText;
292 MENUITEMINFOA mii;
293 LPFMITEM myItem;
294 LPFMINFO menudata;
295 MENUINFO MenuInfo;
296
297
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);
301
302 ZeroMemory (&mii, sizeof(MENUITEMINFOA));
303
304 mii.cbSize = sizeof(MENUITEMINFOA);
305
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;
315 }
316
317 if ( hMenuPopup )
318 { /* sub menu */
319 mii.fMask |= MIIM_TYPE | MIIM_SUBMENU;
320 mii.fType = MFT_OWNERDRAW;
321 mii.hSubMenu = hMenuPopup;
322 }
323 else if (lpText == FM_SEPARATOR )
324 { mii.fMask |= MIIM_ID | MIIM_TYPE;
325 mii.fType = MFT_SEPARATOR;
326 }
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;
332 }
333 mii.wID = uID;
334
335 InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
336
337 /* set bFixedItems to true */
338 MenuInfo.cbSize = sizeof(MENUINFO);
339 MenuInfo.fMask = MIM_MENUDATA;
340
341 if (! GetMenuInfo(hMenu, &MenuInfo))
342 return FALSE;
343
344 menudata = (LPFMINFO)MenuInfo.dwMenuData;
345 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
346 {
347 ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
348 return 0;
349 }
350
351 menudata->bFixedItems = TRUE;
352 SetMenuInfo(hMenu, &MenuInfo);
353
354 return TRUE;
355
356}
357
358/**********************************************************************/
359
360BOOL WINAPI FileMenu_AppendItemAW(
361 HMENU hMenu,
362 LPCVOID lpText,
363 UINT uID,
364 int icon,
365 HMENU hMenuPopup,
366 int nItemHeight)
367{
368 BOOL ret;
369 LPSTR lpszText=NULL;
370
371 if (SHELL_OsIsUnicode() && (lpText!=FM_SEPARATOR))
372 lpszText = HEAP_strdupWtoA ( GetProcessHeap(),0, lpText);
373
374 ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : lpText, uID, icon, hMenuPopup, nItemHeight);
375
376 if (lpszText)
377 HeapFree( GetProcessHeap(), 0, lpszText );
378
379 return ret;
380}
381/*************************************************************************
382 * FileMenu_InsertUsingPidl [SHELL32.110]
383 *
384 * NOTES
385 * uEnumFlags any SHCONTF flag
386 */
387int WINAPI FileMenu_InsertUsingPidl (
388 HMENU hmenu,
389 UINT uID,
390 LPCITEMIDLIST pidl,
391 UINT uFlags,
392 UINT uEnumFlags,
393 LPFNFMCALLBACK lpfnCallback)
394{
395 TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
396 hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
397
398 pdump (pidl);
399
400 bAbortInit = FALSE;
401
402 FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
403
404 return FM_InitMenuPopup(hmenu, NULL);
405}
406
407/*************************************************************************
408 * FileMenu_ReplaceUsingPidl [SHELL32.113]
409 *
410 * FIXME: the static items are deleted but wont be refreshed
411 */
412int WINAPI FileMenu_ReplaceUsingPidl(
413 HMENU hmenu,
414 UINT uID,
415 LPCITEMIDLIST pidl,
416 UINT uEnumFlags,
417 LPFNFMCALLBACK lpfnCallback)
418{
419 TRACE("0x%08x 0x%08x %p 0x%08x %p\n",
420 hmenu, uID, pidl, uEnumFlags, lpfnCallback);
421
422 FileMenu_DeleteAllItems (hmenu);
423
424 FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback);
425
426 return FM_InitMenuPopup(hmenu, NULL);
427}
428
429/*************************************************************************
430 * FileMenu_Invalidate [SHELL32.111]
431 */
432void WINAPI FileMenu_Invalidate (HMENU hMenu)
433{
434 FIXME("0x%08x\n",hMenu);
435}
436
437/*************************************************************************
438 * FileMenu_FindSubMenuByPidl [SHELL32.106]
439 */
440HMENU WINAPI FileMenu_FindSubMenuByPidl(
441 HMENU hMenu,
442 LPCITEMIDLIST pidl)
443{
444 FIXME("0x%08x %p\n",hMenu, pidl);
445 return 0;
446}
447
448/*************************************************************************
449 * FileMenu_AppendFilesForPidl [SHELL32.124]
450 */
451int WINAPI FileMenu_AppendFilesForPidl(
452 HMENU hmenu,
453 LPCITEMIDLIST pidl,
454 BOOL bAddSeperator)
455{
456 LPFMINFO menudata;
457
458 menudata = FM_GetMenuInfo(hmenu);
459
460 menudata->bInitialized = FALSE;
461
462 FM_InitMenuPopup(hmenu, pidl);
463
464 if (bAddSeperator)
465 FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
466
467 TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator);
468
469 return 0;
470}
471/*************************************************************************
472 * FileMenu_AddFilesForPidl [SHELL32.125]
473 *
474 * NOTES
475 * uEnumFlags any SHCONTF flag
476 */
477int WINAPI FileMenu_AddFilesForPidl (
478 HMENU hmenu,
479 UINT uReserved,
480 UINT uID,
481 LPCITEMIDLIST pidl,
482 UINT uFlags,
483 UINT uEnumFlags,
484 LPFNFMCALLBACK lpfnCallback)
485{
486 TRACE("0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
487 hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
488
489 return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
490
491}
492
493
494/*************************************************************************
495 * FileMenu_TrackPopupMenuEx [SHELL32.116]
496 */
497BOOL WINAPI FileMenu_TrackPopupMenuEx (
498 HMENU hMenu,
499 UINT uFlags,
500 int x,
501 int y,
502 HWND hWnd,
503 LPTPMPARAMS lptpm)
504{
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);
508}
509
510/*************************************************************************
511 * FileMenu_GetLastSelectedItemPidls [SHELL32.107]
512 */
513BOOL WINAPI FileMenu_GetLastSelectedItemPidls(
514 UINT uReserved,
515 LPCITEMIDLIST *ppidlFolder,
516 LPCITEMIDLIST *ppidlItem)
517{
518 FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
519 return 0;
520}
521
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]
530 */
531LRESULT WINAPI FileMenu_MeasureItem(
532 HWND hWnd,
533 LPMEASUREITEMSTRUCT lpmis)
534{
535 LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
536 HDC hdc = GetDC(hWnd);
537 SIZE size;
538 LPFMINFO menuinfo;
539
540 TRACE("0x%08x %p %s\n", hWnd, lpmis, pMyItem->szItemText);
541
542 GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
543
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);
546
547 /* add the menubitmap */
548 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
549 if (menuinfo->nBorderWidth)
550 lpmis->itemWidth += menuinfo->nBorderWidth;
551
552 TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight);
553 ReleaseDC (hWnd, hdc);
554 return 0;
555}
556/*************************************************************************
557 * FileMenu_DrawItem [SHELL32.105]
558 */
559LRESULT WINAPI FileMenu_DrawItem(
560 HWND hWnd,
561 LPDRAWITEMSTRUCT lpdis)
562{
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;
569
570 TRACE("0x%08x %p %s\n", hWnd, lpdis, pMyItem->szItemText);
571
572 if (lpdis->itemState & ODS_SELECTED)
573 {
574 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
575 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
576 }
577 else
578 {
579 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT));
580 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU));
581 }
582
583 CopyRect(&TextRect, &(lpdis->rcItem));
584
585 /* add the menubitmap */
586 menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
587 if (menuinfo->nBorderWidth)
588 TextRect.left += menuinfo->nBorderWidth;
589
590 BorderRect.right = menuinfo->nBorderWidth;
591/* FillRect(lpdis->hDC, &BorderRect, CreateSolidBrush( menuinfo->crBorderColor));
592*/
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;
597
598 xt = xi + FM_ICON_SIZE + FM_SPACE2;
599 yt = yi;
600
601 ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
602
603 Shell_GetImageList(0, &hImageList);
604 ImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
605
606 TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom);
607
608 SetTextColor(lpdis->hDC, clrPrevText);
609 SetBkColor(lpdis->hDC, clrPrevBkgnd);
610
611 return TRUE;
612}
613
614/*************************************************************************
615 * FileMenu_InitMenuPopup [SHELL32.109]
616 *
617 * NOTES
618 * The filemenu is a ownerdrawn menu. Call this function responding to
619 * WM_INITPOPUPMENU
620 *
621 */
622BOOL WINAPI FileMenu_InitMenuPopup (HMENU hmenu)
623{
624 FM_InitMenuPopup(hmenu, NULL);
625 return TRUE;
626}
627
628/*************************************************************************
629 * FileMenu_HandleMenuChar [SHELL32.108]
630 */
631LRESULT WINAPI FileMenu_HandleMenuChar(
632 HMENU hMenu,
633 WPARAM wParam)
634{
635 FIXME("0x%08x 0x%08x\n",hMenu,wParam);
636 return 0;
637}
638
639/*************************************************************************
640 * FileMenu_DeleteAllItems [SHELL32.104]
641 *
642 * NOTES
643 * exported by name
644 */
645BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
646{
647 MENUITEMINFOA mii;
648 LPFMINFO menudata;
649
650 int i;
651
652 TRACE("0x%08x\n", hmenu);
653
654 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
655 mii.cbSize = sizeof(MENUITEMINFOA);
656 mii.fMask = MIIM_SUBMENU|MIIM_DATA;
657
658 for (i = 0; i < GetMenuItemCount( hmenu ); i++)
659 { GetMenuItemInfoA(hmenu, i, TRUE, &mii );
660
661 if (mii.dwItemData)
662 SHFree((LPFMINFO)mii.dwItemData);
663
664 if (mii.hSubMenu)
665 FileMenu_Destroy(mii.hSubMenu);
666 }
667
668 while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
669
670 menudata = FM_GetMenuInfo(hmenu);
671
672 menudata->bInitialized = FALSE;
673
674 return TRUE;
675}
676
677/*************************************************************************
678 * FileMenu_DeleteItemByCmd [SHELL32.]
679 *
680 */
681BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
682{
683 MENUITEMINFOA mii;
684
685 TRACE("0x%08x 0x%08x\n", hMenu, uID);
686
687 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
688 mii.cbSize = sizeof(MENUITEMINFOA);
689 mii.fMask = MIIM_SUBMENU;
690
691 GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
692 if ( mii.hSubMenu )
693 {
694 /* FIXME: Do what? */
695 }
696
697 DeleteMenu(hMenu, MF_BYCOMMAND, uID);
698 return TRUE;
699}
700
701/*************************************************************************
702 * FileMenu_DeleteItemByIndex [SHELL32.140]
703 */
704BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
705{
706 MENUITEMINFOA mii;
707
708 TRACE("0x%08x 0x%08x\n", hMenu, uPos);
709
710 ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
711 mii.cbSize = sizeof(MENUITEMINFOA);
712 mii.fMask = MIIM_SUBMENU;
713
714 GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
715 if ( mii.hSubMenu )
716 {
717 /* FIXME: Do what? */
718 }
719
720 DeleteMenu(hMenu, MF_BYPOSITION, uPos);
721 return TRUE;
722}
723
724/*************************************************************************
725 * FileMenu_DeleteItemByFirstID [SHELL32.141]
726 */
727BOOL WINAPI FileMenu_DeleteItemByFirstID(
728 HMENU hMenu,
729 UINT uID)
730{
731 TRACE("0x%08x 0x%08x\n", hMenu, uID);
732 return 0;
733}
734
735/*************************************************************************
736 * FileMenu_DeleteSeparator [SHELL32.142]
737 */
738BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu)
739{
740 TRACE("0x%08x\n", hMenu);
741 return 0;
742}
743
744/*************************************************************************
745 * FileMenu_EnableItemByCmd [SHELL32.143]
746 */
747BOOL WINAPI FileMenu_EnableItemByCmd(
748 HMENU hMenu,
749 UINT uID,
750 BOOL bEnable)
751{
752 TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
753 return 0;
754}
755
756/*************************************************************************
757 * FileMenu_GetItemExtent [SHELL32.144]
758 *
759 * NOTES
760 * if the menu is to big, entrys are getting cut away!!
761 */
762DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos)
763{ RECT rect;
764
765 FIXME("0x%08x 0x%08x\n", hMenu, uPos);
766
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);
771 }
772 return 0x00100010; /*fixme*/
773}
774
775/*************************************************************************
776 * FileMenu_AbortInitMenu [SHELL32.120]
777 *
778 */
779void WINAPI FileMenu_AbortInitMenu (void)
780{ TRACE("\n");
781 bAbortInit = TRUE;
782}
783
784/*************************************************************************
785 * SHFind_InitMenuPopup [SHELL32.149]
786 *
787 *
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)
793 *
794 * RETURNS
795 * LPXXXXX pointer to struct containing a func addr at offset 8
796 * or NULL at failure.
797 */
798LPVOID 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 */
802}
803
804/*************************************************************************
805 * Shell_MergeMenus [SHELL32.67]
806 *
807 */
808BOOL _SHIsMenuSeparator(HMENU hm, int i)
809{
810 MENUITEMINFOA mii;
811
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))
816 {
817 return(FALSE);
818 }
819
820 if (mii.fType & MFT_SEPARATOR)
821 {
822 return(TRUE);
823 }
824
825 return(FALSE);
826}
827
828/**********************************************************************/
829
830HRESULT 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;
837
838 TRACE("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x 0x%04lx\n",
839 hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
840
841 if (!hmDst || !hmSrc)
842 { return uIDMax;
843 }
844
845 nItem = GetMenuItemCount(hmDst);
846
847 if (uInsert >= (UINT)nItem) /* insert position inside menu? */
848 {
849 uInsert = (UINT)nItem; /* append on the end */
850 bAlreadySeparated = TRUE;
851 }
852 else
853 {
854 bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
855 }
856
857 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
858 {
859 /* Add a separator between the menus */
860 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
861 bAlreadySeparated = TRUE;
862 }
863
864
865 /* Go through the menu items and clone them*/
866 for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
867 {
868 miiSrc.cbSize = sizeof(MENUITEMINFOA);
869 miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
870
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);
876
877 if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
878 {
879 continue;
880 }
881
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);
883*/
884 if (miiSrc.fType & MFT_SEPARATOR)
885 {
886 /* This is a separator; don't put two of them in a row */
887 if (bAlreadySeparated)
888 continue;
889
890 bAlreadySeparated = TRUE;
891 }
892 else if (miiSrc.hSubMenu)
893 {
894 if (uFlags & MM_SUBMENUSHAVEIDS)
895 {
896 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
897
898 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
899 continue;
900
901 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
902 uIDMax = miiSrc.wID + 1;
903 }
904 else
905 {
906 miiSrc.fMask &= ~MIIM_ID; /* Don't set IDs for submenus that didn't have them already */
907 }
908 hmSubMenu = miiSrc.hSubMenu;
909
910 miiSrc.hSubMenu = CreatePopupMenu();
911
912 if (!miiSrc.hSubMenu) return(uIDMax);
913
914 uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS);
915
916 if (uIDMax <= uTemp)
917 uIDMax = uTemp;
918
919 bAlreadySeparated = FALSE;
920 }
921 else /* normal menu item */
922 {
923 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */
924
925 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */
926 continue;
927
928 if (uIDMax <= miiSrc.wID) /* remember the highest ID */
929 uIDMax = miiSrc.wID + 1;
930
931 bAlreadySeparated = FALSE;
932 }
933
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);
935*/
936 if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
937 {
938 return(uIDMax);
939 }
940 }
941
942 /* Ensure the correct number of separators at the beginning of the
943 inserted menu items*/
944 if (uInsert == 0)
945 {
946 if (bAlreadySeparated)
947 {
948 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
949 }
950 }
951 else
952 {
953 if (_SHIsMenuSeparator(hmDst, uInsert-1))
954 {
955 if (bAlreadySeparated)
956 {
957 DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
958 }
959 }
960 else
961 {
962 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
963 {
964 /* Add a separator between the menus*/
965 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
966 }
967 }
968 }
969 return(uIDMax);
970}
971
Note: See TracBrowser for help on using the repository browser.