4 * Copyright 2007 Hervé Poussineau
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 St, Fifth Floor, Boston, MA 02110-1301, USA
23 WINE_DEFAULT_DEBUG_CHANNEL(shell32start
);
25 typedef struct _tagStartMenu
{
26 const IMenuPopupVtbl
*vtbl
;
27 const IObjectWithSiteVtbl
*objectSiteVtbl
;
28 const IInitializeObjectVtbl
*initObjectVtbl
;
29 const IMenuBandVtbl
*menuBandVtbl
;
32 IBandSite
* pBandSite
;
33 } StartMenu
, *LPStartMenu
;
35 typedef struct _tagMenuBandSite
{
36 const IBandSiteVtbl
* lpVtbl
;
42 } MenuBandSite
, *LPMenuBandSite
;
44 static const IMenuPopupVtbl StartMenuVtbl
;
45 static const IObjectWithSiteVtbl StartMenu_ObjectWithSiteVtbl
;
46 static const IInitializeObjectVtbl StartMenu_InitializeObjectVtbl
;
47 static const IBandSiteVtbl StartMenu_BandSiteVtbl
;
48 static const IMenuBandVtbl StartMenu_MenuBandVtbl
;
50 static LPStartMenu __inline
impl_from_IMenuPopup(IMenuPopup
*iface
)
52 return (LPStartMenu
)((char *)iface
- FIELD_OFFSET(StartMenu
, vtbl
));
55 static LPStartMenu __inline
impl_from_IObjectWithSite(IObjectWithSite
*iface
)
57 return (LPStartMenu
)((char *)iface
- FIELD_OFFSET(StartMenu
, objectSiteVtbl
));
60 static LPStartMenu __inline
impl_from_IInitializeObject(IInitializeObject
*iface
)
62 return (LPStartMenu
)((char *)iface
- FIELD_OFFSET(StartMenu
, initObjectVtbl
));
65 HRESULT WINAPI
StartMenu_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, LPVOID
*ppv
)
69 TRACE("StartMenu_Constructor(%p, %s, %p)\n", pUnkOuter
, debugstr_guid(riid
), ppv
);
74 This
= CoTaskMemAlloc(sizeof(StartMenu
));
77 ZeroMemory(This
, sizeof(*This
));
78 This
->vtbl
= &StartMenuVtbl
;
79 This
->objectSiteVtbl
= &StartMenu_ObjectWithSiteVtbl
;
80 This
->initObjectVtbl
= &StartMenu_InitializeObjectVtbl
;
81 This
->menuBandVtbl
= &StartMenu_MenuBandVtbl
;
84 TRACE("StartMenu_Constructor returning %p\n", This
);
85 *ppv
= (IUnknown
*)This
;
89 static void WINAPI
StartMenu_Destructor(StartMenu
*This
)
91 TRACE("destroying %p\n", This
);
92 if (This
->pUnkSite
) IUnknown_Release(This
->pUnkSite
);
96 static HRESULT WINAPI
StartMenu_QueryInterface(IMenuPopup
*iface
, REFIID iid
, LPVOID
*ppvOut
)
98 StartMenu
*This
= impl_from_IMenuPopup(iface
);
101 TRACE("StartMenu_QueryInterface (%p, %s, %p)\n", iface
, debugstr_guid(iid
), ppvOut
);
103 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IOleWindow
)
104 || IsEqualIID(iid
, &IID_IDeskBar
) || IsEqualIID(iid
, &IID_IMenuPopup
))
106 *ppvOut
= (void *)&This
->vtbl
;
108 else if (IsEqualIID(iid
, &IID_IObjectWithSite
))
110 *ppvOut
= (void *)&This
->objectSiteVtbl
;
112 else if (IsEqualIID(iid
, &IID_IInitializeObject
))
114 *ppvOut
= (void *)&This
->initObjectVtbl
;
119 IUnknown_AddRef(iface
);
123 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
124 return E_NOINTERFACE
;
127 static ULONG WINAPI
StartMenu_AddRef(IMenuPopup
*iface
)
129 StartMenu
*This
= impl_from_IMenuPopup(iface
);
130 TRACE("StartMenu_AddRef(%p)\n", iface
);
131 return InterlockedIncrement(&This
->refCount
);
134 static ULONG WINAPI
StartMenu_Release(IMenuPopup
*iface
)
136 StartMenu
*This
= impl_from_IMenuPopup(iface
);
139 TRACE("StartMenu_Release(%p)\n", iface
);
141 ret
= InterlockedDecrement(&This
->refCount
);
143 StartMenu_Destructor(This
);
147 static HRESULT WINAPI
StartMenu_GetWindow(IMenuPopup
*iface
, HWND
*phwnd
)
149 FIXME("(%p, %p)\n", iface
, phwnd
);
153 static HRESULT WINAPI
StartMenu_ContextSensitiveHelp(IMenuPopup
*iface
, BOOL fEnterMode
)
155 FIXME("(%p, %d)\n", iface
, fEnterMode
);
159 static HRESULT WINAPI
StartMenu_SetClient(IMenuPopup
*iface
, IUnknown
*punkClient
)
161 FIXME("(%p, %p)\n", iface
, punkClient
);
165 static HRESULT WINAPI
StartMenu_GetClient(IMenuPopup
*iface
, IUnknown
**ppunkClient
)
167 StartMenu
* This
= (StartMenu
*)iface
;
169 TRACE("StartMenu_GetClient (%p, %p)\n", iface
, ppunkClient
);
171 *ppunkClient
= (IUnknown
*)This
->pBandSite
;
172 IUnknown_AddRef(*ppunkClient
);
176 static HRESULT WINAPI
StartMenu_OnPosRectChangeDB(IMenuPopup
*iface
, LPRECT prc
)
178 FIXME("(%p, %p)\n", iface
, prc
);
182 static HRESULT WINAPI
StartMenu_Popup(IMenuPopup
*iface
, POINTL
*ppt
, RECTL
*prcExclude
, MP_POPUPFLAGS dwFlags
)
184 FIXME("(%p, %p, %p, %x)\n", iface
, ppt
, prcExclude
, dwFlags
);
188 static HRESULT WINAPI
StartMenu_OnSelect(IMenuPopup
*iface
, DWORD dwSelectType
)
190 FIXME("(%p, %u)\n", iface
, dwSelectType
);
194 static HRESULT WINAPI
StartMenu_SetSubMenu(IMenuPopup
*iface
, IMenuPopup
*pmp
, BOOL fSet
)
196 FIXME("(%p, %p, %d)\n", iface
, pmp
, fSet
);
200 static const IMenuPopupVtbl StartMenuVtbl
=
203 StartMenu_QueryInterface
,
209 StartMenu_ContextSensitiveHelp
,
214 StartMenu_OnPosRectChangeDB
,
219 StartMenu_SetSubMenu
,
222 static HRESULT WINAPI
StartMenu_IObjectWithSite_QueryInterface(IObjectWithSite
*iface
, REFIID iid
, LPVOID
*ppvOut
)
224 StartMenu
*This
= impl_from_IObjectWithSite(iface
);
225 TRACE("(%p, %s, %p)\n", iface
, debugstr_guid(iid
), ppvOut
);
226 return StartMenu_QueryInterface((IMenuPopup
*)This
, iid
, ppvOut
);
229 static ULONG WINAPI
StartMenu_IObjectWithSite_AddRef(IObjectWithSite
*iface
)
231 StartMenu
*This
= impl_from_IObjectWithSite(iface
);
232 TRACE("(%p)\n", iface
);
233 return StartMenu_AddRef((IMenuPopup
*)This
);
236 static ULONG WINAPI
StartMenu_IObjectWithSite_Release(IObjectWithSite
*iface
)
238 StartMenu
*This
= impl_from_IObjectWithSite(iface
);
239 TRACE("StartMenu_IObjectWithSite_Release (%p)\n", iface
);
240 return StartMenu_Release((IMenuPopup
*)This
);
243 static HRESULT WINAPI
StartMenu_IObjectWithSite_SetSite(IObjectWithSite
*iface
, IUnknown
*pUnkSite
)
245 StartMenu
*This
= impl_from_IObjectWithSite(iface
);
247 TRACE("StartMenu_IObjectWithSite_SetSite(%p, %p)\n", iface
, pUnkSite
);
250 IUnknown_Release(This
->pUnkSite
);
251 This
->pUnkSite
= pUnkSite
;
253 IUnknown_AddRef(This
->pUnkSite
);
257 static HRESULT WINAPI
StartMenu_IObjectWithSite_GetSite(IObjectWithSite
*iface
, REFIID riid
, void **ppvSite
)
259 StartMenu
*This
= impl_from_IObjectWithSite(iface
);
261 TRACE("(%p, %s, %p)\n", iface
, debugstr_guid(riid
), ppvSite
);
266 return IUnknown_QueryInterface(This
->pUnkSite
, riid
, ppvSite
);
269 static const IObjectWithSiteVtbl StartMenu_ObjectWithSiteVtbl
=
271 StartMenu_IObjectWithSite_QueryInterface
,
272 StartMenu_IObjectWithSite_AddRef
,
273 StartMenu_IObjectWithSite_Release
,
275 StartMenu_IObjectWithSite_SetSite
,
276 StartMenu_IObjectWithSite_GetSite
,
279 static HRESULT WINAPI
StartMenu_IInitializeObject_QueryInterface(IInitializeObject
*iface
, REFIID iid
, LPVOID
*ppvOut
)
281 StartMenu
*This
= impl_from_IInitializeObject(iface
);
282 TRACE("(%p, %s, %p)\n", iface
, debugstr_guid(iid
), ppvOut
);
283 return StartMenu_QueryInterface((IMenuPopup
*)This
, iid
, ppvOut
);
286 static ULONG WINAPI
StartMenu_IInitializeObject_AddRef(IInitializeObject
*iface
)
288 StartMenu
*This
= impl_from_IInitializeObject(iface
);
289 TRACE("StartMenu_IInitializeObject_AddRef(%p)\n", iface
);
290 return StartMenu_AddRef((IMenuPopup
*)This
);
293 static ULONG WINAPI
StartMenu_IInitializeObject_Release(IInitializeObject
*iface
)
295 StartMenu
*This
= impl_from_IInitializeObject(iface
);
296 TRACE("StartMenu_IInitializeObject_Release (%p)\n", iface
);
297 return StartMenu_Release((IMenuPopup
*)This
);
300 static HRESULT WINAPI
StartMenu_IInitializeObject_Initialize(IInitializeObject
*iface
)
303 StartMenu
*This
= impl_from_IInitializeObject(iface
);
304 TRACE("StartMenu_IInitializeObject_Initialize (%p)\n", iface
);
306 hr
= MenuBandSite_Constructor(NULL
, &IID_IBandSite
, (LPVOID
*)&This
->pBandSite
);
310 return IBandSite_AddBand(This
->pBandSite
, (IUnknown
*)&This
->menuBandVtbl
);
313 static const IInitializeObjectVtbl StartMenu_InitializeObjectVtbl
=
315 StartMenu_IInitializeObject_QueryInterface
,
316 StartMenu_IInitializeObject_AddRef
,
317 StartMenu_IInitializeObject_Release
,
319 StartMenu_IInitializeObject_Initialize
,
322 //--------------------------------------------------------------
323 // IMenuBand interface
326 static HRESULT STDMETHODCALLTYPE
StartMenu_IMenuBand_QueryInterface(IMenuBand
*iface
, REFIID iid
, LPVOID
*ppvOut
)
328 StartMenu
*This
= (StartMenu
*)CONTAINING_RECORD(iface
, StartMenu
, menuBandVtbl
);
330 if (IsEqualIID(iid
, &IID_IUnknown
) ||
331 IsEqualIID(iid
, &IID_IMenuBand
))
333 *ppvOut
= &This
->menuBandVtbl
;
334 IUnknown_AddRef((IUnknown
*)*ppvOut
);
338 WARN("unsupported interface:(%p, %s, %p)\n", iface
, debugstr_guid(iid
), ppvOut
);
339 return E_NOINTERFACE
;
342 static ULONG STDMETHODCALLTYPE
StartMenu_IMenuBand_AddRef(IMenuBand
*iface
)
344 StartMenu
*This
= (StartMenu
*)CONTAINING_RECORD(iface
, StartMenu
, menuBandVtbl
);
345 TRACE("StartMenu_IInitializeObject_AddRef(%p)\n", This
);
346 return StartMenu_AddRef((IMenuPopup
*)This
);
349 static ULONG STDMETHODCALLTYPE
StartMenu_IMenuBand_Release(IMenuBand
*iface
)
351 StartMenu
*This
= (StartMenu
*)CONTAINING_RECORD(iface
, StartMenu
, menuBandVtbl
);
352 TRACE("StartMenu_IInitializeObject_Release (%p)\n", This
);
353 return StartMenu_Release((IMenuPopup
*)This
);
356 HRESULT STDMETHODCALLTYPE
StartMenu_IMenuBand_IsMenuMessage(IMenuBand
*iface
, MSG
*pmsg
)
358 StartMenu
*This
= (StartMenu
*)CONTAINING_RECORD(iface
, StartMenu
, menuBandVtbl
);
359 TRACE("StartMenu_IMenuBand_IsMenuMessage Stub(%p)\n", This
);
363 HRESULT STDMETHODCALLTYPE
StartMenu_IMenuBand_TranslateMenuMessage(IMenuBand
*iface
, MSG
*pmsg
, LRESULT
*plRet
)
365 StartMenu
*This
= (StartMenu
*)CONTAINING_RECORD(iface
, StartMenu
, menuBandVtbl
);
366 TRACE("StartMenu_IMenuBand_TranslateMenuMessage Stub(%p)\n", This
);
371 static const IMenuBandVtbl StartMenu_MenuBandVtbl
=
373 /* IUnknown methods */
374 StartMenu_IMenuBand_QueryInterface
,
375 StartMenu_IMenuBand_AddRef
,
376 StartMenu_IMenuBand_Release
,
377 /* IMenuBand methods */
378 StartMenu_IMenuBand_IsMenuMessage
,
379 StartMenu_IMenuBand_TranslateMenuMessage
,
383 //---------------------------------------------------------------------------------------------------------
384 // IBandSite interface
387 HRESULT WINAPI
MenuBandSite_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, LPVOID
*ppv
)
392 TRACE("StartMenu_Constructor(%p, %s, %p)\n", pUnkOuter
, debugstr_guid(riid
), ppv
);
397 This
= CoTaskMemAlloc(sizeof(MenuBandSite
));
399 return E_OUTOFMEMORY
;
401 ZeroMemory(This
, sizeof(MenuBandSite
));
402 This
->lpVtbl
= &StartMenu_BandSiteVtbl
;
404 hr
= IUnknown_QueryInterface((IUnknown
*)&This
->lpVtbl
, riid
, ppv
);
412 TRACE("StartMenu_Constructor returning %p\n", This
);
413 *ppv
= (IUnknown
*)This
;
417 static HRESULT WINAPI
BandSite_QueryInterface(IBandSite
*iface
, REFIID iid
, LPVOID
*ppvOut
)
419 MenuBandSite
*This
= (MenuBandSite
*)CONTAINING_RECORD(iface
, MenuBandSite
, lpVtbl
);
421 if (IsEqualIID(iid
, &IID_IUnknown
) ||
422 IsEqualIID(iid
, &IID_IBandSite
))
424 *ppvOut
= &This
->lpVtbl
;
425 IUnknown_AddRef((IUnknown
*)*ppvOut
);
429 return E_NOINTERFACE
;
432 static ULONG WINAPI
BandSite_AddRef(IBandSite
*iface
)
434 MenuBandSite
*This
= (MenuBandSite
*)CONTAINING_RECORD(iface
, MenuBandSite
, lpVtbl
);
435 TRACE("BandSite_AddRef(%p)\n", iface
);
436 return InterlockedIncrement(&This
->refCount
);
439 static ULONG WINAPI
BandSite_Release(IBandSite
*iface
)
442 MenuBandSite
*This
= (MenuBandSite
*)CONTAINING_RECORD(iface
, MenuBandSite
, lpVtbl
);
444 ret
= InterlockedDecrement(&This
->refCount
);
445 TRACE("BandSite_Release refCount %u\n", ret
);
449 CoTaskMemFree(This
->Objects
);
457 static HRESULT STDMETHODCALLTYPE
BandSite_AddBand(IBandSite
*iface
, IUnknown
*punk
)
460 MenuBandSite
*This
= (MenuBandSite
*)CONTAINING_RECORD(iface
, MenuBandSite
, lpVtbl
);
462 TRACE("StartMenu_IBandSite_AddBand Stub punk %p\n", punk
);
467 Objects
= (IUnknown
**) CoTaskMemAlloc(sizeof(IUnknown
*) * (This
->ObjectsCount
+ 1));
471 RtlMoveMemory(Objects
, This
->Objects
, sizeof(IUnknown
*) * This
->ObjectsCount
);
473 CoTaskMemFree(This
->Objects
);
475 This
->Objects
= Objects
;
476 Objects
[This
->ObjectsCount
] = punk
;
478 IUnknown_AddRef(punk
);
480 This
->ObjectsCount
++;
486 static HRESULT STDMETHODCALLTYPE
BandSite_EnumBands(IBandSite
*iface
, UINT uBand
, DWORD
*pdwBandID
)
488 ULONG Index
, ObjectCount
;
489 MenuBandSite
*This
= (MenuBandSite
*)CONTAINING_RECORD(iface
, MenuBandSite
, lpVtbl
);
491 TRACE("StartMenu_IBandSite_EnumBands Stub uBand %uu pdwBandID %p\n", uBand
, pdwBandID
);
493 if (uBand
== (UINT
)-1)
494 return This
->ObjectsCount
;
498 for(Index
= 0; Index
< This
->ObjectsCount
; Index
++)
500 if (This
->Objects
[Index
] != NULL
)
502 if (uBand
== ObjectCount
)
513 static HRESULT STDMETHODCALLTYPE
BandSite_QueryBand(IBandSite
*iface
, DWORD dwBandID
, IDeskBand
**ppstb
, DWORD
*pdwState
, LPWSTR pszName
, int cchName
)
515 FIXME("StartMenu_IBandSite_QueryBand Stub dwBandID %u IDeskBand %p pdwState %p Name %p cchName %u\n", dwBandID
, ppstb
, pdwState
, pszName
, cchName
);
519 static HRESULT STDMETHODCALLTYPE
BandSite_SetBandState(IBandSite
*iface
, DWORD dwBandID
, DWORD dwMask
, DWORD dwState
)
521 FIXME("StartMenu_IBandSite_SetBandState Stub dwBandID %u dwMask %x dwState %u\n", dwBandID
, dwMask
, dwState
);
524 static HRESULT STDMETHODCALLTYPE
BandSite_RemoveBand(IBandSite
*iface
, DWORD dwBandID
)
526 MenuBandSite
*This
= (MenuBandSite
*)CONTAINING_RECORD(iface
, MenuBandSite
, lpVtbl
);
527 TRACE("StartMenu_IBandSite_RemoveBand Stub dwBandID %u\n", dwBandID
);
529 if (This
->ObjectsCount
<= dwBandID
)
532 if (This
->Objects
[dwBandID
])
534 This
->Objects
[dwBandID
]->lpVtbl
->Release(This
->Objects
[dwBandID
]);
535 This
->Objects
[dwBandID
] = NULL
;
541 static HRESULT STDMETHODCALLTYPE
BandSite_GetBandObject(IBandSite
*iface
, DWORD dwBandID
, REFIID riid
, void **ppv
)
543 MenuBandSite
*This
= (MenuBandSite
*)CONTAINING_RECORD(iface
, MenuBandSite
, lpVtbl
);
545 TRACE("StartMenu_IBandSite_GetBandObject Stub dwBandID %u riid %p ppv %p\n", dwBandID
, riid
, ppv
);
547 if (This
->ObjectsCount
<= dwBandID
)
550 if (This
->Objects
[dwBandID
])
552 return IUnknown_QueryInterface(This
->Objects
[dwBandID
], riid
, ppv
);
557 static HRESULT STDMETHODCALLTYPE
BandSite_SetBandSiteInfo(IBandSite
*iface
, const BANDSITEINFO
*pbsinfo
)
559 FIXME("StartMenu_IBandSite_SetBandSiteInfo Stub pbsinfo %p\n", pbsinfo
);
563 static HRESULT STDMETHODCALLTYPE
BandSite_GetBandSiteInfo(IBandSite
*iface
, BANDSITEINFO
*pbsinfo
)
565 FIXME("StartMenu_IBandSite_GetBandSiteInfo Stub pbsinfo %p\n", pbsinfo
);
569 static const IBandSiteVtbl StartMenu_BandSiteVtbl
=
571 BandSite_QueryInterface
,
577 BandSite_SetBandState
,
579 BandSite_GetBandObject
,
580 BandSite_SetBandSiteInfo
,
581 BandSite_GetBandSiteInfo