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
23 #include <shdeprecated.h>
27 /*****************************************************************************
28 ** ITrayBandSite ************************************************************
29 *****************************************************************************/
31 static const ITrayBandSiteVtbl ITrayBandSiteImpl_Vtbl
;
32 static const IBandSiteVtbl IBandSiteImpl_Vtbl
;
36 const ITrayBandSiteVtbl
*lpVtbl
;
37 const IBandSiteVtbl
*lpBandSiteVtbl
;
45 IWinEventHandler
*WindowEventHandler
;
46 IContextMenu
*ContextMenu
;
61 ITrayBandSiteImpl_Update(IN OUT ITrayBandSiteImpl
*This
);
64 IUnknown_from_ITrayBandSiteImpl(ITrayBandSiteImpl
*This
)
66 return (IUnknown
*)&This
->lpVtbl
;
69 IMPL_CASTS(ITrayBandSite
, ITrayBandSite
, lpVtbl
)
70 IMPL_CASTS(IBandSite
, ITrayBandSite
, lpBandSiteVtbl
)
72 static ULONG STDMETHODCALLTYPE
73 ITrayBandSiteImpl_AddRef(IN OUT ITrayBandSite
*iface
)
75 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
77 return InterlockedIncrement(&This
->Ref
);
81 ITrayBandSiteImpl_Free(IN OUT ITrayBandSiteImpl
*This
)
83 if (This
->BandSite
!= NULL
)
85 IBandSite_Release(This
->BandSite
);
86 This
->BandSite
= NULL
;
89 if (This
->WindowEventHandler
!= NULL
)
91 IWinEventHandler_Release(This
->WindowEventHandler
);
92 This
->WindowEventHandler
= NULL
;
95 if (This
->ContextMenu
!= NULL
)
97 IContextMenu_Release(This
->ContextMenu
);
98 This
->ContextMenu
= NULL
;
101 if (This
->punkInner
!= NULL
)
103 IUnknown_Release(This
->punkInner
);
104 This
->punkInner
= NULL
;
107 HeapFree(hProcessHeap
,
112 static ULONG STDMETHODCALLTYPE
113 ITrayBandSiteImpl_Release(IN OUT ITrayBandSite
*iface
)
115 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
118 Ret
= InterlockedDecrement(&This
->Ref
);
121 ITrayBandSiteImpl_Free(This
);
126 static HRESULT STDMETHODCALLTYPE
127 ITrayBandSiteImpl_QueryInterface(IN OUT ITrayBandSite
*iface
,
131 ITrayBandSiteImpl
*This
;
136 This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
141 &IID_IBandSiteStreamCallback
))
143 /* NOTE: IID_IBandSiteStreamCallback is queried by the shell, we
144 implement this interface directly */
145 *ppvObj
= IUnknown_from_ITrayBandSiteImpl(This
);
147 else if (IsEqualIID(riid
,
150 *ppvObj
= IBandSite_from_ITrayBandSiteImpl(This
);
152 else if (IsEqualIID(riid
,
153 &IID_IWinEventHandler
))
155 DbgPrint("ITaskBandSite: IWinEventHandler queried!\n");
157 return E_NOINTERFACE
;
159 else if (This
->punkInner
!= NULL
)
161 return IUnknown_QueryInterface(This
->punkInner
,
168 return E_NOINTERFACE
;
171 ITrayBandSiteImpl_AddRef(iface
);
175 static HRESULT STDMETHODCALLTYPE
176 ITrayBandSiteImpl_OnLoad(IN OUT ITrayBandSite
*iface
,
177 IN OUT IStream
*pStm
,
181 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
182 LARGE_INTEGER liPosZero
;
183 ULARGE_INTEGER liCurrent
;
188 /* NOTE: Callback routine called by the shell while loading the task band
189 stream. We use it to intercept the default behavior when the task
190 band is loaded from the stream.
192 NOTE: riid always points to IID_IUnknown! This is because the shell hasn't
193 read anything from the stream and therefore doesn't know what CLSID
194 it's dealing with. We'll have to find it out ourselves by reading
195 the GUID from the stream. */
197 /* Read the current position of the stream, we'll have to reset it everytime
198 we read a CLSID that's not the task band... */
199 ZeroMemory(&liPosZero
,
201 hRet
= IStream_Seek(pStm
,
208 /* Now let's read the CLSID from the stream and see if it's our task band */
209 #if defined(IStream_Read)
210 hRet
= IStream_Read(pStm
,
215 ulRead
= sizeof(clsid
);
216 hRet
= IStream_Read(pStm
,
220 if (SUCCEEDED(hRet
) && ulRead
== sizeof(clsid
))
222 if (IsEqualGUID(&clsid
,
225 ASSERT(This
->TaskBand
!= NULL
);
226 /* We're trying to load the task band! Let's create it... */
228 hRet
= ITaskBand_QueryInterface(This
->TaskBand
,
233 /* Load the stream */
234 DbgPrint("IBandSiteStreamCallback::OnLoad intercepted the task band CLSID!\n");
242 /* Reset the position and let the shell do all the work for us */
243 hRet
= IStream_Seek(pStm
,
244 *(LARGE_INTEGER
*)&liCurrent
,
249 /* Let the shell handle everything else for us :) */
250 hRet
= OleLoadFromStream(pStm
,
255 if (!SUCCEEDED(hRet
))
257 DbgPrint("IBandSiteStreamCallback::OnLoad(0x%p, 0x%p, 0x%p) returns 0x%x\n", pStm
, riid
, pvObj
, hRet
);
263 static HRESULT STDMETHODCALLTYPE
264 ITrayBandSiteImpl_OnSave(IN OUT ITrayBandSite
*iface
,
265 IN OUT IUnknown
*pUnk
,
266 IN OUT IStream
*pStm
)
268 /* NOTE: Callback routine called by the shell while saving the task band
269 stream. We use it to intercept the default behavior when the task
270 band is saved to the stream */
271 /* FIXME: Implement */
272 DbgPrint("IBandSiteStreamCallback::OnSave(0x%p, 0x%p) returns E_NOTIMPL\n", pUnk
, pStm
);
277 IsSameObject(IN IUnknown
*punk1
,
282 hRet
= IUnknown_QueryInterface(punk1
,
285 if (!SUCCEEDED(hRet
))
288 hRet
= IUnknown_QueryInterface(punk2
,
291 IUnknown_Release(punk1
);
293 if (!SUCCEEDED(hRet
))
296 IUnknown_Release(punk2
);
298 /* We're dealing with the same object if the IUnknown pointers are equal */
299 return (punk1
== punk2
) ? S_OK
: S_FALSE
;
302 static HRESULT STDMETHODCALLTYPE
303 ITrayBandSiteImpl_IsTaskBand(IN OUT ITrayBandSite
*iface
,
306 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
307 return IsSameObject((IUnknown
*)This
->BandSite
,
311 static HRESULT STDMETHODCALLTYPE
312 ITrayBandSiteImpl_ProcessMessage(IN OUT ITrayBandSite
*iface
,
317 OUT LRESULT
*plResult
)
319 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
322 ASSERT(This
->hWndRebar
!= NULL
);
324 /* Custom task band behavior */
329 const NMHDR
*nmh
= (const NMHDR
*)lParam
;
331 if (nmh
->hwndFrom
== This
->hWndRebar
)
337 LPNMMOUSE nmm
= (LPNMMOUSE
)lParam
;
339 if (nmm
->dwHitInfo
== RBHT_CLIENT
|| nmm
->dwHitInfo
== RBHT_NOWHERE
||
340 nmm
->dwItemSpec
== (DWORD_PTR
)-1)
342 /* Make the rebar control appear transparent so the user
343 can drag the tray window */
344 *plResult
= HTTRANSPARENT
;
350 /* Deny if an Administrator disabled this "feature" */
351 *plResult
= (SHRestricted(REST_NOMOVINGBAND
) != 0);
356 //DbgPrint("ITrayBandSite::ProcessMessage: WM_NOTIFY for 0x%p, From: 0x%p, Code: NM_FIRST-%u...\n", hWnd, nmh->hwndFrom, NM_FIRST - nmh->code);
361 /* Forward to the shell's IWinEventHandler interface to get the default
363 if (This
->WindowEventHandler
!= NULL
)
365 /*DbgPrint("Calling IWinEventHandler::ProcessMessage(0x%p, 0x%x, 0x%p, 0x%p, 0x%p) This->hWndRebar=0x%p\n", hWnd, uMsg, wParam, lParam, plResult, This->hWndRebar);*/
366 hRet
= IWinEventHandler_OnWinEvent(This
->WindowEventHandler
,
372 if (!SUCCEEDED(hRet
))
374 if (uMsg
== WM_NOTIFY
)
376 const NMHDR
*nmh
= (const NMHDR
*)lParam
;
377 DbgPrint("ITrayBandSite->IWinEventHandler::ProcessMessage: WM_NOTIFY for 0x%p, From: 0x%p, Code: NM_FIRST-%u returned 0x%x\n", hWnd
, nmh
->hwndFrom
, NM_FIRST
- nmh
->code
, hRet
);
381 DbgPrint("ITrayBandSite->IWinEventHandler::ProcessMessage(0x%p,0x%x,0x%p,0x%p,0x%p->0x%p) returned: 0x%x\n", hWnd
, uMsg
, wParam
, lParam
, plResult
, *plResult
, hRet
);
391 static HRESULT STDMETHODCALLTYPE
392 ITrayBandSiteImpl_AddContextMenus(IN OUT ITrayBandSite
*iface
,
398 OUT IContextMenu
**ppcm
)
400 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
404 if (This
->ContextMenu
== NULL
)
406 /* Cache the context menu so we don't need to CoCreateInstance all the time... */
407 hRet
= CoCreateInstance(&CLSID_IShellBandSiteMenu
,
409 CLSCTX_INPROC_SERVER
,
412 DbgPrint("CoCreateInstance(CLSID_IShellBandSiteMenu) for IShellService returned: 0x%x\n", hRet
);
413 if (!SUCCEEDED(hRet
))
416 hRet
= IShellService_SetOwner(pSs
,
417 IUnknown_from_ITrayBandSiteImpl(This
));
418 if (!SUCCEEDED(hRet
))
420 IShellService_Release(pSs
);
424 hRet
= IShellService_QueryInterface(pSs
,
426 (PVOID
*)&This
->ContextMenu
);
428 IShellService_Release(pSs
);
430 if (!SUCCEEDED(hRet
))
436 IContextMenu_AddRef(This
->ContextMenu
);
437 *ppcm
= This
->ContextMenu
;
440 /* Add the menu items */
441 return IContextMenu_QueryContextMenu(This
->ContextMenu
,
449 static HRESULT STDMETHODCALLTYPE
450 ITrayBandSiteImpl_Lock(IN OUT ITrayBandSite
*iface
,
453 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
454 BOOL bPrevLocked
= This
->Locked
;
458 ASSERT(This
->BandSite
!= NULL
);
460 if (bPrevLocked
!= bLock
)
462 This
->Locked
= bLock
;
464 bsi
.dwMask
= BSIM_STYLE
;
465 bsi
.dwStyle
= (This
->Locked
? BSIS_LOCKED
| BSIS_NOGRIPPER
: BSIS_AUTOGRIPPER
);
467 hRet
= IBandSite_SetBandSiteInfo(This
->BandSite
,
471 hRet
= ITrayBandSiteImpl_Update(This
);
480 static const ITrayBandSiteVtbl ITrayBandSiteImpl_Vtbl
=
482 /*** IUnknown methods ***/
483 ITrayBandSiteImpl_QueryInterface
,
484 ITrayBandSiteImpl_AddRef
,
485 ITrayBandSiteImpl_Release
,
486 /*** IBandSiteStreamCallback methods ***/
487 ITrayBandSiteImpl_OnLoad
,
488 ITrayBandSiteImpl_OnSave
,
489 /*** ITrayBandSite methods ***/
490 ITrayBandSiteImpl_IsTaskBand
,
491 ITrayBandSiteImpl_ProcessMessage
,
492 ITrayBandSiteImpl_AddContextMenus
,
493 ITrayBandSiteImpl_Lock
496 /*******************************************************************/
498 METHOD_IUNKNOWN_INHERITED_ADDREF(IBandSite
, ITrayBandSite
)
499 METHOD_IUNKNOWN_INHERITED_RELEASE(IBandSite
, ITrayBandSite
)
500 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IBandSite
, ITrayBandSite
)
502 static HRESULT STDMETHODCALLTYPE
503 ITrayBandSiteImpl_AddBand(IN OUT IBandSite
*iface
,
506 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
507 IOleCommandTarget
*pOct
;
510 hRet
= IUnknown_QueryInterface(punk
,
511 &IID_IOleCommandTarget
,
515 /* Send the DBID_DELAYINIT command to initialize the band to be added */
516 /* FIXME: Should be delayed */
517 IOleCommandTarget_Exec(pOct
,
524 IOleCommandTarget_Release(pOct
);
527 return IBandSite_AddBand(This
->BandSite
,
531 static HRESULT STDMETHODCALLTYPE
532 ITrayBandSiteImpl_EnumBands(IN OUT IBandSite
*iface
,
534 OUT DWORD
*pdwBandID
)
536 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
537 return IBandSite_EnumBands(This
->BandSite
,
542 static HRESULT STDMETHODCALLTYPE
543 ITrayBandSiteImpl_QueryBand(IN OUT IBandSite
*iface
,
545 OUT IDeskBand
**ppstb
,
551 IDeskBand
*pstb
= NULL
;
552 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
554 hRet
= IBandSite_QueryBand(This
->BandSite
,
563 hRet
= IsSameObject((IUnknown
*)pstb
,
564 (IUnknown
*)This
->TaskBand
);
567 /* Add the BSSF_UNDELETEABLE flag to pdwState because the task bar band shouldn't be deletable */
568 if (pdwState
!= NULL
)
569 *pdwState
|= BSSF_UNDELETEABLE
;
571 else if (!SUCCEEDED(hRet
))
573 IDeskBand_Release(pstb
);
580 else if (ppstb
!= NULL
)
586 static HRESULT STDMETHODCALLTYPE
587 ITrayBandSiteImpl_SetBandState(IN OUT IBandSite
*iface
,
592 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
593 return IBandSite_SetBandState(This
->BandSite
,
599 static HRESULT STDMETHODCALLTYPE
600 ITrayBandSiteImpl_RemoveBand(IN OUT IBandSite
*iface
,
603 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
604 return IBandSite_RemoveBand(This
->BandSite
,
608 static HRESULT STDMETHODCALLTYPE
609 ITrayBandSiteImpl_GetBandObject(IN OUT IBandSite
*iface
,
614 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
615 return IBandSite_GetBandObject(This
->BandSite
,
621 static HRESULT STDMETHODCALLTYPE
622 ITrayBandSiteImpl_SetBandSiteInfo(IN OUT IBandSite
*iface
,
623 IN
const BANDSITEINFO
*pbsinfo
)
625 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
626 return IBandSite_SetBandSiteInfo(This
->BandSite
,
630 static HRESULT STDMETHODCALLTYPE
631 ITrayBandSiteImpl_GetBandSiteInfo(IN OUT IBandSite
*iface
,
632 IN OUT BANDSITEINFO
*pbsinfo
)
634 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
635 return IBandSite_GetBandSiteInfo(This
->BandSite
,
639 static const IBandSiteVtbl IBandSiteImpl_Vtbl
=
641 /*** IUnknown methods ***/
642 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IBandSite
, ITrayBandSite
),
643 METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IBandSite
, ITrayBandSite
),
644 METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IBandSite
, ITrayBandSite
),
645 /*** IBandSite methods ***/
646 ITrayBandSiteImpl_AddBand
,
647 ITrayBandSiteImpl_EnumBands
,
648 ITrayBandSiteImpl_QueryBand
,
649 ITrayBandSiteImpl_SetBandState
,
650 ITrayBandSiteImpl_RemoveBand
,
651 ITrayBandSiteImpl_GetBandObject
,
652 ITrayBandSiteImpl_SetBandSiteInfo
,
653 ITrayBandSiteImpl_GetBandSiteInfo
,
657 ITrayBandSiteImpl_HasTaskBand(IN OUT ITrayBandSiteImpl
*This
)
659 ASSERT(This
->TaskBand
!= NULL
);
661 return SUCCEEDED(ITaskBand_GetRebarBandID(This
->TaskBand
,
666 ITrayBandSiteImpl_AddTaskBand(IN OUT ITrayBandSiteImpl
*This
)
669 /* FIXME: This is the code for the simple taskbar */
670 IObjectWithSite
*pOws
;
673 hRet
= ITaskBand_QueryInterface(This
->TaskBand
,
674 &IID_IObjectWithSite
,
678 hRet
= IObjectWithSite_SetSite(pOws
,
679 (IUnknown
*)This
->TaskBand
);
681 IObjectWithSite_Release(pOws
);
686 if (!ITrayBandSiteImpl_HasTaskBand(This
))
688 return IBandSite_AddBand(This
->BandSite
,
689 (IUnknown
*)This
->TaskBand
);
697 ITrayBandSiteImpl_Update(IN OUT ITrayBandSiteImpl
*This
)
699 IOleCommandTarget
*pOct
;
702 hRet
= IUnknown_QueryInterface(This
->punkInner
,
703 &IID_IOleCommandTarget
,
707 /* Send the DBID_BANDINFOCHANGED command to update the band site */
708 hRet
= IOleCommandTarget_Exec(pOct
,
710 DBID_BANDINFOCHANGED
,
715 IOleCommandTarget_Release(pOct
);
722 ITrayBandSiteImpl_BroadcastOleCommandExec(IN OUT ITrayBandSiteImpl
*This
,
723 const GUID
*pguidCmdGroup
,
729 IOleCommandTarget
*pOct
;
733 /* Enumerate all bands */
734 while (SUCCEEDED(IBandSite_EnumBands(This
->BandSite
,
738 if (SUCCEEDED(IBandSite_GetBandObject(This
->BandSite
,
740 &IID_IOleCommandTarget
,
743 /* Execute the command */
744 IOleCommandTarget_Exec(pOct
,
751 IOleCommandTarget_Release(pOct
);
759 ITrayBandSiteImpl_FinishInit(IN OUT ITrayBandSiteImpl
*This
)
761 /* Broadcast the DBID_FINISHINIT command */
762 ITrayBandSiteImpl_BroadcastOleCommandExec(This
,
773 ITrayBandSiteImpl_Show(IN OUT ITrayBandSiteImpl
*This
,
776 IDeskBarClient
*pDbc
;
779 hRet
= IBandSite_QueryInterface(This
->BandSite
,
784 hRet
= IDeskBarClient_UIActivateDBC(pDbc
,
785 bShow
? DBC_SHOW
: DBC_HIDE
);
786 IDeskBarClient_Release(pDbc
);
793 ITrayBandSiteImpl_LoadFromStream(IN OUT ITrayBandSiteImpl
*This
,
794 IN OUT IStream
*pStm
)
796 IPersistStream
*pPStm
;
799 ASSERT(This
->BandSite
!= NULL
);
801 /* We implement the undocumented COM interface IBandSiteStreamCallback
802 that the shell will query so that we can intercept and custom-load
803 the task band when it finds the task band's CLSID (which is internal).
804 This way we can prevent the shell from attempting to CoCreateInstance
805 the (internal) task band, resulting in a failure... */
806 hRet
= IBandSite_QueryInterface(This
->BandSite
,
811 hRet
= IPersistStream_Load(pPStm
,
813 DbgPrint("IPersistStream_Load() returned 0x%x\n", hRet
);
814 IPersistStream_Release(pPStm
);
821 GetUserBandsStream(IN DWORD grfMode
)
824 IStream
*Stream
= NULL
;
826 if (RegCreateKey(hkExplorer
,
828 &hkStreams
) == ERROR_SUCCESS
)
830 Stream
= SHOpenRegStream(hkStreams
,
832 TEXT("TaskbarWinXP"),
835 RegCloseKey(hkStreams
);
842 GetDefaultBandsStream(IN DWORD grfMode
)
845 IStream
*Stream
= NULL
;
847 if (RegCreateKey(HKEY_LOCAL_MACHINE
,
848 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Streams"),
849 &hkStreams
) == ERROR_SUCCESS
)
851 Stream
= SHOpenRegStream(hkStreams
,
853 TEXT("Default Taskbar"),
856 RegCloseKey(hkStreams
);
863 ITrayBandSiteImpl_Load(IN OUT ITrayBandSiteImpl
*This
)
868 /* Try to load the user's settings */
869 pStm
= GetUserBandsStream(STGM_READ
);
872 hRet
= ITrayBandSiteImpl_LoadFromStream(This
,
875 DbgPrint("Loaded user bands settings: 0x%x\n", hRet
);
876 IStream_Release(pStm
);
881 /* If the user's settings couldn't be loaded, try with
882 default settings (ie. when the user logs in for the
884 if (!SUCCEEDED(hRet
))
886 pStm
= GetDefaultBandsStream(STGM_READ
);
889 hRet
= ITrayBandSiteImpl_LoadFromStream(This
,
892 DbgPrint("Loaded default user bands settings: 0x%x\n", hRet
);
893 IStream_Release(pStm
);
902 static ITrayBandSiteImpl
*
903 ITrayBandSiteImpl_Construct(IN OUT ITrayWindow
*Tray
,
904 OUT HWND
*phWndRebar
,
905 OUT HWND
*phwndTaskSwitch
)
907 ITrayBandSiteImpl
*This
;
908 IDeskBarClient
*pDbc
;
914 *phwndTaskSwitch
= NULL
;
916 This
= HeapAlloc(hProcessHeap
,
922 This
->lpVtbl
= &ITrayBandSiteImpl_Vtbl
;
923 This
->lpBandSiteVtbl
= &IBandSiteImpl_Vtbl
;
927 /* Create a RebarBandSite provided by the shell */
928 hRet
= CoCreateInstance(&CLSID_RebarBandSite
,
929 (LPUNKNOWN
)IBandSite_from_ITrayBandSiteImpl(This
),
930 CLSCTX_INPROC_SERVER
,
932 (LPVOID
*)&This
->punkInner
);
933 if (!SUCCEEDED(hRet
))
935 ITrayBandSiteImpl_Free(This
);
939 hRet
= IUnknown_QueryInterface(This
->punkInner
,
941 (PVOID
*)&This
->BandSite
);
942 if (!SUCCEEDED(hRet
))
944 ITrayBandSiteImpl_Free(This
);
948 hRet
= IUnknown_QueryInterface(This
->punkInner
,
949 &IID_IWinEventHandler
,
950 (PVOID
*)&This
->WindowEventHandler
);
951 if (!SUCCEEDED(hRet
))
953 ITrayBandSiteImpl_Free(This
);
957 This
->TaskBand
= CreateTaskBand(Tray
);
958 if (This
->TaskBand
!= NULL
)
960 /* Add the task band to the site */
961 hRet
= IBandSite_QueryInterface(This
->BandSite
,
966 hRet
= ITaskBand_QueryInterface(This
->TaskBand
,
971 /* We cause IDeskBarClient to create the rebar control by passing the new
972 task band to it. The band reports the tray window handle as window handle
973 so that IDeskBarClient knows the parent window of the Rebar control that
974 it wants to create. */
975 hRet
= IDeskBarClient_SetDeskBarSite(pDbc
,
980 /* The Rebar control is now created, we can query the window handle */
981 hRet
= IDeskBarClient_GetWindow(pDbc
,
986 /* We need to manually remove the RBS_BANDBORDERS style! */
987 SetWindowStyle(This
->hWndRebar
,
993 IOleWindow_Release(pOw
);
1000 /* Set the Desk Bar mode to the current one */
1002 /* FIXME: We need to set the mode (and update) whenever the user docks
1003 the tray window to another monitor edge! */
1005 if (!ITrayWindow_IsHorizontal(This
->Tray
))
1006 dwMode
= DBIF_VIEWMODE_VERTICAL
;
1008 hRet
= IDeskBarClient_SetModeDBC(pDbc
,
1012 IDeskBarClient_Release(pDbc
);
1015 /* Load the saved state of the task band site */
1016 /* FIXME: We should delay loading shell extensions, also see DBID_DELAYINIT */
1017 ITrayBandSiteImpl_Load(This
);
1019 /* Add the task bar band if it hasn't been added already */
1020 hRet
= ITrayBandSiteImpl_AddTaskBand(This
);
1021 if (SUCCEEDED(hRet
))
1023 hRet
= ITaskBand_QueryInterface(This
->TaskBand
,
1026 if (SUCCEEDED(hRet
))
1028 hRet
= IDeskBand_GetWindow(pDb
,
1030 if (!SUCCEEDED(hRet
))
1031 *phwndTaskSwitch
= NULL
;
1033 IDeskBand_Release(pDb
);
1037 /* Should we send this after showing it? */
1038 ITrayBandSiteImpl_Update(This
);
1040 /* FIXME: When should we send this? Does anyone care anyway? */
1041 ITrayBandSiteImpl_FinishInit(This
);
1043 /* Activate the band site */
1044 ITrayBandSiteImpl_Show(This
,
1048 *phWndRebar
= This
->hWndRebar
;
1053 /*******************************************************************/
1056 CreateTrayBandSite(IN OUT ITrayWindow
*Tray
,
1057 OUT HWND
*phWndRebar
,
1058 OUT HWND
*phWndTaskSwitch
)
1060 ITrayBandSiteImpl
*This
;
1062 This
= ITrayBandSiteImpl_Construct(Tray
,
1067 return ITrayBandSite_from_ITrayBandSiteImpl(This
);