1c2c66affSColin Finck /*
2c2c66affSColin Finck * ReactOS Explorer
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
5c2c66affSColin Finck *
6c2c66affSColin Finck * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck * License as published by the Free Software Foundation; either
9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck *
11c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14c2c66affSColin Finck * Lesser General Public License for more details.
15c2c66affSColin Finck *
16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19c2c66affSColin Finck */
20c2c66affSColin Finck
21c2c66affSColin Finck #include "precomp.h"
22c2c66affSColin Finck
23c2c66affSColin Finck #include <shdeprecated.h>
24c2c66affSColin Finck
25c2c66affSColin Finck /*****************************************************************************
26c2c66affSColin Finck ** ITrayBandSite ************************************************************
27c2c66affSColin Finck *****************************************************************************/
28c2c66affSColin Finck
29c2c66affSColin Finck // WARNING: Can't use ATL for this class due to our ATL not fully supporting the AGGREGATION functions needed for this class to be an "outer" class
30c2c66affSColin Finck // it works just fine this way.
31c2c66affSColin Finck class CTrayBandSite :
32c2c66affSColin Finck public ITrayBandSite,
33c2c66affSColin Finck public IBandSite,
34c2c66affSColin Finck public IBandSiteStreamCallback
35c2c66affSColin Finck /* TODO: IWinEventHandler */
36c2c66affSColin Finck {
37c2c66affSColin Finck volatile LONG m_RefCount;
38c2c66affSColin Finck
39c2c66affSColin Finck CComPtr<ITrayWindow> m_Tray;
40c2c66affSColin Finck
41c2c66affSColin Finck CComPtr<IUnknown> m_Inner;
42c2c66affSColin Finck CComPtr<IBandSite> m_BandSite;
43c2c66affSColin Finck CComPtr<IDeskBand> m_TaskBand;
44c2c66affSColin Finck CComPtr<IWinEventHandler> m_WindowEventHandler;
45c2c66affSColin Finck CComPtr<IContextMenu> m_ContextMenu;
46c2c66affSColin Finck
47c2c66affSColin Finck HWND m_Rebar;
48c2c66affSColin Finck
49c2c66affSColin Finck union
50c2c66affSColin Finck {
51c2c66affSColin Finck DWORD dwFlags;
52c2c66affSColin Finck struct
53c2c66affSColin Finck {
54c2c66affSColin Finck DWORD Locked : 1;
55c2c66affSColin Finck };
56c2c66affSColin Finck };
57c2c66affSColin Finck
58c2c66affSColin Finck public:
59*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP_(ULONG)
AddRef()60*853b8ebdSKatayama Hirofumi MZ AddRef() override
61c2c66affSColin Finck {
62c2c66affSColin Finck return InterlockedIncrement(&m_RefCount);
63c2c66affSColin Finck }
64c2c66affSColin Finck
65*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP_(ULONG)
Release()66*853b8ebdSKatayama Hirofumi MZ Release() override
67c2c66affSColin Finck {
68c2c66affSColin Finck ULONG Ret = InterlockedDecrement(&m_RefCount);
69c2c66affSColin Finck
70c2c66affSColin Finck if (Ret == 0)
71c2c66affSColin Finck delete this;
72c2c66affSColin Finck
73c2c66affSColin Finck return Ret;
74c2c66affSColin Finck }
75c2c66affSColin Finck
76*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
QueryInterface(IN REFIID riid,OUT LPVOID * ppvObj)77*853b8ebdSKatayama Hirofumi MZ QueryInterface(IN REFIID riid, OUT LPVOID *ppvObj) override
78c2c66affSColin Finck {
79c2c66affSColin Finck if (ppvObj == NULL)
80c2c66affSColin Finck return E_POINTER;
81c2c66affSColin Finck
82c2c66affSColin Finck if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IBandSiteHelper))
83c2c66affSColin Finck {
84c2c66affSColin Finck // return IBandSiteStreamCallback's IUnknown
85c2c66affSColin Finck *ppvObj = static_cast<IBandSiteStreamCallback*>(this);
86c2c66affSColin Finck }
87c2c66affSColin Finck else if (IsEqualIID(riid, IID_IBandSite))
88c2c66affSColin Finck {
89c2c66affSColin Finck *ppvObj = static_cast<IBandSite*>(this);
90c2c66affSColin Finck }
91c2c66affSColin Finck else if (IsEqualIID(riid, IID_IWinEventHandler))
92c2c66affSColin Finck {
93c2c66affSColin Finck TRACE("ITaskBandSite: IWinEventHandler queried!\n");
94c2c66affSColin Finck *ppvObj = NULL;
95c2c66affSColin Finck return E_NOINTERFACE;
96c2c66affSColin Finck }
97c2c66affSColin Finck else if (m_Inner != NULL)
98c2c66affSColin Finck {
99c2c66affSColin Finck return m_Inner->QueryInterface(riid, ppvObj);
100c2c66affSColin Finck }
101c2c66affSColin Finck else
102c2c66affSColin Finck {
103c2c66affSColin Finck *ppvObj = NULL;
104c2c66affSColin Finck return E_NOINTERFACE;
105c2c66affSColin Finck }
106c2c66affSColin Finck
107c2c66affSColin Finck AddRef();
108c2c66affSColin Finck return S_OK;
109c2c66affSColin Finck }
110c2c66affSColin Finck
111c2c66affSColin Finck public:
CTrayBandSite()112c2c66affSColin Finck CTrayBandSite() :
113c2c66affSColin Finck m_RefCount(0),
114c2c66affSColin Finck m_Rebar(NULL)
115c2c66affSColin Finck {
116c2c66affSColin Finck }
117c2c66affSColin Finck
~CTrayBandSite()118c2c66affSColin Finck virtual ~CTrayBandSite() { }
119c2c66affSColin Finck
120*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
OnLoad(IN OUT IStream * pStm,IN REFIID riid,OUT PVOID * pvObj)121*853b8ebdSKatayama Hirofumi MZ OnLoad(
122c2c66affSColin Finck IN OUT IStream *pStm,
123c2c66affSColin Finck IN REFIID riid,
124*853b8ebdSKatayama Hirofumi MZ OUT PVOID *pvObj) override
125c2c66affSColin Finck {
126c2c66affSColin Finck LARGE_INTEGER liPosZero;
127c2c66affSColin Finck ULARGE_INTEGER liCurrent;
128c2c66affSColin Finck CLSID clsid;
129c2c66affSColin Finck ULONG ulRead;
130c2c66affSColin Finck HRESULT hRet;
131c2c66affSColin Finck
132c2c66affSColin Finck /* NOTE: Callback routine called by the shell while loading the task band
133c2c66affSColin Finck stream. We use it to intercept the default behavior when the task
134c2c66affSColin Finck band is loaded from the stream.
135c2c66affSColin Finck
136c2c66affSColin Finck NOTE: riid always points to IID_IUnknown! This is because the shell hasn't
137c2c66affSColin Finck read anything from the stream and therefore doesn't know what CLSID
138c2c66affSColin Finck it's dealing with. We'll have to find it out ourselves by reading
139c2c66affSColin Finck the GUID from the stream. */
140c2c66affSColin Finck
141c2c66affSColin Finck /* Read the current position of the stream, we'll have to reset it everytime
142c2c66affSColin Finck we read a CLSID that's not the task band... */
143c2c66affSColin Finck ZeroMemory(&liPosZero, sizeof(liPosZero));
144c2c66affSColin Finck hRet = pStm->Seek(liPosZero, STREAM_SEEK_CUR, &liCurrent);
145c2c66affSColin Finck
146c2c66affSColin Finck if (SUCCEEDED(hRet))
147c2c66affSColin Finck {
148c2c66affSColin Finck /* Now let's read the CLSID from the stream and see if it's our task band */
149c2c66affSColin Finck hRet = pStm->Read(&clsid, (ULONG)sizeof(clsid), &ulRead);
150c2c66affSColin Finck
151c2c66affSColin Finck if (SUCCEEDED(hRet) && ulRead == sizeof(clsid))
152c2c66affSColin Finck {
153c2c66affSColin Finck if (IsEqualGUID(clsid, CLSID_ITaskBand))
154c2c66affSColin Finck {
155c2c66affSColin Finck ASSERT(m_TaskBand != NULL);
156c2c66affSColin Finck /* We're trying to load the task band! Let's create it... */
157c2c66affSColin Finck
158c2c66affSColin Finck hRet = m_TaskBand->QueryInterface(
159c2c66affSColin Finck riid,
160c2c66affSColin Finck pvObj);
161c2c66affSColin Finck if (SUCCEEDED(hRet))
162c2c66affSColin Finck {
163c2c66affSColin Finck /* Load the stream */
164c2c66affSColin Finck TRACE("IBandSiteStreamCallback::OnLoad intercepted the task band CLSID!\n");
165c2c66affSColin Finck }
166c2c66affSColin Finck
167c2c66affSColin Finck return hRet;
168c2c66affSColin Finck }
169c2c66affSColin Finck }
170c2c66affSColin Finck }
171c2c66affSColin Finck
172c2c66affSColin Finck /* Reset the position and let the shell do all the work for us */
173c2c66affSColin Finck hRet = pStm->Seek(
174c2c66affSColin Finck *(LARGE_INTEGER*) &liCurrent,
175c2c66affSColin Finck STREAM_SEEK_SET,
176c2c66affSColin Finck NULL);
177c2c66affSColin Finck if (SUCCEEDED(hRet))
178c2c66affSColin Finck {
179c2c66affSColin Finck /* Let the shell handle everything else for us :) */
180c2c66affSColin Finck hRet = OleLoadFromStream(pStm,
181c2c66affSColin Finck riid,
182c2c66affSColin Finck pvObj);
183c2c66affSColin Finck }
184c2c66affSColin Finck
185c2c66affSColin Finck if (!SUCCEEDED(hRet))
186c2c66affSColin Finck {
187c2c66affSColin Finck TRACE("IBandSiteStreamCallback::OnLoad(0x%p, 0x%p, 0x%p) returns 0x%x\n", pStm, riid, pvObj, hRet);
188c2c66affSColin Finck }
189c2c66affSColin Finck
190c2c66affSColin Finck return hRet;
191c2c66affSColin Finck }
192c2c66affSColin Finck
193*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
OnSave(IN OUT IUnknown * pUnk,IN OUT IStream * pStm)194*853b8ebdSKatayama Hirofumi MZ OnSave(
195c2c66affSColin Finck IN OUT IUnknown *pUnk,
196*853b8ebdSKatayama Hirofumi MZ IN OUT IStream *pStm) override
197c2c66affSColin Finck {
198c2c66affSColin Finck /* NOTE: Callback routine called by the shell while saving the task band
199c2c66affSColin Finck stream. We use it to intercept the default behavior when the task
200c2c66affSColin Finck band is saved to the stream */
201c2c66affSColin Finck /* FIXME: Implement */
202c2c66affSColin Finck TRACE("IBandSiteStreamCallback::OnSave(0x%p, 0x%p) returns E_NOTIMPL\n", pUnk, pStm);
203c2c66affSColin Finck return E_NOTIMPL;
204c2c66affSColin Finck }
205c2c66affSColin Finck
206*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
IsTaskBand(IN IUnknown * punk)207*853b8ebdSKatayama Hirofumi MZ IsTaskBand(IN IUnknown *punk) override
208c2c66affSColin Finck {
209c2c66affSColin Finck return IsSameObject(m_BandSite, punk);
210c2c66affSColin Finck }
211c2c66affSColin Finck
212*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
ProcessMessage(IN HWND hWnd,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam,OUT LRESULT * plResult)213*853b8ebdSKatayama Hirofumi MZ ProcessMessage(
214c2c66affSColin Finck IN HWND hWnd,
215c2c66affSColin Finck IN UINT uMsg,
216c2c66affSColin Finck IN WPARAM wParam,
217c2c66affSColin Finck IN LPARAM lParam,
218*853b8ebdSKatayama Hirofumi MZ OUT LRESULT *plResult) override
219c2c66affSColin Finck {
220c2c66affSColin Finck HRESULT hRet;
221c2c66affSColin Finck
222c2c66affSColin Finck ASSERT(m_Rebar != NULL);
223c2c66affSColin Finck
224c2c66affSColin Finck /* Custom task band behavior */
225c2c66affSColin Finck switch (uMsg)
226c2c66affSColin Finck {
227c2c66affSColin Finck case WM_NOTIFY:
228c2c66affSColin Finck {
229c2c66affSColin Finck const NMHDR *nmh = (const NMHDR *) lParam;
230c2c66affSColin Finck
231c2c66affSColin Finck if (nmh->hwndFrom == m_Rebar)
232c2c66affSColin Finck {
233c2c66affSColin Finck switch (nmh->code)
234c2c66affSColin Finck {
235c2c66affSColin Finck case NM_NCHITTEST:
236c2c66affSColin Finck {
237c2c66affSColin Finck LPNMMOUSE nmm = (LPNMMOUSE) lParam;
238c2c66affSColin Finck
239c2c66affSColin Finck if (nmm->dwHitInfo == RBHT_CLIENT || nmm->dwHitInfo == RBHT_NOWHERE ||
240c2c66affSColin Finck nmm->dwItemSpec == (DWORD_PTR) -1)
241c2c66affSColin Finck {
242c2c66affSColin Finck /* Make the rebar control appear transparent so the user
243c2c66affSColin Finck can drag the tray window */
244c2c66affSColin Finck *plResult = HTTRANSPARENT;
245c2c66affSColin Finck }
246c2c66affSColin Finck return S_OK;
247c2c66affSColin Finck }
248c2c66affSColin Finck
249c2c66affSColin Finck case RBN_MINMAX:
250c2c66affSColin Finck /* Deny if an Administrator disabled this "feature" */
251c2c66affSColin Finck *plResult = (SHRestricted(REST_NOMOVINGBAND) != 0);
252c2c66affSColin Finck return S_OK;
253c2c66affSColin Finck }
254c2c66affSColin Finck }
255c2c66affSColin Finck
256c2c66affSColin Finck //TRACE("ITrayBandSite::ProcessMessage: WM_NOTIFY for 0x%p, From: 0x%p, Code: NM_FIRST-%u...\n", hWnd, nmh->hwndFrom, NM_FIRST - nmh->code);
257c2c66affSColin Finck break;
258c2c66affSColin Finck }
259c2c66affSColin Finck }
260c2c66affSColin Finck
261c2c66affSColin Finck /* Forward to the shell's IWinEventHandler interface to get the default shell behavior! */
262c2c66affSColin Finck if (!m_WindowEventHandler)
263c2c66affSColin Finck return E_FAIL;
264c2c66affSColin Finck
265c2c66affSColin Finck /*TRACE("Calling IWinEventHandler::ProcessMessage(0x%p, 0x%x, 0x%p, 0x%p, 0x%p) hWndRebar=0x%p\n", hWnd, uMsg, wParam, lParam, plResult, hWndRebar);*/
266c2c66affSColin Finck hRet = m_WindowEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, plResult);
267c2c66affSColin Finck
268c2c66affSColin Finck #if 0
269c2c66affSColin Finck if (FAILED(hRet))
270c2c66affSColin Finck {
271c2c66affSColin Finck if (uMsg == WM_NOTIFY)
272c2c66affSColin Finck {
273c2c66affSColin Finck const NMHDR *nmh = (const NMHDR *) lParam;
274c2c66affSColin Finck ERR("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);
275c2c66affSColin Finck }
276c2c66affSColin Finck else
277c2c66affSColin Finck {
278c2c66affSColin Finck ERR("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);
279c2c66affSColin Finck }
280c2c66affSColin Finck }
281c2c66affSColin Finck #endif
282c2c66affSColin Finck
283c2c66affSColin Finck return hRet;
284c2c66affSColin Finck }
285c2c66affSColin Finck
286*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
AddContextMenus(IN HMENU hmenu,IN UINT indexMenu,IN UINT idCmdFirst,IN UINT idCmdLast,IN UINT uFlags,OUT IContextMenu ** ppcm)287*853b8ebdSKatayama Hirofumi MZ AddContextMenus(
288c2c66affSColin Finck IN HMENU hmenu,
289c2c66affSColin Finck IN UINT indexMenu,
290c2c66affSColin Finck IN UINT idCmdFirst,
291c2c66affSColin Finck IN UINT idCmdLast,
292c2c66affSColin Finck IN UINT uFlags,
293*853b8ebdSKatayama Hirofumi MZ OUT IContextMenu **ppcm) override
294c2c66affSColin Finck {
295c2c66affSColin Finck HRESULT hRet;
296c2c66affSColin Finck
297c2c66affSColin Finck if (m_ContextMenu == NULL)
298c2c66affSColin Finck {
299c2c66affSColin Finck /* Cache the context menu so we don't need to CoCreateInstance all the time... */
300c2c66affSColin Finck hRet = _CBandSiteMenu_CreateInstance(IID_PPV_ARG(IContextMenu, &m_ContextMenu));
301c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet))
302c2c66affSColin Finck return hRet;
303c2c66affSColin Finck
304c2c66affSColin Finck hRet = IUnknown_SetOwner(m_ContextMenu, (IBandSite*)this);
305c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet))
306c2c66affSColin Finck return hRet;
307c2c66affSColin Finck }
308c2c66affSColin Finck
309c2c66affSColin Finck if (ppcm != NULL)
310c2c66affSColin Finck {
311c2c66affSColin Finck *ppcm = m_ContextMenu;
312cd2d2841SMark Jansen (*ppcm)->AddRef();
313c2c66affSColin Finck }
314c2c66affSColin Finck
315c2c66affSColin Finck /* Add the menu items */
316c2c66affSColin Finck hRet = m_ContextMenu->QueryContextMenu(hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
317c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet))
318c2c66affSColin Finck return hRet;
319c2c66affSColin Finck
320c2c66affSColin Finck return S_OK;
321c2c66affSColin Finck }
322c2c66affSColin Finck
323*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
Lock(IN BOOL bLock)324*853b8ebdSKatayama Hirofumi MZ Lock(IN BOOL bLock) override
325c2c66affSColin Finck {
326c2c66affSColin Finck BOOL bPrevLocked = Locked;
327c2c66affSColin Finck BANDSITEINFO bsi;
328c2c66affSColin Finck HRESULT hRet;
329c2c66affSColin Finck
330c2c66affSColin Finck ASSERT(m_BandSite != NULL);
331c2c66affSColin Finck
332c2c66affSColin Finck if (bPrevLocked != bLock)
333c2c66affSColin Finck {
334c2c66affSColin Finck Locked = bLock;
335c2c66affSColin Finck
336c2c66affSColin Finck bsi.dwMask = BSIM_STYLE;
337c2c66affSColin Finck bsi.dwStyle = (Locked ? BSIS_LOCKED | BSIS_NOGRIPPER : BSIS_AUTOGRIPPER);
338c2c66affSColin Finck
339c2c66affSColin Finck hRet = m_BandSite->SetBandSiteInfo(&bsi);
340c2c66affSColin Finck if (SUCCEEDED(hRet))
341c2c66affSColin Finck {
342c2c66affSColin Finck hRet = Update();
343c2c66affSColin Finck }
344c2c66affSColin Finck
345c2c66affSColin Finck return hRet;
346c2c66affSColin Finck }
347c2c66affSColin Finck
348c2c66affSColin Finck return S_FALSE;
349c2c66affSColin Finck }
350c2c66affSColin Finck
351c2c66affSColin Finck /*******************************************************************/
352c2c66affSColin Finck
353*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
AddBand(IN IUnknown * punk)354*853b8ebdSKatayama Hirofumi MZ AddBand(IN IUnknown *punk) override
355c2c66affSColin Finck {
356c2c66affSColin Finck /* Send the DBID_DELAYINIT command to initialize the band to be added */
357c2c66affSColin Finck /* FIXME: Should be delayed */
358c2c66affSColin Finck IUnknown_Exec(punk, IID_IDeskBand, DBID_DELAYINIT, 0, NULL, NULL);
359c2c66affSColin Finck
36071e66c69SGiannis Adamopoulos HRESULT hr = m_BandSite->AddBand(punk);
36171e66c69SGiannis Adamopoulos if (FAILED_UNEXPECTEDLY(hr))
36271e66c69SGiannis Adamopoulos return hr;
36371e66c69SGiannis Adamopoulos
36471e66c69SGiannis Adamopoulos VARIANT vThemeName;
36571e66c69SGiannis Adamopoulos V_VT(&vThemeName) = VT_BSTR;
36671e66c69SGiannis Adamopoulos V_BSTR(&vThemeName) = SysAllocString(L"TaskBar");
36771e66c69SGiannis Adamopoulos IUnknown_Exec(punk,
36871e66c69SGiannis Adamopoulos IID_IDeskBand,
36971e66c69SGiannis Adamopoulos DBID_SETWINDOWTHEME,
37071e66c69SGiannis Adamopoulos 0,
37171e66c69SGiannis Adamopoulos &vThemeName,
37271e66c69SGiannis Adamopoulos NULL);
37371e66c69SGiannis Adamopoulos
37471e66c69SGiannis Adamopoulos SysFreeString(V_BSTR(&vThemeName));
37571e66c69SGiannis Adamopoulos
37671e66c69SGiannis Adamopoulos return S_OK;
377c2c66affSColin Finck }
378c2c66affSColin Finck
379*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
EnumBands(IN UINT uBand,OUT DWORD * pdwBandID)380*853b8ebdSKatayama Hirofumi MZ EnumBands(
381c2c66affSColin Finck IN UINT uBand,
382*853b8ebdSKatayama Hirofumi MZ OUT DWORD *pdwBandID) override
383c2c66affSColin Finck {
384c2c66affSColin Finck return m_BandSite->EnumBands(uBand, pdwBandID);
385c2c66affSColin Finck }
386c2c66affSColin Finck
387*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
QueryBand(IN DWORD dwBandID,OUT IDeskBand ** ppstb,OUT DWORD * pdwState,OUT LPWSTR pszName,IN int cchName)388*853b8ebdSKatayama Hirofumi MZ QueryBand(
389c2c66affSColin Finck IN DWORD dwBandID,
390c2c66affSColin Finck OUT IDeskBand **ppstb,
391c2c66affSColin Finck OUT DWORD *pdwState,
392c2c66affSColin Finck OUT LPWSTR pszName,
393*853b8ebdSKatayama Hirofumi MZ IN int cchName) override
394c2c66affSColin Finck {
395c2c66affSColin Finck HRESULT hRet;
396c2c66affSColin Finck IDeskBand *pstb = NULL;
397c2c66affSColin Finck
398c2c66affSColin Finck hRet = m_BandSite->QueryBand(
399c2c66affSColin Finck dwBandID,
400c2c66affSColin Finck &pstb,
401c2c66affSColin Finck pdwState,
402c2c66affSColin Finck pszName,
403c2c66affSColin Finck cchName);
404c2c66affSColin Finck
405c2c66affSColin Finck if (SUCCEEDED(hRet))
406c2c66affSColin Finck {
407c2c66affSColin Finck hRet = IsSameObject(pstb, m_TaskBand);
408c2c66affSColin Finck if (hRet == S_OK)
409c2c66affSColin Finck {
410c2c66affSColin Finck /* Add the BSSF_UNDELETEABLE flag to pdwState because the task bar band shouldn't be deletable */
411c2c66affSColin Finck if (pdwState != NULL)
412c2c66affSColin Finck *pdwState |= BSSF_UNDELETEABLE;
413c2c66affSColin Finck }
414c2c66affSColin Finck else if (!SUCCEEDED(hRet))
415c2c66affSColin Finck {
416c2c66affSColin Finck pstb->Release();
417c2c66affSColin Finck pstb = NULL;
418c2c66affSColin Finck }
419c2c66affSColin Finck
420c2c66affSColin Finck if (ppstb != NULL)
421c2c66affSColin Finck *ppstb = pstb;
422c2c66affSColin Finck }
423c2c66affSColin Finck else if (ppstb != NULL)
424c2c66affSColin Finck *ppstb = NULL;
425c2c66affSColin Finck
426c2c66affSColin Finck return hRet;
427c2c66affSColin Finck }
428c2c66affSColin Finck
429*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
SetBandState(IN DWORD dwBandID,IN DWORD dwMask,IN DWORD dwState)430*853b8ebdSKatayama Hirofumi MZ SetBandState(
431c2c66affSColin Finck IN DWORD dwBandID,
432c2c66affSColin Finck IN DWORD dwMask,
433*853b8ebdSKatayama Hirofumi MZ IN DWORD dwState) override
434c2c66affSColin Finck {
435c2c66affSColin Finck return m_BandSite->SetBandState(dwBandID, dwMask, dwState);
436c2c66affSColin Finck }
437c2c66affSColin Finck
438*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
RemoveBand(IN DWORD dwBandID)439*853b8ebdSKatayama Hirofumi MZ RemoveBand(IN DWORD dwBandID) override
440c2c66affSColin Finck {
441c2c66affSColin Finck return m_BandSite->RemoveBand(dwBandID);
442c2c66affSColin Finck }
443c2c66affSColin Finck
444*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
GetBandObject(IN DWORD dwBandID,IN REFIID riid,OUT VOID ** ppv)445*853b8ebdSKatayama Hirofumi MZ GetBandObject(
446c2c66affSColin Finck IN DWORD dwBandID,
447c2c66affSColin Finck IN REFIID riid,
448*853b8ebdSKatayama Hirofumi MZ OUT VOID **ppv) override
449c2c66affSColin Finck {
450c2c66affSColin Finck return m_BandSite->GetBandObject(dwBandID, riid, ppv);
451c2c66affSColin Finck }
452c2c66affSColin Finck
453*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
SetBandSiteInfo(IN const BANDSITEINFO * pbsinfo)454*853b8ebdSKatayama Hirofumi MZ SetBandSiteInfo(IN const BANDSITEINFO *pbsinfo) override
455c2c66affSColin Finck {
456c2c66affSColin Finck return m_BandSite->SetBandSiteInfo(pbsinfo);
457c2c66affSColin Finck }
458c2c66affSColin Finck
459*853b8ebdSKatayama Hirofumi MZ STDMETHODIMP
GetBandSiteInfo(IN OUT BANDSITEINFO * pbsinfo)460*853b8ebdSKatayama Hirofumi MZ GetBandSiteInfo(IN OUT BANDSITEINFO *pbsinfo) override
461c2c66affSColin Finck {
462c2c66affSColin Finck return m_BandSite->GetBandSiteInfo(pbsinfo);
463c2c66affSColin Finck }
464c2c66affSColin Finck
HasTaskBand()465c2c66affSColin Finck virtual BOOL HasTaskBand()
466c2c66affSColin Finck {
467c2c66affSColin Finck CComPtr<IPersist> pBand;
468c2c66affSColin Finck CLSID BandCLSID;
469c2c66affSColin Finck DWORD dwBandID;
470c2c66affSColin Finck UINT uBand = 0;
471c2c66affSColin Finck
472c2c66affSColin Finck /* Enumerate all bands */
473c2c66affSColin Finck while (SUCCEEDED(m_BandSite->EnumBands(uBand, &dwBandID)))
474c2c66affSColin Finck {
475ea34ecc9SCarl J. Bialorucki if (dwBandID && SUCCEEDED(m_BandSite->GetBandObject(dwBandID, IID_PPV_ARG(IPersist, &pBand))))
476c2c66affSColin Finck {
477c2c66affSColin Finck if (SUCCEEDED(pBand->GetClassID(&BandCLSID)))
478c2c66affSColin Finck {
479c2c66affSColin Finck if (IsEqualGUID(BandCLSID, CLSID_ITaskBand))
480c2c66affSColin Finck {
481c2c66affSColin Finck return TRUE;
482c2c66affSColin Finck }
483c2c66affSColin Finck }
484c2c66affSColin Finck }
485c2c66affSColin Finck uBand++;
486c2c66affSColin Finck }
487c2c66affSColin Finck
488c2c66affSColin Finck return FALSE;
489c2c66affSColin Finck }
490c2c66affSColin Finck
Update()491c2c66affSColin Finck virtual HRESULT Update()
492c2c66affSColin Finck {
493c2c66affSColin Finck return IUnknown_Exec(m_Inner,
494c2c66affSColin Finck IID_IDeskBand,
495c2c66affSColin Finck DBID_BANDINFOCHANGED,
496c2c66affSColin Finck 0,
497c2c66affSColin Finck NULL,
498c2c66affSColin Finck NULL);
499c2c66affSColin Finck }
500c2c66affSColin Finck
BroadcastOleCommandExec(REFGUID pguidCmdGroup,DWORD nCmdID,DWORD nCmdExecOpt,VARIANTARG * pvaIn,VARIANTARG * pvaOut)501c2c66affSColin Finck virtual VOID BroadcastOleCommandExec(REFGUID pguidCmdGroup,
502c2c66affSColin Finck DWORD nCmdID,
503c2c66affSColin Finck DWORD nCmdExecOpt,
504c2c66affSColin Finck VARIANTARG *pvaIn,
505c2c66affSColin Finck VARIANTARG *pvaOut)
506c2c66affSColin Finck {
507c2c66affSColin Finck IOleCommandTarget *pOct;
508c2c66affSColin Finck DWORD dwBandID;
509c2c66affSColin Finck UINT uBand = 0;
510c2c66affSColin Finck
511c2c66affSColin Finck /* Enumerate all bands */
512c2c66affSColin Finck while (SUCCEEDED(m_BandSite->EnumBands(uBand, &dwBandID)))
513c2c66affSColin Finck {
514c2c66affSColin Finck if (SUCCEEDED(m_BandSite->GetBandObject(dwBandID, IID_PPV_ARG(IOleCommandTarget, &pOct))))
515c2c66affSColin Finck {
516c2c66affSColin Finck /* Execute the command */
517c2c66affSColin Finck pOct->Exec(
518c2c66affSColin Finck &pguidCmdGroup,
519c2c66affSColin Finck nCmdID,
520c2c66affSColin Finck nCmdExecOpt,
521c2c66affSColin Finck pvaIn,
522c2c66affSColin Finck pvaOut);
523c2c66affSColin Finck
524c2c66affSColin Finck pOct->Release();
525c2c66affSColin Finck }
526c2c66affSColin Finck
527c2c66affSColin Finck uBand++;
528c2c66affSColin Finck }
529c2c66affSColin Finck }
530c2c66affSColin Finck
FinishInit()531c2c66affSColin Finck virtual HRESULT FinishInit()
532c2c66affSColin Finck {
533c2c66affSColin Finck /* Broadcast the DBID_FINISHINIT command */
534c2c66affSColin Finck BroadcastOleCommandExec(IID_IDeskBand, DBID_FINISHINIT, 0, NULL, NULL);
535c2c66affSColin Finck
536c2c66affSColin Finck return S_OK;
537c2c66affSColin Finck }
538c2c66affSColin Finck
Show(IN BOOL bShow)539c2c66affSColin Finck virtual HRESULT Show(IN BOOL bShow)
540c2c66affSColin Finck {
541c2c66affSColin Finck CComPtr<IDeskBarClient> pDbc;
542c2c66affSColin Finck HRESULT hRet;
543c2c66affSColin Finck
544c2c66affSColin Finck hRet = m_BandSite->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pDbc));
545c2c66affSColin Finck if (SUCCEEDED(hRet))
546c2c66affSColin Finck {
547c2c66affSColin Finck hRet = pDbc->UIActivateDBC(bShow ? DBC_SHOW : DBC_HIDE);
548c2c66affSColin Finck }
549c2c66affSColin Finck
550c2c66affSColin Finck return hRet;
551c2c66affSColin Finck }
552c2c66affSColin Finck
LoadFromStream(IN OUT IStream * pStm)553c2c66affSColin Finck virtual HRESULT LoadFromStream(IN OUT IStream *pStm)
554c2c66affSColin Finck {
555c2c66affSColin Finck CComPtr<IPersistStream> pPStm;
556c2c66affSColin Finck HRESULT hRet;
557c2c66affSColin Finck
558c2c66affSColin Finck ASSERT(m_BandSite != NULL);
559c2c66affSColin Finck
560c2c66affSColin Finck /* We implement the undocumented COM interface IBandSiteStreamCallback
561c2c66affSColin Finck that the shell will query so that we can intercept and custom-load
562c2c66affSColin Finck the task band when it finds the task band's CLSID (which is internal).
563c2c66affSColin Finck This way we can prevent the shell from attempting to CoCreateInstance
564c2c66affSColin Finck the (internal) task band, resulting in a failure... */
565c2c66affSColin Finck hRet = m_BandSite->QueryInterface(IID_PPV_ARG(IPersistStream, &pPStm));
566c2c66affSColin Finck if (SUCCEEDED(hRet))
567c2c66affSColin Finck {
568c2c66affSColin Finck hRet = pPStm->Load(pStm);
569c2c66affSColin Finck TRACE("->Load() returned 0x%x\n", hRet);
570c2c66affSColin Finck }
571c2c66affSColin Finck
572c2c66affSColin Finck return hRet;
573c2c66affSColin Finck }
574c2c66affSColin Finck
GetUserBandsStream(IN DWORD grfMode)575c2c66affSColin Finck virtual IStream * GetUserBandsStream(IN DWORD grfMode)
576c2c66affSColin Finck {
577c2c66affSColin Finck HKEY hkStreams;
578c2c66affSColin Finck IStream *Stream = NULL;
579c2c66affSColin Finck
580c2c66affSColin Finck if (RegCreateKeyW(hkExplorer,
581c2c66affSColin Finck L"Streams",
582c2c66affSColin Finck &hkStreams) == ERROR_SUCCESS)
583c2c66affSColin Finck {
584c2c66affSColin Finck Stream = SHOpenRegStreamW(hkStreams,
585c2c66affSColin Finck L"Desktop",
586c2c66affSColin Finck L"TaskbarWinXP",
587c2c66affSColin Finck grfMode);
588c2c66affSColin Finck
589c2c66affSColin Finck RegCloseKey(hkStreams);
590c2c66affSColin Finck }
591c2c66affSColin Finck
592c2c66affSColin Finck return Stream;
593c2c66affSColin Finck }
594c2c66affSColin Finck
GetDefaultBandsStream(IN DWORD grfMode)595c2c66affSColin Finck virtual IStream * GetDefaultBandsStream(IN DWORD grfMode)
596c2c66affSColin Finck {
597c2c66affSColin Finck HKEY hkStreams;
598c2c66affSColin Finck IStream *Stream = NULL;
599c2c66affSColin Finck
600c2c66affSColin Finck if (RegCreateKeyW(HKEY_LOCAL_MACHINE,
601c2c66affSColin Finck L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Streams",
602c2c66affSColin Finck &hkStreams) == ERROR_SUCCESS)
603c2c66affSColin Finck {
604c2c66affSColin Finck Stream = SHOpenRegStreamW(hkStreams,
605c2c66affSColin Finck L"Desktop",
606c2c66affSColin Finck L"Default Taskbar",
607c2c66affSColin Finck grfMode);
608c2c66affSColin Finck
609c2c66affSColin Finck RegCloseKey(hkStreams);
610c2c66affSColin Finck }
611c2c66affSColin Finck
612c2c66affSColin Finck return Stream;
613c2c66affSColin Finck }
614c2c66affSColin Finck
Load()615c2c66affSColin Finck virtual HRESULT Load()
616c2c66affSColin Finck {
617c2c66affSColin Finck IStream *pStm;
618c2c66affSColin Finck HRESULT hRet;
619c2c66affSColin Finck
620c2c66affSColin Finck /* Try to load the user's settings */
621c2c66affSColin Finck pStm = GetUserBandsStream(STGM_READ);
622c2c66affSColin Finck if (pStm != NULL)
623c2c66affSColin Finck {
624c2c66affSColin Finck hRet = LoadFromStream(pStm);
625c2c66affSColin Finck
626c2c66affSColin Finck TRACE("Loaded user bands settings: 0x%x\n", hRet);
627c2c66affSColin Finck pStm->Release();
628c2c66affSColin Finck }
629c2c66affSColin Finck else
630c2c66affSColin Finck hRet = E_FAIL;
631c2c66affSColin Finck
632c2c66affSColin Finck /* If the user's settings couldn't be loaded, try with
633c2c66affSColin Finck default settings (ie. when the user logs in for the
634c2c66affSColin Finck first time! */
635c2c66affSColin Finck if (!SUCCEEDED(hRet))
636c2c66affSColin Finck {
637c2c66affSColin Finck pStm = GetDefaultBandsStream(STGM_READ);
638c2c66affSColin Finck if (pStm != NULL)
639c2c66affSColin Finck {
640c2c66affSColin Finck hRet = LoadFromStream(pStm);
641c2c66affSColin Finck
642c2c66affSColin Finck TRACE("Loaded default user bands settings: 0x%x\n", hRet);
643c2c66affSColin Finck pStm->Release();
644c2c66affSColin Finck }
645c2c66affSColin Finck else
646c2c66affSColin Finck hRet = E_FAIL;
647c2c66affSColin Finck }
648c2c66affSColin Finck
649c2c66affSColin Finck return hRet;
650c2c66affSColin Finck }
651c2c66affSColin Finck
_Init(IN ITrayWindow * tray,IN IDeskBand * pTaskBand)652c2c66affSColin Finck HRESULT _Init(IN ITrayWindow *tray, IN IDeskBand* pTaskBand)
653c2c66affSColin Finck {
654c2c66affSColin Finck CComPtr<IDeskBarClient> pDbc;
655c2c66affSColin Finck CComPtr<IDeskBand> pDb;
656c2c66affSColin Finck CComPtr<IOleWindow> pOw;
657c2c66affSColin Finck HRESULT hRet;
658c2c66affSColin Finck
659c2c66affSColin Finck m_Tray = tray;
660c2c66affSColin Finck m_TaskBand = pTaskBand;
661c2c66affSColin Finck
662c2c66affSColin Finck /* Create the RebarBandSite */
663c2c66affSColin Finck hRet = _CBandSite_CreateInstance(static_cast<IBandSite*>(this), IID_PPV_ARG(IUnknown, &m_Inner));
664c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet))
665c2c66affSColin Finck return hRet;
666c2c66affSColin Finck
667c2c66affSColin Finck hRet = m_Inner->QueryInterface(IID_PPV_ARG(IBandSite, &m_BandSite));
668c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet))
669c2c66affSColin Finck return hRet;
670c2c66affSColin Finck
671c2c66affSColin Finck hRet = m_Inner->QueryInterface(IID_PPV_ARG(IWinEventHandler, &m_WindowEventHandler));
672c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet))
673c2c66affSColin Finck return hRet;
674c2c66affSColin Finck
675c2c66affSColin Finck hRet = m_Inner->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pDbc));
676c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet))
677c2c66affSColin Finck return hRet;
678c2c66affSColin Finck
679c2c66affSColin Finck
680c2c66affSColin Finck
681c2c66affSColin Finck
682c2c66affSColin Finck /* Crete the rebar in the tray */
683c2c66affSColin Finck hRet = pDbc->SetDeskBarSite(tray);
684c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet))
685c2c66affSColin Finck return hRet;
686c2c66affSColin Finck
687c2c66affSColin Finck hRet = pDbc->GetWindow(&m_Rebar);
688c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet))
689c2c66affSColin Finck return hRet;
690c2c66affSColin Finck
691c2c66affSColin Finck SetWindowStyle(m_Rebar, RBS_BANDBORDERS, 0);
692c2c66affSColin Finck
693c2c66affSColin Finck /* Set the Desk Bar mode to the current one */
694c2c66affSColin Finck DWORD dwMode = 0;
695c2c66affSColin Finck /* FIXME: We need to set the mode (and update) whenever the user docks
696c2c66affSColin Finck the tray window to another monitor edge! */
697c2c66affSColin Finck if (!m_Tray->IsHorizontal())
698c2c66affSColin Finck dwMode = DBIF_VIEWMODE_VERTICAL;
699c2c66affSColin Finck
700c2c66affSColin Finck hRet = pDbc->SetModeDBC(dwMode);
701c2c66affSColin Finck
702c2c66affSColin Finck /* Load the saved state of the task band site */
703c2c66affSColin Finck /* FIXME: We should delay loading shell extensions, also see DBID_DELAYINIT */
704c2c66affSColin Finck Load();
705c2c66affSColin Finck
706c2c66affSColin Finck /* Add the task bar band if it hasn't been added while loading */
707c2c66affSColin Finck if (!HasTaskBand())
708c2c66affSColin Finck {
709c2c66affSColin Finck hRet = m_BandSite->AddBand(m_TaskBand);
710c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet))
711c2c66affSColin Finck return hRet;
712c2c66affSColin Finck }
713c2c66affSColin Finck
714c2c66affSColin Finck /* Should we send this after showing it? */
715c2c66affSColin Finck Update();
716c2c66affSColin Finck
717c2c66affSColin Finck /* FIXME: When should we send this? Does anyone care anyway? */
718c2c66affSColin Finck FinishInit();
719c2c66affSColin Finck
720c2c66affSColin Finck /* Activate the band site */
721c2c66affSColin Finck Show(TRUE);
722c2c66affSColin Finck
723c2c66affSColin Finck return S_OK;
724c2c66affSColin Finck }
725c2c66affSColin Finck };
726c2c66affSColin Finck /*******************************************************************/
727c2c66affSColin Finck
CTrayBandSite_CreateInstance(IN ITrayWindow * tray,IN IDeskBand * pTaskBand,OUT ITrayBandSite ** pBandSite)728c2c66affSColin Finck HRESULT CTrayBandSite_CreateInstance(IN ITrayWindow *tray, IN IDeskBand* pTaskBand, OUT ITrayBandSite** pBandSite)
729c2c66affSColin Finck {
730c2c66affSColin Finck HRESULT hr;
731c2c66affSColin Finck
732c2c66affSColin Finck CTrayBandSite * tb = new CTrayBandSite();
733c2c66affSColin Finck if (!tb)
734c2c66affSColin Finck return E_FAIL;
735c2c66affSColin Finck
736c2c66affSColin Finck tb->AddRef();
737c2c66affSColin Finck
738c2c66affSColin Finck hr = tb->_Init(tray, pTaskBand);
739c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
740c2c66affSColin Finck {
741c2c66affSColin Finck tb->Release();
742c2c66affSColin Finck return hr;
743c2c66affSColin Finck }
744c2c66affSColin Finck
745c2c66affSColin Finck *pBandSite = tb;
746c2c66affSColin Finck
747c2c66affSColin Finck return S_OK;
748c2c66affSColin Finck }
749