f23e79d53f41e3248dc717413235cb92e7eabc72
[reactos.git] / reactos / dll / win32 / browseui / shellbars / CBandSite.cpp
1 /*
2 * Rebar band site
3 *
4 * Copyright 2007 Hervé Poussineau
5 * Copyright 2009 Andrew Hill
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "shellbars.h"
23
24 #ifndef ASSERT
25 #define ASSERT(cond) \
26 if (!(cond)) \
27 ERR ("ASSERTION %s AT %s:%d FAILED!\n", #cond, __FILE__, __LINE__)
28 #endif
29
30 CBandSiteBase::CBandSiteBase()
31 {
32 fBandsCount = 0;
33 fBandsAllocated = 0;
34 fBands = NULL;
35 fRebarWindow = NULL;
36 }
37
38 UINT CBandSiteBase::GetBandID(struct BandObject *Band)
39 {
40 return (UINT)(Band - fBands);
41 }
42
43 struct CBandSiteBase::BandObject *CBandSiteBase::GetBandByID(DWORD dwBandID)
44 {
45 if ((LONG)dwBandID >= fBandsAllocated)
46 return NULL;
47
48 if (fBands[dwBandID].DeskBand == NULL)
49 return NULL;
50
51 return &fBands[dwBandID];
52 }
53
54 void CBandSiteBase::FreeBand(struct BandObject *Band)
55 {
56 ATLASSERT(Band->DeskBand != NULL);
57 ATLASSERT(Band->OleWindow != NULL);
58 ATLASSERT(Band->WndEvtHandler != NULL);
59 Band->DeskBand->Release();
60 Band->OleWindow->Release();
61 Band->WndEvtHandler->Release();
62 memset(Band, 0, sizeof(*Band));
63 fBandsCount--;
64 }
65
66 DWORD CBandSiteBase::GetBandSiteViewMode()
67 {
68 DWORD dwStyle;
69
70 /* FIXME: What about DBIF_VIEWMODE_FLOATING and DBIF_VIEWMODE_TRANSPARENT? */
71 dwStyle = GetWindowLongPtr(fRebarWindow, GWL_STYLE);
72
73 if (dwStyle & CCS_VERT)
74 return DBIF_VIEWMODE_VERTICAL;
75 else
76 return DBIF_VIEWMODE_NORMAL;
77 }
78
79 VOID CBandSiteBase::BuildRebarBandInfo(struct BandObject *Band, REBARBANDINFOW *prbi)
80 {
81 ZeroMemory(prbi, sizeof(*prbi));
82 prbi->cbSize = sizeof(*prbi);
83
84 prbi->fMask = RBBIM_ID;
85 prbi->wID = GetBandID(Band);
86
87 if (Band->dbi.dwMask & DBIM_MINSIZE)
88 {
89 prbi->fMask |= RBBIM_CHILDSIZE;
90 prbi->cxMinChild = Band->dbi.ptMinSize.x;
91 prbi->cyMinChild = Band->dbi.ptMinSize.y;
92 }
93
94 if (Band->dbi.dwMask & DBIM_MAXSIZE)
95 {
96 prbi->fMask |= RBBIM_CHILDSIZE;
97 prbi->cyMaxChild = Band->dbi.ptMaxSize.y;
98 }
99
100 if ((Band->dbi.dwMask & (DBIM_INTEGRAL | DBIM_MODEFLAGS)) == (DBIM_INTEGRAL | DBIM_MODEFLAGS) &&
101 (Band->dbi.dwModeFlags & DBIMF_VARIABLEHEIGHT))
102 {
103 prbi->fMask |= RBBIM_CHILDSIZE;
104 prbi->cyIntegral = Band->dbi.ptIntegral.y;
105 }
106
107 if (Band->dbi.dwMask & DBIM_ACTUAL)
108 {
109 prbi->fMask |= RBBIM_IDEALSIZE | RBBIM_SIZE | RBBIM_CHILDSIZE;
110 prbi->cxIdeal = Band->dbi.ptActual.x;
111 prbi->cx = Band->dbi.ptActual.x;
112 prbi->cyChild = Band->dbi.ptActual.y;
113 }
114
115 if (Band->dbi.dwMask & DBIM_TITLE)
116 {
117 prbi->fMask |= RBBIM_TEXT;
118 prbi->lpText = Band->dbi.wszTitle;
119 prbi->cch = wcslen(Band->dbi.wszTitle);
120 }
121
122 if (Band->dbi.dwMask & DBIM_MODEFLAGS)
123 {
124 prbi->fMask |= RBBIM_STYLE;
125
126 if (Band->dbi.dwModeFlags & DBIMF_FIXED)
127 prbi->fStyle |= RBBS_FIXEDSIZE | RBBS_NOGRIPPER;
128 if (Band->dbi.dwModeFlags & DBIMF_FIXEDBMP)
129 prbi->fStyle |= RBBS_FIXEDBMP;
130 if (Band->dbi.dwModeFlags & DBIMF_VARIABLEHEIGHT)
131 prbi->fStyle |= RBBS_VARIABLEHEIGHT;
132 if (Band->dbi.dwModeFlags & DBIMF_DEBOSSED)
133 prbi->fStyle |= RBBS_CHILDEDGE;
134 if (Band->dbi.dwModeFlags & DBIMF_USECHEVRON)
135 prbi->fStyle |= RBBS_USECHEVRON;
136 if (Band->dbi.dwModeFlags & DBIMF_BREAK)
137 prbi->fStyle |= RBBS_BREAK;
138 if (Band->dbi.dwModeFlags & DBIMF_TOPALIGN)
139 prbi->fStyle |= RBBS_TOPALIGN;
140 if (Band->dbi.dwModeFlags & DBIMF_NOGRIPPER)
141 prbi->fStyle |= RBBS_NOGRIPPER;
142 if (Band->dbi.dwModeFlags & DBIMF_ALWAYSGRIPPER)
143 prbi->fStyle |= RBBS_GRIPPERALWAYS;
144 }
145
146 if ((Band->dbi.dwMask & (DBIM_BKCOLOR | DBIM_MODEFLAGS)) == (DBIM_BKCOLOR | DBIM_MODEFLAGS) &&
147 (Band->dbi.dwModeFlags & DBIMF_BKCOLOR))
148 {
149 prbi->fMask |= RBBIM_COLORS;
150 prbi->clrFore = (COLORREF)(COLOR_WINDOWTEXT + 1);
151 prbi->clrBack = Band->dbi.crBkgnd;
152 }
153 }
154
155 HRESULT CBandSiteBase::UpdateSingleBand(struct BandObject *Band)
156 {
157 REBARBANDINFOW rbi;
158 DWORD dwViewMode;
159 UINT uBand;
160 HRESULT hRet;
161
162 ZeroMemory(&Band->dbi, sizeof(Band->dbi));
163 Band->dbi.dwMask = DBIM_MINSIZE | DBIM_MAXSIZE | DBIM_INTEGRAL |
164 DBIM_ACTUAL | DBIM_TITLE | DBIM_MODEFLAGS | DBIM_BKCOLOR;
165
166 dwViewMode = GetBandSiteViewMode();
167
168 hRet = Band->DeskBand->GetBandInfo((DWORD)GetBandID(Band), dwViewMode, &Band->dbi);
169 if (SUCCEEDED(hRet))
170 {
171 BuildRebarBandInfo(Band, &rbi);
172 if (SUCCEEDED(Band->OleWindow->GetWindow(&rbi.hwndChild)) &&
173 rbi.hwndChild != NULL)
174 {
175 rbi.fMask |= RBBIM_CHILD;
176 WARN ("ReBar band uses child window 0x%p\n", rbi.hwndChild);
177 }
178
179 uBand = (UINT)SendMessageW(fRebarWindow, RB_IDTOINDEX, (WPARAM)rbi.wID, 0);
180 if (uBand != (UINT)-1)
181 {
182 if (!SendMessageW(fRebarWindow, RB_SETBANDINFOW, (WPARAM)uBand, reinterpret_cast<LPARAM>(&rbi)))
183 {
184 WARN("Failed to update the rebar band!\n");
185 }
186 }
187 else
188 WARN("Failed to map rebar band id to index!\n");
189
190 }
191
192 return hRet;
193 }
194
195 HRESULT CBandSiteBase::UpdateAllBands()
196 {
197 LONG i;
198 HRESULT hRet;
199
200 for (i = 0; i < fBandsAllocated; i++)
201 {
202 if (fBands[i].DeskBand != NULL)
203 {
204 hRet = UpdateSingleBand(&fBands[i]);
205 if (FAILED_UNEXPECTEDLY(hRet))
206 return hRet;
207 }
208 }
209
210 return S_OK;
211 }
212
213 HRESULT CBandSiteBase::UpdateBand(DWORD dwBandID)
214 {
215 struct BandObject *Band;
216
217 Band = GetBandByID(dwBandID);
218 if (Band == NULL)
219 return E_FAIL;
220
221 return UpdateSingleBand(Band);
222 }
223
224 struct CBandSiteBase::BandObject *CBandSiteBase::GetBandFromHwnd(HWND hwnd)
225 {
226 HRESULT hRet;
227 HWND hWndBand;
228 LONG i;
229
230 for (i = 0; i < fBandsAllocated; i++)
231 {
232 if (fBands[i].DeskBand != NULL)
233 {
234 ASSERT(fBands[i].OleWindow);
235
236 hWndBand = NULL;
237 hRet = fBands[i].OleWindow->GetWindow(&hWndBand);
238 if (SUCCEEDED(hRet) && hWndBand == hwnd)
239 return &fBands[i];
240 }
241 }
242
243 return NULL;
244 }
245
246 CBandSiteBase::~CBandSiteBase()
247 {
248
249 TRACE("destroying %p\n", this);
250
251 if (fRebarWindow != NULL)
252 {
253 DestroyWindow(fRebarWindow);
254 fRebarWindow = NULL;
255 }
256
257 if (fBands != NULL)
258 {
259 for (INT i = 0; i < fBandsAllocated; i++)
260 {
261 if (fBands[i].DeskBand != NULL)
262 FreeBand(&fBands[i]);
263 }
264 CoTaskMemFree(fBands);
265 fBands = NULL;
266 }
267 }
268
269 HRESULT STDMETHODCALLTYPE CBandSiteBase::AddBand(IUnknown *punk)
270 {
271 LONG NewAllocated;
272 struct BandObject *NewBand = NULL;
273 CComPtr<IDeskBand> DeskBand;
274 CComPtr<IObjectWithSite> ObjWithSite;
275 CComPtr<IOleWindow> OleWindow;
276 CComPtr<IWinEventHandler> WndEvtHandler;
277 REBARBANDINFOW rbi;
278 HRESULT hRet;
279 UINT uBand;
280
281 TRACE("(%p, %p)\n", this, punk);
282
283 if (punk == NULL || fRebarWindow == NULL)
284 return E_FAIL;
285
286 hRet = punk->QueryInterface(IID_PPV_ARG(IDeskBand, &DeskBand));
287 if (!SUCCEEDED(hRet) || DeskBand == NULL)
288 goto Cleanup;
289 hRet = punk->QueryInterface(IID_PPV_ARG(IObjectWithSite, &ObjWithSite));
290 if (!SUCCEEDED(hRet) || ObjWithSite == NULL)
291 goto Cleanup;
292 hRet = punk->QueryInterface(IID_PPV_ARG(IOleWindow, &OleWindow));
293 if (!SUCCEEDED(hRet) || OleWindow == NULL)
294 goto Cleanup;
295 hRet = punk->QueryInterface(IID_PPV_ARG(IWinEventHandler, &WndEvtHandler));
296 if (!SUCCEEDED(hRet) || WndEvtHandler == NULL)
297 goto Cleanup;
298
299 hRet = S_OK;
300 if (fBandsAllocated > fBandsCount)
301 {
302 /* Search for a free band object */
303 for (INT i = 0; i < fBandsAllocated; i++)
304 {
305 if (fBands[i].DeskBand == NULL)
306 {
307 NewBand = &fBands[i];
308 break;
309 }
310 }
311 }
312 else if (fBandsAllocated > 0)
313 {
314 ASSERT (fBands != NULL);
315
316 /* Reallocate the band object array */
317 NewAllocated = fBandsAllocated + 8;
318 if (NewAllocated > 0xFFFF)
319 NewAllocated = 0xFFFF;
320 if (NewAllocated == fBandsAllocated)
321 {
322 hRet = E_OUTOFMEMORY;
323 goto Cleanup;
324 }
325
326
327 NewBand = static_cast<struct BandObject *>(CoTaskMemAlloc(NewAllocated * sizeof(struct BandObject)));
328 if (NewBand == NULL)
329 {
330 hRet = E_OUTOFMEMORY;
331 goto Cleanup;
332 }
333
334 /* Copy the old array */
335 memcpy(NewBand, fBands, fBandsAllocated * sizeof(struct BandObject));
336
337 /* Initialize the added bands */
338 memset(&NewBand[fBandsAllocated], 0, (NewAllocated - fBandsAllocated) * sizeof(struct BandObject));
339
340 fBandsAllocated = NewAllocated;
341 CoTaskMemFree(fBands);
342 fBands = NewBand;
343 }
344 else
345 {
346 ASSERT(fBands == NULL);
347 ASSERT(fBandsAllocated == 0);
348 ASSERT(fBandsCount == 0);
349
350 /* Allocate new array */
351 fBands = static_cast<struct BandObject *>(CoTaskMemAlloc(8 * sizeof(struct BandObject)));
352 if (fBands == NULL)
353 {
354 hRet = E_OUTOFMEMORY;
355 goto Cleanup;
356 }
357
358 /* Initialize the added bands */
359 memset(fBands, 0, 8 * sizeof(struct BandObject));
360
361 fBandsAllocated += 8;
362 NewBand = &fBands[0];
363 }
364
365 if (SUCCEEDED(hRet))
366 {
367 ASSERT(NewBand != NULL);
368
369 fBandsCount++;
370 NewBand->DeskBand = DeskBand.Detach();
371 NewBand->OleWindow = OleWindow.Detach();
372 NewBand->WndEvtHandler = WndEvtHandler.Detach();
373
374 /* Create the ReBar band */
375 hRet = ObjWithSite->SetSite(static_cast<IOleWindow *>(this));
376 if (SUCCEEDED(hRet))
377 {
378 uBand = 0xffffffff;
379 if (SUCCEEDED(UpdateSingleBand(NewBand)))
380 {
381 if (NewBand->dbi.dwMask & DBIM_MODEFLAGS)
382 {
383 if (NewBand->dbi.dwModeFlags & DBIMF_ADDTOFRONT)
384 uBand = 0;
385 }
386 }
387
388 BuildRebarBandInfo(NewBand, &rbi);
389
390 if (SUCCEEDED(NewBand->OleWindow->GetWindow(&rbi.hwndChild)) &&
391 rbi.hwndChild != NULL)
392 {
393 rbi.fMask |= RBBIM_CHILD;
394 WARN ("ReBar band uses child window 0x%p\n", rbi.hwndChild);
395 }
396
397 if (!SendMessageW(fRebarWindow, RB_INSERTBANDW, (WPARAM)uBand, reinterpret_cast<LPARAM>(&rbi)))
398 return E_FAIL;
399
400 hRet = (HRESULT)((USHORT)GetBandID(NewBand));
401 }
402 else
403 {
404 WARN("IBandSite::AddBand(): Call to IDeskBand::SetSite() failed: %x\n", hRet);
405
406 /* Remove the band from the ReBar control */
407 BuildRebarBandInfo(NewBand, &rbi);
408 uBand = (UINT)SendMessageW(fRebarWindow, RB_IDTOINDEX, (WPARAM)rbi.wID, 0);
409 if (uBand != (UINT)-1)
410 {
411 if (!SendMessageW(fRebarWindow, RB_DELETEBAND, (WPARAM)uBand, 0))
412 {
413 ERR("Failed to delete band!\n");
414 }
415 }
416 else
417 ERR("Failed to map band id to index!\n");
418
419 FreeBand(NewBand);
420
421 hRet = E_FAIL;
422 /* goto Cleanup; */
423 }
424 }
425 Cleanup:
426 return hRet;
427 }
428
429 HRESULT STDMETHODCALLTYPE CBandSiteBase::EnumBands(UINT uBand, DWORD *pdwBandID)
430 {
431 DWORD i;
432
433 TRACE("(%p, %u, %p)\n", this, uBand, pdwBandID);
434
435 if (uBand == 0xffffffff)
436 return (UINT)fBandsCount;
437
438 if (uBand >= (UINT)fBandsCount)
439 return E_FAIL;
440
441 for (i = 0; i < (DWORD)fBandsAllocated; i++)
442 {
443 if (fBands[i].DeskBand != NULL)
444 {
445 if (uBand == 0)
446 {
447 *pdwBandID = i;
448 return S_OK;
449 }
450
451 uBand--;
452 }
453 }
454
455 return E_FAIL;
456 }
457
458 HRESULT STDMETHODCALLTYPE CBandSiteBase::QueryBand(DWORD dwBandID, IDeskBand **ppstb,
459 DWORD *pdwState, LPWSTR pszName, int cchName)
460 {
461 struct BandObject *Band;
462
463 TRACE("(%p, %u, %p, %p, %p, %d)\n", this, dwBandID, ppstb, pdwState, pszName, cchName);
464
465 Band = GetBandByID(dwBandID);
466 if (Band == NULL)
467 return E_FAIL;
468
469 if (ppstb != NULL)
470 {
471 Band->DeskBand->AddRef();
472 *ppstb = Band->DeskBand;
473 }
474
475 if (pdwState != NULL)
476 {
477 FIXME("IBandSite::QueryBand() requests band state!\n");
478 *pdwState = 0;
479 }
480
481 if (pszName != NULL && cchName > 0)
482 {
483 FIXME("IBandSite::QueryBand() requests band name!\n");
484 pszName[0] = 0;
485 }
486 return S_OK;
487 }
488
489 HRESULT STDMETHODCALLTYPE CBandSiteBase::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState)
490 {
491 struct BandObject *Band;
492
493 TRACE("(%p, %u, %x, %x)\n", this, dwBandID, dwMask, dwState);
494
495 Band = GetBandByID(dwBandID);
496 if (Band == NULL)
497 return E_FAIL;
498
499 FIXME("Stub\n");
500 return E_NOTIMPL;
501 }
502
503 HRESULT STDMETHODCALLTYPE CBandSiteBase::RemoveBand(DWORD dwBandID)
504 {
505 struct BandObject *Band;
506 UINT uBand;
507
508 TRACE("(%p, %u)\n", this, dwBandID);
509
510 if (fRebarWindow == NULL)
511 return E_FAIL;
512
513 Band = GetBandByID(dwBandID);
514 if (Band == NULL)
515 return E_FAIL;
516
517 uBand = (UINT)SendMessageW(fRebarWindow, RB_IDTOINDEX, (WPARAM)GetBandID(Band), 0);
518 if (uBand != (UINT)-1)
519 {
520 if (!SendMessageW(fRebarWindow, RB_DELETEBAND, (WPARAM)uBand, 0))
521 {
522 ERR("Could not delete band!\n");
523 }
524 }
525 else
526 ERR("Could not map band id to index!\n");
527
528 FreeBand(Band);
529 return S_OK;
530 }
531
532 HRESULT STDMETHODCALLTYPE CBandSiteBase::GetBandObject(DWORD dwBandID, REFIID riid, VOID **ppv)
533 {
534 struct BandObject *Band;
535
536 TRACE("(%p, %u, %s, %p)\n", this, dwBandID, debugstr_guid(&riid), ppv);
537
538 Band = GetBandByID(dwBandID);
539 if (Band == NULL)
540 {
541 *ppv = NULL;
542 return E_FAIL;
543 }
544
545 return Band->DeskBand->QueryInterface(riid, ppv);
546 }
547
548 HRESULT STDMETHODCALLTYPE CBandSiteBase::SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
549 {
550 FIXME("(%p, %p)\n", this, pbsinfo);
551 return E_NOTIMPL;
552 }
553
554 HRESULT STDMETHODCALLTYPE CBandSiteBase::GetBandSiteInfo(BANDSITEINFO *pbsinfo)
555 {
556 FIXME("(%p, %p)\n", this, pbsinfo);
557 return E_NOTIMPL;
558 }
559
560 HRESULT STDMETHODCALLTYPE CBandSiteBase::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plrResult)
561 {
562 struct BandObject *Band;
563
564 TRACE("(%p, %p, %u, %p, %p, %p)\n", this, hWnd, uMsg, wParam, lParam, plrResult);
565
566 *plrResult = 0;
567 if (fRebarWindow == NULL)
568 return E_FAIL;
569
570 if (hWnd == fRebarWindow)
571 {
572 /* FIXME: Just send the message? */
573 *plrResult = SendMessageW(hWnd, uMsg, wParam, lParam);
574 return S_OK;
575 }
576
577 Band = GetBandFromHwnd(hWnd);
578 if (Band != NULL)
579 {
580 return Band->WndEvtHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, plrResult);
581 }
582
583 return E_FAIL;
584 }
585
586 HRESULT STDMETHODCALLTYPE CBandSiteBase::IsWindowOwner(HWND hWnd)
587 {
588 struct BandObject *Band;
589
590 TRACE("(%p, %p)\n", this, hWnd);
591
592 if (fRebarWindow == NULL)
593 return E_FAIL;
594
595 Band = GetBandFromHwnd(hWnd);
596 if (Band != NULL)
597 return S_OK;
598
599 return S_FALSE;
600 }
601
602 HRESULT STDMETHODCALLTYPE CBandSiteBase::GetWindow(HWND *phWnd)
603 {
604 TRACE("(%p, %p)\n", this, phWnd);
605
606 *phWnd = fRebarWindow;
607 if (fRebarWindow != NULL)
608 return S_OK;
609
610 return E_FAIL;
611 }
612
613 HRESULT STDMETHODCALLTYPE CBandSiteBase::ContextSensitiveHelp(BOOL fEnterMode)
614 {
615 FIXME("(%p, %d)\n", this, fEnterMode);
616 return E_NOTIMPL;
617 }
618
619 HRESULT STDMETHODCALLTYPE CBandSiteBase::SetDeskBarSite(IUnknown *pUnk)
620 {
621 HWND hWndParent;
622 HRESULT hRet;
623 DWORD style;
624
625 TRACE("(%p, %p)\n", this, pUnk);
626
627 fOleWindow.Release();
628
629 hRet = pUnk->QueryInterface(IID_PPV_ARG(IOleWindow, &fOleWindow));
630 if (FAILED_UNEXPECTEDLY(hRet))
631 return E_FAIL;
632
633 hRet = fOleWindow->GetWindow(&hWndParent);
634 if (FAILED_UNEXPECTEDLY(hRet))
635 return E_FAIL;
636
637 style = WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | RBS_VARHEIGHT | RBS_AUTOSIZE |
638 RBS_BANDBORDERS | CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN;
639
640 fRebarWindow = CreateWindowExW(WS_EX_TOOLWINDOW,
641 REBARCLASSNAMEW,
642 NULL,
643 style,
644 0, 0, 0, 0,
645 hWndParent,
646 NULL,
647 _AtlBaseModule.GetModuleInstance(),
648 NULL);
649 if (fRebarWindow == NULL)
650 {
651 fOleWindow.Release();
652 WARN("IDeskbarClient::SetDeskBarSite() failed to create ReBar control!\n");
653 return E_FAIL;
654 }
655
656 return S_OK;
657 }
658
659 HRESULT STDMETHODCALLTYPE CBandSiteBase::SetModeDBC(DWORD dwMode)
660 {
661 LONG dwStyle;
662 LONG dwPrevStyle;
663
664 TRACE("(%p, %x)\n", this, dwMode);
665
666 if (fRebarWindow == NULL)
667 return E_FAIL;
668
669 dwStyle = dwPrevStyle = GetWindowLongPtr(fRebarWindow, GWL_STYLE);
670 if (dwMode & DBIF_VIEWMODE_VERTICAL)
671 dwStyle |= CCS_VERT;
672
673 if (dwMode & ~DBIF_VIEWMODE_VERTICAL)
674 FIXME("IDeskBarClient::SetModeDBC() unhandled modes: %x\n", dwStyle & ~DBIF_VIEWMODE_VERTICAL);
675
676 if (dwStyle != dwPrevStyle)
677 {
678 SetWindowLongPtr(fRebarWindow, GWL_STYLE, dwPrevStyle);
679 }
680
681 return S_OK;
682 }
683
684 HRESULT STDMETHODCALLTYPE CBandSiteBase::UIActivateDBC(DWORD dwState)
685 {
686 TRACE("(%p, %x)\n", this, dwState);
687
688 if (fRebarWindow == NULL)
689 return E_FAIL;
690
691 ShowWindow(fRebarWindow, (dwState & DBC_SHOW) ? SW_SHOW : SW_HIDE);
692 FIXME("IDeskBarClient::UIActivateDBC() Properly notify bands?\n");
693 return S_OK;
694 }
695
696 HRESULT STDMETHODCALLTYPE CBandSiteBase::GetSize(DWORD unknown1, LPRECT unknown2)
697 {
698 FIXME("(%p, %x, %p)\n", this, unknown1, unknown2);
699 return E_NOTIMPL;
700 }
701
702 HRESULT STDMETHODCALLTYPE CBandSiteBase::QueryStatus(const GUID *pguidCmdGroup,
703 DWORD cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText)
704 {
705 FIXME("(%p, %p, %u, %p, %p)\n", this, pguidCmdGroup, cCmds, prgCmds, pCmdText);
706 return E_NOTIMPL;
707 }
708
709 HRESULT STDMETHODCALLTYPE CBandSiteBase::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
710 DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut)
711 {
712 HRESULT hRet = S_OK;
713
714 TRACE("(%p, %p, %u, %u, %p, %p)\n", this, pguidCmdGroup, nCmdID, nCmdExecOpt, pvaIn, pvaOut);
715
716 if (fRebarWindow == NULL)
717 return E_FAIL;
718
719 if (IsEqualIID(*pguidCmdGroup, IID_IDeskBand))
720 {
721 switch (nCmdID)
722 {
723 case DBID_BANDINFOCHANGED:
724 if (pvaIn == NULL)
725 hRet = UpdateAllBands();
726 else
727 {
728 /* Update a single band */
729 if (pvaIn->n1.n2.vt == VT_I4)
730 hRet = UpdateBand(pvaIn->n1.n2.n3.lVal);
731 else
732 hRet = E_FAIL;
733 }
734 break;
735
736 case DBID_SHOWONLY:
737 case DBID_MAXIMIZEBAND:
738 case DBID_PUSHCHEVRON:
739 FIXME("IOleCommandTarget::Exec(): Unsupported command ID %d\n", nCmdID);
740 return E_NOTIMPL;
741 default:
742 return E_FAIL;
743 }
744 return hRet;
745 }
746 else
747 WARN("IOleCommandTarget::Exec(): Unsupported command group GUID\n");
748
749 return E_NOTIMPL;
750 }
751
752 HRESULT STDMETHODCALLTYPE CBandSiteBase::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
753 {
754 return E_NOTIMPL;
755 }
756
757 HRESULT STDMETHODCALLTYPE CBandSiteBase::HasFocusIO()
758 {
759 return E_NOTIMPL;
760 }
761
762 HRESULT STDMETHODCALLTYPE CBandSiteBase::TranslateAcceleratorIO(LPMSG lpMsg)
763 {
764 return E_NOTIMPL;
765 }
766
767 HRESULT STDMETHODCALLTYPE CBandSiteBase::OnFocusChangeIS(struct IUnknown *paramC, int param10)
768 {
769 return E_NOTIMPL;
770 }
771
772 HRESULT STDMETHODCALLTYPE CBandSiteBase::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
773 {
774 return E_NOTIMPL;
775 }
776
777 HRESULT STDMETHODCALLTYPE CBandSiteBase::GetClassID(CLSID *pClassID)
778 {
779 return E_NOTIMPL;
780 }
781
782 HRESULT STDMETHODCALLTYPE CBandSiteBase::IsDirty()
783 {
784 return E_NOTIMPL;
785 }
786
787 HRESULT STDMETHODCALLTYPE CBandSiteBase::Load(IStream *pStm)
788 {
789 return E_NOTIMPL;
790 }
791
792 HRESULT STDMETHODCALLTYPE CBandSiteBase::Save(IStream *pStm, BOOL fClearDirty)
793 {
794 return E_NOTIMPL;
795 }
796
797 HRESULT STDMETHODCALLTYPE CBandSiteBase::GetSizeMax(ULARGE_INTEGER *pcbSize)
798 {
799 return E_NOTIMPL;
800 }
801
802 HRESULT STDMETHODCALLTYPE CBandSiteBase::DragEnter(
803 IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
804 {
805 return E_NOTIMPL;
806 }
807
808 HRESULT STDMETHODCALLTYPE CBandSiteBase::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
809 {
810 return E_NOTIMPL;
811 }
812
813 HRESULT STDMETHODCALLTYPE CBandSiteBase::DragLeave()
814 {
815 return E_NOTIMPL;
816 }
817
818 HRESULT STDMETHODCALLTYPE CBandSiteBase::Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
819 {
820 return E_NOTIMPL;
821 }
822
823 HRESULT STDMETHODCALLTYPE CBandSiteBase::LoadFromStreamBS(IStream *, const GUID &, void **)
824 {
825 return E_NOTIMPL;
826 }
827
828 HRESULT STDMETHODCALLTYPE CBandSiteBase::SaveToStreamBS(IUnknown *, IStream *)
829 {
830 return E_NOTIMPL;
831 }
832
833 extern "C"
834 HRESULT WINAPI CBandSite_CreateInstance(REFIID riid, void **ppv)
835 {
836 return ShellObjectCreator<CBandSite>(riid, ppv);
837 }