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

Last change on this file since 1215 was 1215, checked in by sandervl, 26 years ago

Added $Id$

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