source: trunk/src/shell32/shlmenu.cpp@ 1470

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

Fix: debug info

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