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

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

.

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