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

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

Add: update to wine/shell32 1999/11/02 #4

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