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 /*****************************************************************************
24 ** ITrayBandSite ************************************************************
25 *****************************************************************************/
27 static const ITrayBandSiteVtbl ITrayBandSiteImpl_Vtbl
;
28 static const IBandSiteVtbl IBandSiteImpl_Vtbl
;
32 const ITrayBandSiteVtbl
*lpVtbl
;
33 const IBandSiteVtbl
*lpBandSiteVtbl
;
41 IWinEventHandler
*WindowEventHandler
;
42 IContextMenu
*ContextMenu
;
57 ITrayBandSiteImpl_Update(IN OUT ITrayBandSiteImpl
*This
);
60 IUnknown_from_ITrayBandSiteImpl(ITrayBandSiteImpl
*This
)
62 return (IUnknown
*)&This
->lpVtbl
;
65 IMPL_CASTS(ITrayBandSite
, ITrayBandSite
, lpVtbl
)
66 IMPL_CASTS(IBandSite
, ITrayBandSite
, lpBandSiteVtbl
)
68 static ULONG STDMETHODCALLTYPE
69 ITrayBandSiteImpl_AddRef(IN OUT ITrayBandSite
*iface
)
71 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
73 return InterlockedIncrement(&This
->Ref
);
77 ITrayBandSiteImpl_Free(IN OUT ITrayBandSiteImpl
*This
)
79 if (This
->BandSite
!= NULL
)
81 IBandSite_Release(This
->BandSite
);
82 This
->BandSite
= NULL
;
85 if (This
->WindowEventHandler
!= NULL
)
87 IWinEventHandler_Release(This
->WindowEventHandler
);
88 This
->WindowEventHandler
= NULL
;
91 if (This
->ContextMenu
!= NULL
)
93 IContextMenu_Release(This
->ContextMenu
);
94 This
->ContextMenu
= NULL
;
97 if (This
->punkInner
!= NULL
)
99 IUnknown_Release(This
->punkInner
);
100 This
->punkInner
= NULL
;
103 HeapFree(hProcessHeap
,
108 static ULONG STDMETHODCALLTYPE
109 ITrayBandSiteImpl_Release(IN OUT ITrayBandSite
*iface
)
111 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
114 Ret
= InterlockedDecrement(&This
->Ref
);
117 ITrayBandSiteImpl_Free(This
);
122 static HRESULT STDMETHODCALLTYPE
123 ITrayBandSiteImpl_QueryInterface(IN OUT ITrayBandSite
*iface
,
127 ITrayBandSiteImpl
*This
;
132 This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
137 &IID_IBandSiteStreamCallback
))
139 /* NOTE: IID_IBandSiteStreamCallback is queried by the shell, we
140 implement this interface directly */
141 *ppvObj
= IUnknown_from_ITrayBandSiteImpl(This
);
143 else if (IsEqualIID(riid
,
146 *ppvObj
= IBandSite_from_ITrayBandSiteImpl(This
);
148 else if (IsEqualIID(riid
,
149 &IID_IWinEventHandler
))
151 DbgPrint("ITaskBandSite: IWinEventHandler queried!\n");
153 return E_NOINTERFACE
;
155 else if (This
->punkInner
!= NULL
)
157 return IUnknown_QueryInterface(This
->punkInner
,
164 return E_NOINTERFACE
;
167 ITrayBandSiteImpl_AddRef(iface
);
171 static HRESULT STDMETHODCALLTYPE
172 ITrayBandSiteImpl_OnLoad(IN OUT ITrayBandSite
*iface
,
173 IN OUT IStream
*pStm
,
177 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
178 LARGE_INTEGER liPosZero
;
179 ULARGE_INTEGER liCurrent
;
184 /* NOTE: Callback routine called by the shell while loading the task band
185 stream. We use it to intercept the default behavior when the task
186 band is loaded from the stream.
188 NOTE: riid always points to IID_IUnknown! This is because the shell hasn't
189 read anything from the stream and therefore doesn't know what CLSID
190 it's dealing with. We'll have to find it out ourselves by reading
191 the GUID from the stream. */
193 /* Read the current position of the stream, we'll have to reset it everytime
194 we read a CLSID that's not the task band... */
195 ZeroMemory(&liPosZero
,
197 hRet
= IStream_Seek(pStm
,
204 /* Now let's read the CLSID from the stream and see if it's our task band */
205 #if defined(IStream_Read)
206 hRet
= IStream_Read(pStm
,
211 ulRead
= sizeof(clsid
);
212 hRet
= IStream_Read(pStm
,
216 if (SUCCEEDED(hRet
) && ulRead
== sizeof(clsid
))
218 if (IsEqualGUID(&clsid
,
221 ASSERT(This
->TaskBand
!= NULL
);
222 /* We're trying to load the task band! Let's create it... */
224 hRet
= ITaskBand_QueryInterface(This
->TaskBand
,
229 /* Load the stream */
230 DbgPrint("IBandSiteStreamCallback::OnLoad intercepted the task band CLSID!\n");
238 /* Reset the position and let the shell do all the work for us */
239 hRet
= IStream_Seek(pStm
,
240 *(LARGE_INTEGER
*)&liCurrent
,
245 /* Let the shell handle everything else for us :) */
246 hRet
= OleLoadFromStream(pStm
,
251 if (!SUCCEEDED(hRet
))
253 DbgPrint("IBandSiteStreamCallback::OnLoad(0x%p, 0x%p, 0x%p) returns 0x%x\n", pStm
, riid
, pvObj
, hRet
);
259 static HRESULT STDMETHODCALLTYPE
260 ITrayBandSiteImpl_OnSave(IN OUT ITrayBandSite
*iface
,
261 IN OUT IUnknown
*pUnk
,
262 IN OUT IStream
*pStm
)
264 /* NOTE: Callback routine called by the shell while saving the task band
265 stream. We use it to intercept the default behavior when the task
266 band is saved to the stream */
267 /* FIXME: Implement */
268 DbgPrint("IBandSiteStreamCallback::OnSave(0x%p, 0x%p) returns E_NOTIMPL\n", pUnk
, pStm
);
273 IsSameObject(IN IUnknown
*punk1
,
278 hRet
= IUnknown_QueryInterface(punk1
,
281 if (!SUCCEEDED(hRet
))
284 hRet
= IUnknown_QueryInterface(punk2
,
287 IUnknown_Release(punk1
);
289 if (!SUCCEEDED(hRet
))
292 IUnknown_Release(punk2
);
294 /* We're dealing with the same object if the IUnknown pointers are equal */
295 return (punk1
== punk2
) ? S_OK
: S_FALSE
;
298 static HRESULT STDMETHODCALLTYPE
299 ITrayBandSiteImpl_IsTaskBand(IN OUT ITrayBandSite
*iface
,
302 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
303 return IsSameObject((IUnknown
*)This
->BandSite
,
307 static HRESULT STDMETHODCALLTYPE
308 ITrayBandSiteImpl_ProcessMessage(IN OUT ITrayBandSite
*iface
,
313 OUT LRESULT
*plResult
)
315 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
318 ASSERT(This
->hWndRebar
!= NULL
);
320 /* Custom task band behavior */
325 const NMHDR
*nmh
= (const NMHDR
*)lParam
;
327 if (nmh
->hwndFrom
== This
->hWndRebar
)
333 LPNMMOUSE nmm
= (LPNMMOUSE
)lParam
;
335 if (nmm
->dwHitInfo
== RBHT_CLIENT
|| nmm
->dwHitInfo
== RBHT_NOWHERE
||
336 nmm
->dwItemSpec
== (DWORD_PTR
)-1)
338 /* Make the rebar control appear transparent so the user
339 can drag the tray window */
340 *plResult
= HTTRANSPARENT
;
346 /* Deny if an Administrator disabled this "feature" */
347 *plResult
= (SHRestricted(REST_NOMOVINGBAND
) != 0);
352 //DbgPrint("ITrayBandSite::ProcessMessage: WM_NOTIFY for 0x%p, From: 0x%p, Code: NM_FIRST-%u...\n", hWnd, nmh->hwndFrom, NM_FIRST - nmh->code);
357 /* Forward to the shell's IWinEventHandler interface to get the default
359 if (This
->WindowEventHandler
!= NULL
)
361 /*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);*/
362 hRet
= IWinEventHandler_OnWinEvent(This
->WindowEventHandler
,
368 if (!SUCCEEDED(hRet
))
370 if (uMsg
== WM_NOTIFY
)
372 const NMHDR
*nmh
= (const NMHDR
*)lParam
;
373 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
);
377 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
);
387 static HRESULT STDMETHODCALLTYPE
388 ITrayBandSiteImpl_AddContextMenus(IN OUT ITrayBandSite
*iface
,
394 OUT IContextMenu
**ppcm
)
396 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
400 if (This
->ContextMenu
== NULL
)
402 /* Cache the context menu so we don't need to CoCreateInstance all the time... */
403 hRet
= CoCreateInstance(&CLSID_IShellBandSiteMenu
,
405 CLSCTX_INPROC_SERVER
,
408 DbgPrint("CoCreateInstance(CLSID_IShellBandSiteMenu) for IShellService returned: 0x%x\n", hRet
);
409 if (!SUCCEEDED(hRet
))
412 hRet
= IShellService_SetOwner(pSs
,
413 IUnknown_from_ITrayBandSiteImpl(This
));
414 if (!SUCCEEDED(hRet
))
416 IShellService_Release(pSs
);
420 hRet
= IShellService_QueryInterface(pSs
,
422 (PVOID
*)&This
->ContextMenu
);
424 IShellService_Release(pSs
);
426 if (!SUCCEEDED(hRet
))
432 IContextMenu_AddRef(This
->ContextMenu
);
433 *ppcm
= This
->ContextMenu
;
436 /* Add the menu items */
437 return IContextMenu_QueryContextMenu(This
->ContextMenu
,
445 static HRESULT STDMETHODCALLTYPE
446 ITrayBandSiteImpl_Lock(IN OUT ITrayBandSite
*iface
,
449 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_ITrayBandSite(iface
);
450 BOOL bPrevLocked
= This
->Locked
;
454 ASSERT(This
->BandSite
!= NULL
);
456 if (bPrevLocked
!= bLock
)
458 This
->Locked
= bLock
;
460 bsi
.dwMask
= BSIM_STYLE
;
461 bsi
.dwStyle
= (This
->Locked
? BSIS_LOCKED
| BSIS_NOGRIPPER
: BSIS_AUTOGRIPPER
);
463 hRet
= IBandSite_SetBandSiteInfo(This
->BandSite
,
467 hRet
= ITrayBandSiteImpl_Update(This
);
476 static const ITrayBandSiteVtbl ITrayBandSiteImpl_Vtbl
=
478 /*** IUnknown methods ***/
479 ITrayBandSiteImpl_QueryInterface
,
480 ITrayBandSiteImpl_AddRef
,
481 ITrayBandSiteImpl_Release
,
482 /*** IBandSiteStreamCallback methods ***/
483 ITrayBandSiteImpl_OnLoad
,
484 ITrayBandSiteImpl_OnSave
,
485 /*** ITrayBandSite methods ***/
486 ITrayBandSiteImpl_IsTaskBand
,
487 ITrayBandSiteImpl_ProcessMessage
,
488 ITrayBandSiteImpl_AddContextMenus
,
489 ITrayBandSiteImpl_Lock
492 /*******************************************************************/
494 METHOD_IUNKNOWN_INHERITED_ADDREF(IBandSite
, ITrayBandSite
)
495 METHOD_IUNKNOWN_INHERITED_RELEASE(IBandSite
, ITrayBandSite
)
496 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IBandSite
, ITrayBandSite
)
498 static HRESULT STDMETHODCALLTYPE
499 ITrayBandSiteImpl_AddBand(IN OUT IBandSite
*iface
,
502 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
503 IOleCommandTarget
*pOct
;
506 hRet
= IUnknown_QueryInterface(punk
,
507 &IID_IOleCommandTarget
,
511 /* Send the DBID_DELAYINIT command to initialize the band to be added */
512 /* FIXME: Should be delayed */
513 IOleCommandTarget_Exec(pOct
,
520 IOleCommandTarget_Release(pOct
);
523 return IBandSite_AddBand(This
->BandSite
,
527 static HRESULT STDMETHODCALLTYPE
528 ITrayBandSiteImpl_EnumBands(IN OUT IBandSite
*iface
,
530 OUT DWORD
*pdwBandID
)
532 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
533 return IBandSite_EnumBands(This
->BandSite
,
538 static HRESULT STDMETHODCALLTYPE
539 ITrayBandSiteImpl_QueryBand(IN OUT IBandSite
*iface
,
541 OUT IDeskBand
**ppstb
,
547 IDeskBand
*pstb
= NULL
;
548 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
550 hRet
= IBandSite_QueryBand(This
->BandSite
,
559 hRet
= IsSameObject((IUnknown
*)pstb
,
560 (IUnknown
*)This
->TaskBand
);
563 /* Add the BSSF_UNDELETEABLE flag to pdwState because the task bar band shouldn't be deletable */
564 if (pdwState
!= NULL
)
565 *pdwState
|= BSSF_UNDELETEABLE
;
567 else if (!SUCCEEDED(hRet
))
569 IDeskBand_Release(pstb
);
576 else if (ppstb
!= NULL
)
582 static HRESULT STDMETHODCALLTYPE
583 ITrayBandSiteImpl_SetBandState(IN OUT IBandSite
*iface
,
588 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
589 return IBandSite_SetBandState(This
->BandSite
,
595 static HRESULT STDMETHODCALLTYPE
596 ITrayBandSiteImpl_RemoveBand(IN OUT IBandSite
*iface
,
599 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
600 return IBandSite_RemoveBand(This
->BandSite
,
604 static HRESULT STDMETHODCALLTYPE
605 ITrayBandSiteImpl_GetBandObject(IN OUT IBandSite
*iface
,
610 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
611 return IBandSite_GetBandObject(This
->BandSite
,
617 static HRESULT STDMETHODCALLTYPE
618 ITrayBandSiteImpl_SetBandSiteInfo(IN OUT IBandSite
*iface
,
619 IN
const BANDSITEINFO
*pbsinfo
)
621 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
622 return IBandSite_SetBandSiteInfo(This
->BandSite
,
626 static HRESULT STDMETHODCALLTYPE
627 ITrayBandSiteImpl_GetBandSiteInfo(IN OUT IBandSite
*iface
,
628 IN OUT BANDSITEINFO
*pbsinfo
)
630 ITrayBandSiteImpl
*This
= ITrayBandSiteImpl_from_IBandSite(iface
);
631 return IBandSite_GetBandSiteInfo(This
->BandSite
,
635 static const IBandSiteVtbl IBandSiteImpl_Vtbl
=
637 /*** IUnknown methods ***/
638 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IBandSite
, ITrayBandSite
),
639 METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IBandSite
, ITrayBandSite
),
640 METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IBandSite
, ITrayBandSite
),
641 /*** IBandSite methods ***/
642 ITrayBandSiteImpl_AddBand
,
643 ITrayBandSiteImpl_EnumBands
,
644 ITrayBandSiteImpl_QueryBand
,
645 ITrayBandSiteImpl_SetBandState
,
646 ITrayBandSiteImpl_RemoveBand
,
647 ITrayBandSiteImpl_GetBandObject
,
648 ITrayBandSiteImpl_SetBandSiteInfo
,
649 ITrayBandSiteImpl_GetBandSiteInfo
,
653 ITrayBandSiteImpl_HasTaskBand(IN OUT ITrayBandSiteImpl
*This
)
655 ASSERT(This
->TaskBand
!= NULL
);
657 return SUCCEEDED(ITaskBand_GetRebarBandID(This
->TaskBand
,
662 ITrayBandSiteImpl_AddTaskBand(IN OUT ITrayBandSiteImpl
*This
)
665 /* FIXME: This is the code for the simple taskbar */
666 IObjectWithSite
*pOws
;
669 hRet
= ITaskBand_QueryInterface(This
->TaskBand
,
670 &IID_IObjectWithSite
,
674 hRet
= IObjectWithSite_SetSite(pOws
,
675 (IUnknown
*)This
->TaskBand
);
677 IObjectWithSite_Release(pOws
);
682 if (!ITrayBandSiteImpl_HasTaskBand(This
))
684 return IBandSite_AddBand(This
->BandSite
,
685 (IUnknown
*)This
->TaskBand
);
693 ITrayBandSiteImpl_Update(IN OUT ITrayBandSiteImpl
*This
)
695 IOleCommandTarget
*pOct
;
698 hRet
= IUnknown_QueryInterface(This
->punkInner
,
699 &IID_IOleCommandTarget
,
703 /* Send the DBID_BANDINFOCHANGED command to update the band site */
704 hRet
= IOleCommandTarget_Exec(pOct
,
706 DBID_BANDINFOCHANGED
,
711 IOleCommandTarget_Release(pOct
);
718 ITrayBandSiteImpl_BroadcastOleCommandExec(IN OUT ITrayBandSiteImpl
*This
,
719 const GUID
*pguidCmdGroup
,
725 IOleCommandTarget
*pOct
;
729 /* Enumerate all bands */
730 while (SUCCEEDED(IBandSite_EnumBands(This
->BandSite
,
734 if (SUCCEEDED(IBandSite_GetBandObject(This
->BandSite
,
736 &IID_IOleCommandTarget
,
739 /* Execute the command */
740 IOleCommandTarget_Exec(pOct
,
747 IOleCommandTarget_Release(pOct
);
755 ITrayBandSiteImpl_FinishInit(IN OUT ITrayBandSiteImpl
*This
)
757 /* Broadcast the DBID_FINISHINIT command */
758 ITrayBandSiteImpl_BroadcastOleCommandExec(This
,
769 ITrayBandSiteImpl_Show(IN OUT ITrayBandSiteImpl
*This
,
772 IDeskBarClient
*pDbc
;
775 hRet
= IBandSite_QueryInterface(This
->BandSite
,
780 hRet
= IDeskBarClient_UIActivateDBC(pDbc
,
781 bShow
? DBC_SHOW
: DBC_HIDE
);
782 IDeskBarClient_Release(pDbc
);
789 ITrayBandSiteImpl_LoadFromStream(IN OUT ITrayBandSiteImpl
*This
,
790 IN OUT IStream
*pStm
)
792 IPersistStream
*pPStm
;
795 ASSERT(This
->BandSite
!= NULL
);
797 /* We implement the undocumented COM interface IBandSiteStreamCallback
798 that the shell will query so that we can intercept and custom-load
799 the task band when it finds the task band's CLSID (which is internal).
800 This way we can prevent the shell from attempting to CoCreateInstance
801 the (internal) task band, resulting in a failure... */
802 hRet
= IBandSite_QueryInterface(This
->BandSite
,
807 hRet
= IPersistStream_Load(pPStm
,
809 DbgPrint("IPersistStream_Load() returned 0x%x\n", hRet
);
810 IPersistStream_Release(pPStm
);
817 GetUserBandsStream(IN DWORD grfMode
)
820 IStream
*Stream
= NULL
;
822 if (RegCreateKey(hkExplorer
,
824 &hkStreams
) == ERROR_SUCCESS
)
826 Stream
= SHOpenRegStream(hkStreams
,
828 TEXT("TaskbarWinXP"),
831 RegCloseKey(hkStreams
);
838 GetDefaultBandsStream(IN DWORD grfMode
)
841 IStream
*Stream
= NULL
;
843 if (RegCreateKey(HKEY_LOCAL_MACHINE
,
844 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Streams"),
845 &hkStreams
) == ERROR_SUCCESS
)
847 Stream
= SHOpenRegStream(hkStreams
,
849 TEXT("Default Taskbar"),
852 RegCloseKey(hkStreams
);
859 ITrayBandSiteImpl_Load(IN OUT ITrayBandSiteImpl
*This
)
864 /* Try to load the user's settings */
865 pStm
= GetUserBandsStream(STGM_READ
);
868 hRet
= ITrayBandSiteImpl_LoadFromStream(This
,
871 DbgPrint("Loaded user bands settings: 0x%x\n", hRet
);
872 IStream_Release(pStm
);
877 /* If the user's settings couldn't be loaded, try with
878 default settings (ie. when the user logs in for the
880 if (!SUCCEEDED(hRet
))
882 pStm
= GetDefaultBandsStream(STGM_READ
);
885 hRet
= ITrayBandSiteImpl_LoadFromStream(This
,
888 DbgPrint("Loaded default user bands settings: 0x%x\n", hRet
);
889 IStream_Release(pStm
);
898 static ITrayBandSiteImpl
*
899 ITrayBandSiteImpl_Construct(IN OUT ITrayWindow
*Tray
,
900 OUT HWND
*phWndRebar
,
901 OUT HWND
*phwndTaskSwitch
)
903 ITrayBandSiteImpl
*This
;
904 IDeskBarClient
*pDbc
;
910 *phwndTaskSwitch
= NULL
;
912 This
= HeapAlloc(hProcessHeap
,
920 This
->lpVtbl
= &ITrayBandSiteImpl_Vtbl
;
921 This
->lpBandSiteVtbl
= &IBandSiteImpl_Vtbl
;
925 /* Create a RebarBandSite provided by the shell */
926 hRet
= CoCreateInstance(&CLSID_RebarBandSite
,
927 (LPUNKNOWN
)IBandSite_from_ITrayBandSiteImpl(This
),
928 CLSCTX_INPROC_SERVER
,
930 (LPVOID
*)&This
->punkInner
);
931 if (!SUCCEEDED(hRet
))
933 ITrayBandSiteImpl_Free(This
);
937 hRet
= IUnknown_QueryInterface(This
->punkInner
,
939 (PVOID
*)&This
->BandSite
);
940 if (!SUCCEEDED(hRet
))
942 ITrayBandSiteImpl_Free(This
);
946 hRet
= IUnknown_QueryInterface(This
->punkInner
,
947 &IID_IWinEventHandler
,
948 (PVOID
*)&This
->WindowEventHandler
);
949 if (!SUCCEEDED(hRet
))
951 ITrayBandSiteImpl_Free(This
);
955 This
->TaskBand
= CreateTaskBand(Tray
);
956 if (This
->TaskBand
!= NULL
)
958 /* Add the task band to the site */
959 hRet
= IBandSite_QueryInterface(This
->BandSite
,
964 hRet
= ITaskBand_QueryInterface(This
->TaskBand
,
969 /* We cause IDeskBarClient to create the rebar control by passing the new
970 task band to it. The band reports the tray window handle as window handle
971 so that IDeskBarClient knows the parent window of the Rebar control that
972 it wants to create. */
973 hRet
= IDeskBarClient_SetDeskBarSite(pDbc
,
978 /* The Rebar control is now created, we can query the window handle */
979 hRet
= IDeskBarClient_GetWindow(pDbc
,
984 /* We need to manually remove the RBS_BANDBORDERS style! */
985 SetWindowStyle(This
->hWndRebar
,
991 IOleWindow_Release(pOw
);
998 /* Set the Desk Bar mode to the current one */
1000 /* FIXME: We need to set the mode (and update) whenever the user docks
1001 the tray window to another monitor edge! */
1003 if (!ITrayWindow_IsHorizontal(This
->Tray
))
1004 dwMode
= DBIF_VIEWMODE_VERTICAL
;
1006 hRet
= IDeskBarClient_SetModeDBC(pDbc
,
1010 IDeskBarClient_Release(pDbc
);
1013 /* Load the saved state of the task band site */
1014 /* FIXME: We should delay loading shell extensions, also see DBID_DELAYINIT */
1015 ITrayBandSiteImpl_Load(This
);
1017 /* Add the task bar band if it hasn't been added already */
1018 hRet
= ITrayBandSiteImpl_AddTaskBand(This
);
1019 if (SUCCEEDED(hRet
))
1021 hRet
= ITaskBand_QueryInterface(This
->TaskBand
,
1024 if (SUCCEEDED(hRet
))
1026 hRet
= IDeskBand_GetWindow(pDb
,
1028 if (!SUCCEEDED(hRet
))
1029 *phwndTaskSwitch
= NULL
;
1031 IDeskBand_Release(pDb
);
1035 /* Should we send this after showing it? */
1036 ITrayBandSiteImpl_Update(This
);
1038 /* FIXME: When should we send this? Does anyone care anyway? */
1039 ITrayBandSiteImpl_FinishInit(This
);
1041 /* Activate the band site */
1042 ITrayBandSiteImpl_Show(This
,
1046 *phWndRebar
= This
->hWndRebar
;
1051 /*******************************************************************/
1054 CreateTrayBandSite(IN OUT ITrayWindow
*Tray
,
1055 OUT HWND
*phWndRebar
,
1056 OUT HWND
*phWndTaskSwitch
)
1058 ITrayBandSiteImpl
*This
;
1060 This
= ITrayBandSiteImpl_Construct(Tray
,
1065 return ITrayBandSite_from_ITrayBandSiteImpl(This
);