source: trunk/src/shell32/new/shlmenu.cpp@ 791

Last change on this file since 791 was 791, checked in by phaller, 26 years ago

Add: shell32/new - a direct port of WINE's Shell32 implmentation

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