4 * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * Start menu button context menu
27 typedef struct _STARTMNU_CTMENU_CTX
31 } STARTMNU_CTMENU_CTX
, *PSTARTMNU_CTMENU_CTX
;
34 CreateStartContextMenu(IN HWND hWndOwner
,
35 IN PVOID
*ppcmContext
,
36 IN PVOID Context OPTIONAL
);
39 OnStartContextMenuCommand(IN HWND hWndOwner
,
41 IN PVOID pcmContext OPTIONAL
,
42 IN PVOID Context OPTIONAL
);
44 const TRAYWINDOW_CTXMENU StartMenuBtnCtxMenu
= {
45 CreateStartContextMenu
,
46 OnStartContextMenuCommand
50 CreateContextMenuFromShellFolderPidl(IN HWND hWndOwner
,
51 IN OUT IShellFolder
*psf
,
52 IN OUT LPITEMIDLIST pidl
,
53 OUT IContextMenu
**ppcm
)
59 hRet
= IShellFolder_GetUIObjectOf(psf
,
62 (LPCITEMIDLIST
*)&pidl
,
68 hPopup
= CreatePopupMenu();
72 hRet
= IContextMenu_QueryContextMenu(pcm
,
88 IContextMenu_Release(pcm
);
95 OnStartContextMenuCommand(IN HWND hWndOwner
,
97 IN PVOID pcmContext OPTIONAL
,
98 IN PVOID Context OPTIONAL
)
100 PSTARTMNU_CTMENU_CTX psmcmc
= pcmContext
;
104 if ((uiCmdId
>= ID_SHELL_CMD_FIRST
) && (uiCmdId
<= ID_SHELL_CMD_LAST
))
106 CMINVOKECOMMANDINFO cmici
= {0};
107 CHAR szDir
[MAX_PATH
];
109 /* Setup and invoke the shell command */
110 cmici
.cbSize
= sizeof(cmici
);
111 cmici
.hwnd
= hWndOwner
;
112 cmici
.lpVerb
= (LPCSTR
)MAKEINTRESOURCE(uiCmdId
- ID_SHELL_CMD_FIRST
);
113 cmici
.nShow
= SW_NORMAL
;
115 /* FIXME: Support Unicode!!! */
116 if (SHGetPathFromIDListA(psmcmc
->pidl
,
119 cmici
.lpDirectory
= szDir
;
122 IContextMenu_InvokeCommand(psmcmc
->pcm
,
127 ITrayWindow_ExecContextMenuCmd((ITrayWindow
*)Context
,
132 IContextMenu_Release(psmcmc
->pcm
);
134 HeapFree(hProcessHeap
,
140 AddStartContextMenuItems(IN HWND hWndOwner
,
143 TCHAR szBuf
[MAX_PATH
];
146 /* Add the "Open All Users" menu item */
147 if (LoadString(hExplorerInstance
,
150 sizeof(szBuf
) / sizeof(szBuf
[0])))
154 ID_SHELL_CMD_PROPERTIES
,
158 if (!SHRestricted(REST_NOCOMMONGROUPS
))
160 /* Check if we should add menu items for the common start menu */
161 hRet
= SHGetFolderPath(hWndOwner
,
162 CSIDL_COMMON_STARTMENU
,
166 if (SUCCEEDED(hRet
) && hRet
!= S_FALSE
)
168 /* The directory exists, but only show the items if the
169 user can actually make any changes to the common start
170 menu. This is most likely only the case if the user
171 has administrative rights! */
179 /* Add the "Open All Users" menu item */
180 if (LoadString(hExplorerInstance
,
183 sizeof(szBuf
) / sizeof(szBuf
[0])))
187 ID_SHELL_CMD_OPEN_ALL_USERS
,
191 /* Add the "Explore All Users" menu item */
192 if (LoadString(hExplorerInstance
,
193 IDS_EXPLORE_ALL_USERS
,
195 sizeof(szBuf
) / sizeof(szBuf
[0])))
199 ID_SHELL_CMD_EXPLORE_ALL_USERS
,
208 CreateStartContextMenu(IN HWND hWndOwner
,
209 IN PVOID
*ppcmContext
,
210 IN PVOID Context OPTIONAL
)
212 LPITEMIDLIST pidlStart
, pidlLast
;
213 IShellFolder
*psfStart
, *psfDesktop
;
218 pidlStart
= SHCloneSpecialIDList(hWndOwner
,
222 if (pidlStart
!= NULL
)
224 pidlLast
= ILClone(ILFindLastID(pidlStart
));
225 ILRemoveLastID(pidlStart
);
227 if (pidlLast
!= NULL
)
229 hRet
= SHGetDesktopFolder(&psfDesktop
);
232 hRet
= IShellFolder_BindToObject(psfDesktop
,
239 hPopup
= CreateContextMenuFromShellFolderPidl(hWndOwner
,
246 PSTARTMNU_CTMENU_CTX psmcmc
;
248 psmcmc
= HeapAlloc(hProcessHeap
,
254 psmcmc
->pidl
= pidlLast
;
256 AddStartContextMenuItems(hWndOwner
,
259 *ppcmContext
= psmcmc
;
264 IContextMenu_Release(pcm
);
271 IShellFolder_Release(psfStart
);
274 IShellFolder_Release(psfDesktop
);
286 /*****************************************************************************
287 ** IStartMenuSite ***********************************************************
288 *****************************************************************************/
290 static const IStartMenuSiteVtbl IStartMenuSiteImpl_Vtbl
;
291 static const IServiceProviderVtbl IServiceProviderImpl_Vtbl
;
292 static const ITrayPrivVtbl ITrayPrivImpl_Vtbl
;
293 static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl
;
294 static const IMenuPopupVtbl IMenuPopupImpl_Vtbl
;
298 const IStartMenuSiteVtbl
*lpVtbl
;
299 const IServiceProviderVtbl
*lpServiceProviderVtbl
;
300 const ITrayPrivVtbl
*lpStartMenuCallbackVtbl
;
301 const IOleCommandTargetVtbl
*lpOleCommandTargetVtbl
;
302 const IMenuPopupVtbl
*lpMenuPopupVtbl
;
307 IMenuPopup
* StartMenuPopup
;
308 } IStartMenuSiteImpl
;
311 IUnknown_from_IStartMenuSiteImpl(IStartMenuSiteImpl
*This
)
313 return (IUnknown
*)&This
->lpVtbl
;
316 IMPL_CASTS(IStartMenuSite
, IStartMenuSite
, lpVtbl
)
317 IMPL_CASTS(IServiceProvider
, IStartMenuSite
, lpServiceProviderVtbl
)
318 IMPL_CASTS(ITrayPriv
, IStartMenuSite
, lpStartMenuCallbackVtbl
)
319 IMPL_CASTS(IOleCommandTarget
, IStartMenuSite
, lpOleCommandTargetVtbl
)
320 IMPL_CASTS(IDeskBar
, IStartMenuSite
, lpMenuPopupVtbl
)
321 IMPL_CASTS(IMenuPopup
, IStartMenuSite
, lpMenuPopupVtbl
)
323 /*******************************************************************/
325 static ULONG STDMETHODCALLTYPE
326 IStartMenuSiteImpl_AddRef(IN OUT IStartMenuSite
*iface
)
328 IStartMenuSiteImpl
*This
= IStartMenuSiteImpl_from_IStartMenuSite(iface
);
330 return InterlockedIncrement(&This
->Ref
);
334 IStartMenuSiteImpl_Free(IN OUT IStartMenuSiteImpl
*This
)
336 HeapFree(hProcessHeap
,
341 static ULONG STDMETHODCALLTYPE
342 IStartMenuSiteImpl_Release(IN OUT IStartMenuSite
*iface
)
344 IStartMenuSiteImpl
*This
= IStartMenuSiteImpl_from_IStartMenuSite(iface
);
347 Ret
= InterlockedDecrement(&This
->Ref
);
350 IStartMenuSiteImpl_Free(This
);
355 static HRESULT STDMETHODCALLTYPE
356 IStartMenuSiteImpl_QueryInterface(IN OUT IStartMenuSite
*iface
,
360 IStartMenuSiteImpl
*This
;
365 This
= IStartMenuSiteImpl_from_IStartMenuSite(iface
);
370 *ppvObj
= IUnknown_from_IStartMenuSiteImpl(This
);
372 else if (IsEqualIID(riid
,
373 &IID_IServiceProvider
))
375 *ppvObj
= IServiceProvider_from_IStartMenuSiteImpl(This
);
377 else if (IsEqualIID(riid
,
382 *ppvObj
= ITrayPriv_from_IStartMenuSiteImpl(This
);
384 else if (IsEqualIID(riid
,
385 &IID_IOleCommandTarget
))
387 *ppvObj
= IOleCommandTarget_from_IStartMenuSiteImpl(This
);
389 else if (IsEqualIID(riid
,
392 *ppvObj
= IDeskBar_from_IStartMenuSiteImpl(This
);
394 else if (IsEqualIID(riid
,
397 *ppvObj
= IMenuPopup_from_IStartMenuSiteImpl(This
);
401 TRACE("IStartMenuSite::QueryInterface queried unsupported interface: "
402 "{0x%8x,0x%4x,0x%4x,{0x%2x,0x%2x,0x%2x,0x%2x,0x%2x,0x%2x,0x%2x,0x%2x}}\n",
403 riid
->Data1
, riid
->Data2
, riid
->Data3
, riid
->Data4
[0], riid
->Data4
[1],
404 riid
->Data4
[2], riid
->Data4
[3], riid
->Data4
[4], riid
->Data4
[5],
405 riid
->Data4
[6], riid
->Data4
[7]);
407 return E_NOINTERFACE
;
410 IStartMenuSiteImpl_AddRef(iface
);
414 static const IStartMenuSiteVtbl IStartMenuSiteImpl_Vtbl
=
416 /*** IUnknown methods ***/
417 IStartMenuSiteImpl_QueryInterface
,
418 IStartMenuSiteImpl_AddRef
,
419 IStartMenuSiteImpl_Release
,
420 /*** IStartMenuSite methods ***/
423 /*******************************************************************/
425 METHOD_IUNKNOWN_INHERITED_ADDREF(IServiceProvider
, IStartMenuSite
)
426 METHOD_IUNKNOWN_INHERITED_RELEASE(IServiceProvider
, IStartMenuSite
)
427 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IServiceProvider
, IStartMenuSite
)
429 static HRESULT STDMETHODCALLTYPE
430 IStartMenuSiteImpl_QueryService(IN OUT IServiceProvider
*iface
,
431 IN REFGUID guidService
,
433 OUT PVOID
*ppvObject
)
435 IStartMenuSiteImpl
*This
= IStartMenuSiteImpl_from_IServiceProvider(iface
);
437 if (IsEqualGUID(guidService
,
440 return IStartMenuSiteImpl_QueryInterface(IStartMenuSite_from_IStartMenuSiteImpl(This
),
445 return E_NOINTERFACE
;
448 static const IServiceProviderVtbl IServiceProviderImpl_Vtbl
=
450 /*** IUnknown methods ***/
451 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IServiceProvider
, IStartMenuSite
),
452 METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IServiceProvider
, IStartMenuSite
),
453 METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IServiceProvider
, IStartMenuSite
),
454 /*** IServiceProvider methods ***/
455 IStartMenuSiteImpl_QueryService
458 /*******************************************************************/
460 METHOD_IUNKNOWN_INHERITED_ADDREF(ITrayPriv
, IStartMenuSite
)
461 METHOD_IUNKNOWN_INHERITED_RELEASE(ITrayPriv
, IStartMenuSite
)
462 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(ITrayPriv
, IStartMenuSite
)
464 static HRESULT STDMETHODCALLTYPE
465 IStartMenuSiteImpl_GetWindow(IN OUT ITrayPriv
*iface
,
468 IStartMenuSiteImpl
*This
= IStartMenuSiteImpl_from_ITrayPriv(iface
);
469 TRACE("ITrayPriv::GetWindow\n");
471 *phwnd
= ITrayWindow_GetHWND(This
->Tray
);
478 static HRESULT STDMETHODCALLTYPE
479 IStartMenuSiteImpl_ContextSensitiveHelp(IN OUT ITrayPriv
*iface
,
482 TRACE("ITrayPriv::ContextSensitiveHelp\n");
486 static HRESULT STDMETHODCALLTYPE
487 IStartMenuSiteImpl_Execute(IN OUT ITrayPriv
*iface
,
488 IN IShellFolder
*pShellFolder
,
489 IN LPCITEMIDLIST pidl
)
492 HRESULT ret
= S_FALSE
;
494 IStartMenuSiteImpl
*This
= IStartMenuSiteImpl_from_ITrayPriv(iface
);
496 TRACE("ITrayPriv::Execute\n");
498 hShlwapi
= GetModuleHandle(TEXT("SHLWAPI.DLL"));
499 if (hShlwapi
!= NULL
)
501 SHINVDEFCMD SHInvokeDefCmd
;
503 /* SHInvokeDefaultCommand */
504 SHInvokeDefCmd
= (SHINVDEFCMD
)GetProcAddress(hShlwapi
,
505 (LPCSTR
)((LONG
)279));
506 if (SHInvokeDefCmd
!= NULL
)
508 ret
= SHInvokeDefCmd(ITrayWindow_GetHWND(This
->Tray
),
517 static HRESULT STDMETHODCALLTYPE
518 IStartMenuSiteImpl_Unknown(IN OUT ITrayPriv
*iface
,
524 TRACE("ITrayPriv::Unknown(0x%p,0x%p,0x%p,0x%p)\n", Unknown1
, Unknown2
, Unknown3
, Unknown4
);
529 ShowUndockMenuItem(VOID
)
531 TRACE("ShowUndockMenuItem() not implemented!\n");
532 /* FIXME: How do we detect this?! */
537 ShowSynchronizeMenuItem(VOID
)
539 TRACE("ShowSynchronizeMenuItem() not implemented!\n");
540 /* FIXME: How do we detect this?! */
544 static HRESULT STDMETHODCALLTYPE
545 IStartMenuSiteImpl_AppendMenu(IN OUT ITrayPriv
*iface
,
548 HMENU hMenu
, hSettingsMenu
;
551 UINT uLastItemsCount
= 5; /* 5 menu items below the last separator */
554 TRACE("ITrayPriv::AppendMenu\n");
556 hMenu
= LoadPopupMenu(hExplorerInstance
,
557 MAKEINTRESOURCE(IDM_STARTMENU
));
562 /* Remove menu items that don't apply */
564 dwLogoff
= SHRestricted(REST_STARTMENULOGOFF
);
565 bWantLogoff
= (dwLogoff
== 2 ||
566 SHRestricted(REST_FORCESTARTMENULOGOFF
) ||
567 GetExplorerRegValueSet(HKEY_CURRENT_USER
,
569 TEXT("StartMenuLogoff")));
572 if (!GetExplorerRegValueSet(HKEY_CURRENT_USER
,
574 TEXT("StartMenuFavorites")))
582 if (SHRestricted(REST_NORECENTDOCSMENU
))
590 hSettingsMenu
= FindSubMenu(hMenu
,
593 if (hSettingsMenu
!= NULL
)
595 if (SHRestricted(REST_NOSETFOLDERS
))
598 if (SHRestricted(REST_NOCONTROLPANEL
))
600 DeleteMenu(hSettingsMenu
,
604 /* Delete the separator below it */
605 DeleteMenu(hSettingsMenu
,
610 /* Network Connections */
611 if (SHRestricted(REST_NONETWORKCONNECTIONS
))
613 DeleteMenu(hSettingsMenu
,
614 IDM_NETWORKCONNECTIONS
,
618 /* Printers and Faxes */
619 DeleteMenu(hSettingsMenu
,
620 IDM_PRINTERSANDFAXES
,
625 if (GetSystemMetrics(SM_REMOTECONTROL
) == 0 ||
626 SHRestricted(REST_NOSECURITY
))
628 DeleteMenu(hSettingsMenu
,
633 if (GetMenuItemCount(hSettingsMenu
) == 0)
642 /* FIXME: Enable after implementing */
643 /* if (SHRestricted(REST_NOFIND)) */
653 if (SHRestricted(REST_NORUN
))
661 if (!ShowSynchronizeMenuItem())
670 if (dwLogoff
!= 1 && bWantLogoff
)
672 /* FIXME: We need a more sophisticated way to determine whether to show
673 or hide it, it might be hidden in too many cases!!! */
675 /* Update Log Off menu item */
676 if (!GetCurrentLoggedOnUserName(szUser
,
677 sizeof(szUser
) / sizeof(szUser
[0])))
679 szUser
[0] = _T('\0');
682 if (!FormatMenuString(hMenu
,
687 /* We couldn't update the menu item, delete it... */
703 if (GetSystemMetrics(SM_REMOTECONTROL
) == 0)
711 /* Undock computer */
712 if (!ShowUndockMenuItem())
721 if (SHRestricted(REST_NOCLOSE
))
729 if (uLastItemsCount
== 0)
731 /* Remove the separator at the end of the menu */
733 IDM_LASTSTARTMENU_SEPARATOR
,
740 static const ITrayPrivVtbl ITrayPrivImpl_Vtbl
=
742 /*** IUnknown methods ***/
743 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(ITrayPriv
, IStartMenuSite
),
744 METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(ITrayPriv
, IStartMenuSite
),
745 METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(ITrayPriv
, IStartMenuSite
),
746 /*** IOleWindow methods ***/
747 IStartMenuSiteImpl_GetWindow
,
748 IStartMenuSiteImpl_ContextSensitiveHelp
,
749 /*** ITrayPriv methods ***/
750 IStartMenuSiteImpl_Execute
,
751 IStartMenuSiteImpl_Unknown
,
752 IStartMenuSiteImpl_AppendMenu
755 /*******************************************************************/
757 METHOD_IUNKNOWN_INHERITED_ADDREF(IOleCommandTarget
, IStartMenuSite
)
758 METHOD_IUNKNOWN_INHERITED_RELEASE(IOleCommandTarget
, IStartMenuSite
)
759 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IOleCommandTarget
, IStartMenuSite
)
761 static HRESULT STDMETHODCALLTYPE
762 IStartMenuSiteImpl_QueryStatus(IN OUT IOleCommandTarget
*iface
,
763 IN
const GUID
*pguidCmdGroup OPTIONAL
,
765 IN OUT OLECMD
*prgCmds
,
766 IN OUT OLECMDTEXT
*pCmdText OPTIONAL
)
771 static HRESULT STDMETHODCALLTYPE
772 IStartMenuSiteImpl_Exec(IN OUT IOleCommandTarget
*iface
,
773 IN
const GUID
*pguidCmdGroup OPTIONAL
,
775 IN DWORD nCmdExecOpt
,
776 IN VARIANTARG
*pvaIn OPTIONAL
,
777 IN VARIANTARG
*pvaOut OPTIONAL
)
782 static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl
=
784 /*** IUnknown methods ***/
785 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IOleCommandTarget
, IStartMenuSite
),
786 METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IOleCommandTarget
, IStartMenuSite
),
787 METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IOleCommandTarget
, IStartMenuSite
),
788 /*** IOleCommandTarget ***/
789 IStartMenuSiteImpl_QueryStatus
,
790 IStartMenuSiteImpl_Exec
793 /*******************************************************************/
795 METHOD_IUNKNOWN_INHERITED_ADDREF(IMenuPopup
, IStartMenuSite
)
796 METHOD_IUNKNOWN_INHERITED_RELEASE(IMenuPopup
, IStartMenuSite
)
797 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IMenuPopup
, IStartMenuSite
)
799 static HRESULT STDMETHODCALLTYPE
800 IStartMenuSiteImpl_IMenuPopup_GetWindow(IN OUT IMenuPopup
*iface
, OUT HWND
*phwnd
)
802 IStartMenuSiteImpl
* This
= IStartMenuSiteImpl_from_IMenuPopup(iface
);
803 ITrayPriv
* tp
= ITrayPriv_from_IStartMenuSiteImpl(This
);
804 return IStartMenuSiteImpl_GetWindow(tp
, phwnd
);
807 static HRESULT STDMETHODCALLTYPE
808 IStartMenuSiteImpl_IMenuPopup_ContextSensitiveHelp(IN OUT IMenuPopup
*iface
, IN BOOL fEnterMode
)
810 IStartMenuSiteImpl
* This
= IStartMenuSiteImpl_from_IMenuPopup(iface
);
811 ITrayPriv
* tp
= ITrayPriv_from_IStartMenuSiteImpl(This
);
812 return IStartMenuSiteImpl_ContextSensitiveHelp(tp
, fEnterMode
);
815 static HRESULT STDMETHODCALLTYPE
816 IStartMenuSiteImpl_SetClient(IN OUT IMenuPopup
*iface
, IUnknown
*punkClient
)
821 static HRESULT STDMETHODCALLTYPE
822 IStartMenuSiteImpl_GetClient(IN OUT IMenuPopup
*iface
, IUnknown
** ppunkClient
)
827 static HRESULT STDMETHODCALLTYPE
828 IStartMenuSiteImpl_OnPosRectChangeDB(IN OUT IMenuPopup
*iface
, RECT
*prc
)
833 static HRESULT STDMETHODCALLTYPE
834 IStartMenuSiteImpl_Popup(IN OUT IMenuPopup
*iface
, POINTL
*ppt
, RECTL
*prcExclude
, MP_POPUPFLAGS dwFlags
)
839 static HRESULT STDMETHODCALLTYPE
840 IStartMenuSiteImpl_OnSelect(IN OUT IMenuPopup
*iface
, DWORD dwSelectType
)
845 static HRESULT STDMETHODCALLTYPE
846 IStartMenuSiteImpl_SetSubMenu(IN OUT IMenuPopup
*iface
, IMenuPopup
*pmp
, BOOL fSet
)
850 return Tray_OnStartMenuDismissed();
856 static const IMenuPopupVtbl IMenuPopupImpl_Vtbl
=
858 /*** IUnknown methods ***/
859 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IMenuPopup
, IStartMenuSite
),
860 METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IMenuPopup
, IStartMenuSite
),
861 METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IMenuPopup
, IStartMenuSite
),
862 /*** IOleWindow methods ***/
863 IStartMenuSiteImpl_IMenuPopup_GetWindow
,
864 IStartMenuSiteImpl_IMenuPopup_ContextSensitiveHelp
,
865 /*** IDeskBar methods ***/
866 IStartMenuSiteImpl_SetClient
,
867 IStartMenuSiteImpl_GetClient
,
868 IStartMenuSiteImpl_OnPosRectChangeDB
,
870 IStartMenuSiteImpl_Popup
,
871 IStartMenuSiteImpl_OnSelect
,
872 IStartMenuSiteImpl_SetSubMenu
876 /*******************************************************************/
878 static IStartMenuSiteImpl
*
879 IStartMenuSiteImpl_Construct(IN ITrayWindow
*Tray
)
881 IStartMenuSiteImpl
*This
;
883 This
= HeapAlloc(hProcessHeap
,
889 This
->lpVtbl
= &IStartMenuSiteImpl_Vtbl
;
890 This
->lpServiceProviderVtbl
= &IServiceProviderImpl_Vtbl
;
891 This
->lpStartMenuCallbackVtbl
= &ITrayPrivImpl_Vtbl
;
892 This
->lpOleCommandTargetVtbl
= &IOleCommandTargetImpl_Vtbl
;
893 This
->lpMenuPopupVtbl
= &IMenuPopupImpl_Vtbl
;
901 static IStartMenuSite
*
902 CreateStartMenuSite(IN ITrayWindow
*Tray
)
904 IStartMenuSiteImpl
*This
;
906 This
= IStartMenuSiteImpl_Construct(Tray
);
909 return IStartMenuSite_from_IStartMenuSiteImpl(This
);
916 UpdateStartMenu(IN OUT IMenuPopup
*pMenuPopup
,
917 IN HBITMAP hbmBanner OPTIONAL
,
923 hRet
= IMenuPopup_QueryInterface(pMenuPopup
,
928 hRet
= IBanneredBar_SetBitmap(pbb
, hbmBanner
);
930 /* Update the icon size */
931 hRet
= IBanneredBar_SetIconSize(pbb
,
932 bSmallIcons
? BMICON_SMALL
: BMICON_LARGE
);
934 IBanneredBar_Release(pbb
);
941 CreateStartMenu(IN ITrayWindow
*Tray
,
942 OUT IMenuBand
**ppMenuBand
,
943 IN HBITMAP hbmBanner OPTIONAL
,
947 IObjectWithSite
*pOws
= NULL
;
948 IMenuPopup
*pMp
= NULL
;
949 IStartMenuSite
*pSms
= NULL
;
950 IMenuBand
*pMb
= NULL
;
951 IInitializeObject
*pIo
;
952 IUnknown
*pUnk
= NULL
;
953 IBandSite
*pBs
= NULL
;
956 pSms
= CreateStartMenuSite(Tray
);
961 hr
= CoCreateInstance(&CLSID_StartMenu
,
963 CLSCTX_INPROC_SERVER
,
967 hr
= CStartMenu_Constructor(&IID_IMenuPopup
,(PVOID
*)&pMp
);
971 TRACE("CoCreateInstance failed: %x\n", hr
);
975 hr
= IMenuPopup_QueryInterface(pMp
,
976 &IID_IObjectWithSite
,
980 TRACE("IMenuPopup_QueryInterface failed: %x\n", hr
);
984 /* Set the menu site so we can handle messages */
985 hr
= IObjectWithSite_SetSite(pOws
, (IUnknown
*)pSms
);
988 TRACE("IObjectWithSite_SetSite failed: %x\n", hr
);
992 /* Initialize the menu object */
993 hr
= IMenuPopup_QueryInterface(pMp
, &IID_IInitializeObject
, (PVOID
*)&pIo
);
996 hr
= IInitializeObject_Initialize(pIo
);
997 IInitializeObject_Release(pIo
);
1002 /* Everything is initialized now. Let's get the IMenuBand interface. */
1005 TRACE("IMenuPopup_QueryInterface failed: %x\n", hr
);
1009 hr
= IMenuPopup_GetClient(pMp
, &pUnk
);
1012 TRACE("IMenuPopup_GetClient failed: %x\n", hr
);
1016 hr
= IUnknown_QueryInterface(pUnk
, &IID_IBandSite
, (PVOID
*)&pBs
);
1019 TRACE("IUnknown_QueryInterface pBs failed: %x\n", hr
);
1023 /* Finally we have the IBandSite interface, there's only one
1024 band in it that apparently provides the IMenuBand interface */
1025 hr
= IBandSite_EnumBands(pBs
, 0, &dwBandId
);
1028 TRACE("IBandSite_EnumBands failed: %x\n", hr
);
1032 hr
= IBandSite_GetBandObject(pBs
, dwBandId
, &IID_IMenuBand
, (PVOID
*)&pMb
);
1035 TRACE("IBandSite_GetBandObject failed: %x\n", hr
);
1039 UpdateStartMenu(pMp
,
1046 else if (pMb
!= NULL
)
1047 IMenuBand_Release(pMb
);
1050 IBandSite_Release(pBs
);
1052 IUnknown_Release(pUnk
);
1054 IObjectWithSite_Release(pOws
);
1056 IMenuPopup_Release(pMp
);
1058 IStartMenuSite_Release(pSms
);