4 * Copyright 2009 Andrew Hill <ash77 at domain 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 Base bar that contains a vertical or horizontal explorer band. It also
23 provides resizing abilities.
30 ****When a new bar is added, resize correctly the band inside instead of keeping current size.
31 *Translate close button label
32 **Add owner draw for base bar -- hackplemented atm
33 **Make label text in base bar always draw in black
34 ***Set rebar band style flags accordingly to what band object asked.
35 ***Set rebar style accordingly to direction
36 ****This class should also manage desktop bands ? (another kind of explorer bands)
40 public CWindowImpl
<CBaseBarSite
, CWindow
, CControlWinTraits
>,
41 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
42 // public IDockingWindowSite,
44 public IServiceProvider
,
45 public IWinEventHandler
,
46 public IInputObjectSite
,
47 public IDeskBarClient
,
48 public IOleCommandTarget
,
50 // public IBandSiteHelper,
51 // public IExplorerToolbar,
58 CComPtr
<IUnknown
> fTheBar
;
59 CLSID fBarClass
; // class of active bar
63 CBarInfo
*fCurrentActiveBar
; //
64 // HWND fRebarWindow; // rebar for top of window
65 CComPtr
<IUnknown
> fDeskBarSite
;
68 HIMAGELIST toolImageList
;
73 HRESULT
Initialize(BOOL vert
) { fVertical
= vert
; return S_OK
; };
75 HRESULT
InsertBar(IUnknown
*newBar
);
77 // *** IOleWindow methods ***
78 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
79 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
81 // *** IInputObject methods ***
82 virtual HRESULT STDMETHODCALLTYPE
UIActivateIO(BOOL fActivate
, LPMSG lpMsg
);
83 virtual HRESULT STDMETHODCALLTYPE
HasFocusIO();
84 virtual HRESULT STDMETHODCALLTYPE
TranslateAcceleratorIO(LPMSG lpMsg
);
86 // *** IServiceProvider methods ***
87 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
89 // *** IWinEventHandler methods ***
90 virtual HRESULT STDMETHODCALLTYPE
OnWinEvent(
91 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
);
92 virtual HRESULT STDMETHODCALLTYPE
IsWindowOwner(HWND hWnd
);
94 // *** IInputObjectSite specific methods ***
95 virtual HRESULT STDMETHODCALLTYPE
OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
);
97 // *** IDeskBarClient methods ***
98 virtual HRESULT STDMETHODCALLTYPE
SetDeskBarSite(IUnknown
*punkSite
);
99 virtual HRESULT STDMETHODCALLTYPE
SetModeDBC(DWORD dwMode
);
100 virtual HRESULT STDMETHODCALLTYPE
UIActivateDBC(DWORD dwState
);
101 virtual HRESULT STDMETHODCALLTYPE
GetSize(DWORD dwWhich
, LPRECT prc
);
103 // *** IOleCommandTarget methods ***
104 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
105 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
106 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
107 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
109 // *** IBandSite specific methods ***
110 virtual HRESULT STDMETHODCALLTYPE
AddBand(IUnknown
*punk
);
111 virtual HRESULT STDMETHODCALLTYPE
EnumBands(UINT uBand
, DWORD
*pdwBandID
);
112 virtual HRESULT STDMETHODCALLTYPE
QueryBand(DWORD dwBandID
, IDeskBand
**ppstb
, DWORD
*pdwState
,
113 LPWSTR pszName
, int cchName
);
114 virtual HRESULT STDMETHODCALLTYPE
SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
);
115 virtual HRESULT STDMETHODCALLTYPE
RemoveBand(DWORD dwBandID
);
116 virtual HRESULT STDMETHODCALLTYPE
GetBandObject(DWORD dwBandID
, REFIID riid
, void **ppv
);
117 virtual HRESULT STDMETHODCALLTYPE
SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
);
118 virtual HRESULT STDMETHODCALLTYPE
GetBandSiteInfo(BANDSITEINFO
*pbsinfo
);
120 // *** IPersist methods ***
121 virtual HRESULT STDMETHODCALLTYPE
GetClassID(CLSID
*pClassID
);
123 // *** IPersistStream methods ***
124 virtual HRESULT STDMETHODCALLTYPE
IsDirty();
125 virtual HRESULT STDMETHODCALLTYPE
Load(IStream
*pStm
);
126 virtual HRESULT STDMETHODCALLTYPE
Save(IStream
*pStm
, BOOL fClearDirty
);
127 virtual HRESULT STDMETHODCALLTYPE
GetSizeMax(ULARGE_INTEGER
*pcbSize
);
130 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
131 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
132 LRESULT
OnCustomDraw(LPNMCUSTOMDRAW pnmcd
);
135 HFONT
GetTitleFont();
136 HRESULT
FindBandByGUID(REFIID pGuid
, DWORD
*pdwBandID
);
137 HRESULT
ShowBand(DWORD dwBandID
);
138 HRESULT
GetInternalBandInfo(UINT uBand
, REBARBANDINFO
*pBandInfo
);
139 HRESULT
GetInternalBandInfo(UINT uBand
, REBARBANDINFO
*pBandInfo
, DWORD fMask
);
142 BEGIN_MSG_MAP(CBaseBarSite
)
143 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
144 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
147 BEGIN_COM_MAP(CBaseBarSite
)
148 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
149 // COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite, IDockingWindowSite)
150 COM_INTERFACE_ENTRY_IID(IID_IInputObject
, IInputObject
)
151 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
152 COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler
, IWinEventHandler
)
153 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite
, IInputObjectSite
)
154 COM_INTERFACE_ENTRY_IID(IID_IDeskBarClient
, IDeskBarClient
)
155 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
156 COM_INTERFACE_ENTRY_IID(IID_IBandSite
, IBandSite
)
157 // COM_INTERFACE_ENTRY_IID(IID_IBandSiteHelper, IBandSiteHelper)
158 // COM_INTERFACE_ENTRY_IID(IID_IExplorerToolbar, IExplorerToolbar)
159 COM_INTERFACE_ENTRY_IID(IID_IPersist
, IPersist
)
160 COM_INTERFACE_ENTRY_IID(IID_IPersistStream
, IPersistStream
)
164 CBaseBarSite::CBaseBarSite() : fVertical(TRUE
)
166 fCurrentActiveBar
= NULL
;
170 CBaseBarSite::~CBaseBarSite()
172 TRACE("CBaseBarSite deleted\n");
175 HRESULT
CBaseBarSite::InsertBar(IUnknown
*newBar
)
177 CComPtr
<IPersist
> persist
;
178 CComPtr
<IObjectWithSite
> site
;
179 CComPtr
<IOleWindow
> oleWindow
;
180 CComPtr
<IDeskBand
> deskBand
;
182 REBARBANDINFOW bandInfo
;
183 DESKBANDINFO deskBandInfo
;
188 hResult
= newBar
->QueryInterface(IID_PPV_ARG(IPersist
, &persist
));
189 if (FAILED_UNEXPECTEDLY(hResult
))
191 hResult
= newBar
->QueryInterface(IID_PPV_ARG(IObjectWithSite
, &site
));
192 if (FAILED_UNEXPECTEDLY(hResult
))
194 hResult
= newBar
->QueryInterface(IID_PPV_ARG(IOleWindow
, &oleWindow
));
195 if (FAILED_UNEXPECTEDLY(hResult
))
197 hResult
= newBar
->QueryInterface(IID_PPV_ARG(IDeskBand
, &deskBand
));
198 if (FAILED_UNEXPECTEDLY(hResult
))
201 // Check if the GUID already exists
202 hResult
= persist
->GetClassID(&tmp
);
203 if (!SUCCEEDED(hResult
))
207 if (FindBandByGUID(tmp
, &thisBandID
) == S_OK
)
209 return ShowBand(thisBandID
);
212 hResult
= site
->SetSite(static_cast<IOleWindow
*>(this));
213 if (FAILED_UNEXPECTEDLY(hResult
))
216 ATLTRY(newInfo
= new CBarInfo
);
218 return E_OUTOFMEMORY
;
221 thisBandID
= fNextBandID
++;
222 newInfo
->fTheBar
= newBar
;
223 newInfo
->fBandID
= thisBandID
;
224 newInfo
->fBarClass
= tmp
;
227 deskBandInfo
.dwMask
= DBIM_MINSIZE
| DBIM_ACTUAL
| DBIM_TITLE
| DBIM_BKCOLOR
;
228 deskBandInfo
.wszTitle
[0] = 0;
229 hResult
= deskBand
->GetBandInfo(0, (fVertical
) ? DBIF_VIEWMODE_VERTICAL
: DBIF_VIEWMODE_NORMAL
, &deskBandInfo
);
232 memset(&bandInfo
, 0, sizeof(bandInfo
));
233 bandInfo
.cbSize
= sizeof(bandInfo
);
234 bandInfo
.fMask
= RBBIM_STYLE
| RBBIM_CHILD
| RBBIM_CHILDSIZE
| RBBIM_IDEALSIZE
| RBBIM_TEXT
|
235 RBBIM_LPARAM
| RBBIM_ID
;
236 bandInfo
.fStyle
= RBBS_TOPALIGN
| RBBS_VARIABLEHEIGHT
| RBBS_NOGRIPPER
;
237 bandInfo
.lpText
= deskBandInfo
.wszTitle
;
238 hResult
= oleWindow
->GetWindow(&bandInfo
.hwndChild
);
239 /* It seems Windows XP doesn't take account of band minsize */
241 bandInfo
.cxMinChild
= 200; //deskBandInfo.ptMinSize.x;
242 bandInfo
.cyMinChild
= 200; //deskBandInfo.ptMinSize.y;
245 bandInfo
.wID
= thisBandID
;
246 bandInfo
.cyChild
= -1; //deskBandInfo.ptActual.y;
247 bandInfo
.cyMaxChild
= 32000;
248 bandInfo
.cyIntegral
= 1;
249 bandInfo
.cxIdeal
= 0; //deskBandInfo.ptActual.x;
250 bandInfo
.lParam
= reinterpret_cast<LPARAM
>(newInfo
);
251 SendMessage(RB_INSERTBANDW
, -1, reinterpret_cast<LPARAM
>(&bandInfo
));
252 hResult
= ShowBand(newInfo
->fBandID
);
253 //fCurrentActiveBar = newInfo;
257 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetWindow(HWND
*lphwnd
)
265 HRESULT STDMETHODCALLTYPE
CBaseBarSite::ContextSensitiveHelp(BOOL fEnterMode
)
270 HRESULT STDMETHODCALLTYPE
CBaseBarSite::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
272 if (!fCurrentActiveBar
)
275 return IUnknown_UIActivateIO(fCurrentActiveBar
->fTheBar
, fActivate
, lpMsg
);
278 HRESULT STDMETHODCALLTYPE
CBaseBarSite::HasFocusIO()
280 if (!fCurrentActiveBar
)
283 return IUnknown_HasFocusIO(fCurrentActiveBar
->fTheBar
);
286 HRESULT STDMETHODCALLTYPE
CBaseBarSite::TranslateAcceleratorIO(LPMSG lpMsg
)
288 if (!fCurrentActiveBar
)
292 TranslateMessage(lpMsg
);
293 DispatchMessage(lpMsg
);
298 return IUnknown_TranslateAcceleratorIO(fCurrentActiveBar
->fTheBar
, lpMsg
);
301 HRESULT STDMETHODCALLTYPE
CBaseBarSite::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
303 CComPtr
<IServiceProvider
> serviceProvider
;
306 if (fDeskBarSite
== NULL
)
308 hResult
= fDeskBarSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
309 if (FAILED_UNEXPECTEDLY(hResult
))
311 // called for SID_STopLevelBrowser, IID_IBrowserService to find top level browser
312 // called for SID_IWebBrowserApp, IID_IConnectionPointContainer
313 // connection point called for DIID_DWebBrowserEvents2 to establish connection
314 return serviceProvider
->QueryService(guidService
, riid
, ppvObject
);
317 HRESULT STDMETHODCALLTYPE
CBaseBarSite::OnWinEvent(
318 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
320 CComPtr
<IDeskBar
> deskBar
;
321 CComPtr
<IWinEventHandler
> winEventHandler
;
328 if (uMsg
== WM_NOTIFY
)
330 notifyHeader
= (NMHDR
*)lParam
;
331 if (notifyHeader
->hwndFrom
== m_hWnd
)
333 switch (notifyHeader
->code
)
336 // For now, don't notify basebar we tried to resize ourselves, we don't
337 // get correct values at the moment.
339 hResult
= fDeskBarSite
->QueryInterface(IID_PPV_ARG(IDeskBar
, &deskBar
));
340 GetClientRect(&newBounds
);
341 hResult
= deskBar
->OnPosRectChangeDB(&newBounds
);
346 result
= OnCustomDraw((LPNMCUSTOMDRAW
)lParam
);
353 if (fCurrentActiveBar
!= NULL
)
355 hResult
= fCurrentActiveBar
->fTheBar
->QueryInterface(
356 IID_PPV_ARG(IWinEventHandler
, &winEventHandler
));
357 if (SUCCEEDED(hResult
) && winEventHandler
.p
!= NULL
)
358 hResult
= winEventHandler
->OnWinEvent(hWnd
, uMsg
, wParam
, lParam
, theResult
);
363 HRESULT STDMETHODCALLTYPE
CBaseBarSite::IsWindowOwner(HWND hWnd
)
368 HRESULT STDMETHODCALLTYPE
CBaseBarSite::OnFocusChangeIS (IUnknown
*punkObj
, BOOL fSetFocus
)
370 // FIXME: should we directly pass-through, or advertise ourselves as focus owner ?
371 return IUnknown_OnFocusChangeIS(fDeskBarSite
, punkObj
, fSetFocus
);
374 HRESULT STDMETHODCALLTYPE
CBaseBarSite::SetDeskBarSite(IUnknown
*punkSite
)
376 CComPtr
<IOleWindow
> oleWindow
;
381 if (punkSite
== NULL
)
384 TRACE("Destroying site \n");
385 /* Cleanup our bands */
386 while(SUCCEEDED(EnumBands(-1, &dwBandID
)) && dwBandID
)
388 hResult
= EnumBands(0, &dwBandID
);
389 if(FAILED_UNEXPECTEDLY(hResult
))
391 RemoveBand(dwBandID
);
400 hResult
= punkSite
->QueryInterface(IID_PPV_ARG(IOleWindow
, &oleWindow
));
401 if (FAILED_UNEXPECTEDLY(hResult
))
403 hResult
= punkSite
->QueryInterface(IID_PPV_ARG(IUnknown
, &fDeskBarSite
));
404 if (FAILED_UNEXPECTEDLY(hResult
))
406 hResult
= oleWindow
->GetWindow(&ownerWindow
);
407 if (FAILED_UNEXPECTEDLY(hResult
))
410 DWORD dwStyle
= WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_BORDER
|
411 RBS_VARHEIGHT
| RBS_REGISTERDROP
| RBS_AUTOSIZE
| RBS_VERTICALGRIPPER
| RBS_DBLCLKTOGGLE
|
412 CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_NORESIZE
;
416 /* Create site window */
417 HWND tmp
= CreateWindowW(REBARCLASSNAMEW
, NULL
, dwStyle
, 0, 0, 0, 0, ownerWindow
, NULL
,
418 _AtlBaseModule
.GetModuleInstance(), NULL
);
420 /* Give window management to ATL */
423 SendMessage(RB_SETTEXTCOLOR
, 0, CLR_DEFAULT
);
424 SendMessage(RB_SETBKCOLOR
, 0, CLR_DEFAULT
);
426 /* Create close toolbar and imagelist */
427 toolbarWnd
= CreateWindowW(TOOLBARCLASSNAMEW
, NULL
,
428 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
429 TBSTYLE_FLAT
| TBSTYLE_TRANSPARENT
| TBSTYLE_TOOLTIPS
|
430 CCS_NOMOVEY
| CCS_NORESIZE
| CCS_NOPARENTALIGN
| CCS_NODIVIDER
431 , 0, 0, 0, 0, m_hWnd
, NULL
, _AtlBaseModule
.GetModuleInstance(), NULL
);
433 toolImageList
= ImageList_Create(13, 11, ILC_COLOR24
| ILC_MASK
, 3, 0);
435 hBmp
= (HBITMAP
)LoadImage(_AtlBaseModule
.GetModuleInstance(),
436 MAKEINTRESOURCE(IDB_BANDBUTTONS
), IMAGE_BITMAP
, 0, 0,
439 ImageList_AddMasked(toolImageList
, hBmp
, RGB(192, 192, 192));
442 SendMessage(toolbarWnd
, TB_SETIMAGELIST
, 0, (LPARAM
)toolImageList
);
444 /* Add button to toolbar */
445 closeBtn
.iBitmap
= MAKELONG(1, 0);
446 closeBtn
.idCommand
= IDM_BASEBAR_CLOSE
;
447 closeBtn
.fsState
= TBSTATE_ENABLED
;
448 closeBtn
.fsStyle
= BTNS_BUTTON
;
449 ZeroMemory(closeBtn
.bReserved
, sizeof(closeBtn
.bReserved
));
451 closeBtn
.iString
= (INT_PTR
)L
"Close";
453 SendMessage(toolbarWnd
, TB_INSERTBUTTON
, 0, (LPARAM
)&closeBtn
);
454 SendMessage(toolbarWnd
, TB_SETMAXTEXTROWS
, 0, 0);
455 //SendMessage(toolbarWnd, TB_AUTOSIZE, 0, 0);
460 HRESULT STDMETHODCALLTYPE
CBaseBarSite::SetModeDBC(DWORD dwMode
)
465 HRESULT STDMETHODCALLTYPE
CBaseBarSite::UIActivateDBC(DWORD dwState
)
470 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetSize(DWORD dwWhich
, LPRECT prc
)
475 HRESULT STDMETHODCALLTYPE
CBaseBarSite::QueryStatus(const GUID
*pguidCmdGroup
,
476 ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
481 HRESULT STDMETHODCALLTYPE
CBaseBarSite::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
482 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
484 if (IsEqualIID(*pguidCmdGroup
, IID_IDeskBand
))
490 case 1: // insert a new band
491 if (V_VT(pvaIn
) != VT_UNKNOWN
)
493 return InsertBar(V_UNKNOWN(pvaIn
));
502 HRESULT
CBaseBarSite::GetInternalBandInfo(UINT uBand
, REBARBANDINFO
*pBandInfo
)
506 memset(pBandInfo
, 0, sizeof(REBARBANDINFO
));
507 pBandInfo
->cbSize
= sizeof(REBARBANDINFO
);
508 pBandInfo
->fMask
= RBBIM_LPARAM
| RBBIM_ID
;
510 // Grab our bandinfo from rebar control
511 if (!SendMessage(RB_GETBANDINFO
, uBand
, reinterpret_cast<LPARAM
>(pBandInfo
)))
516 HRESULT
CBaseBarSite::GetInternalBandInfo(UINT uBand
, REBARBANDINFO
*pBandInfo
, DWORD fMask
)
520 pBandInfo
->cbSize
= sizeof(REBARBANDINFO
);
521 pBandInfo
->fMask
= fMask
;
523 // Grab our bandinfo from rebar control
524 if (!SendMessage(RB_GETBANDINFO
, uBand
, reinterpret_cast<LPARAM
>(pBandInfo
)))
529 HRESULT STDMETHODCALLTYPE
CBaseBarSite::AddBand(IUnknown
*punk
)
531 return InsertBar(punk
);
534 HRESULT STDMETHODCALLTYPE
CBaseBarSite::EnumBands(UINT uBand
, DWORD
*pdwBandID
)
536 REBARBANDINFO bandInfo
;
538 if (pdwBandID
== NULL
)
540 if (uBand
== 0xffffffff)
542 *pdwBandID
= (DWORD
)SendMessage(RB_GETBANDCOUNT
, 0, 0);
545 if (!SUCCEEDED(GetInternalBandInfo(uBand
, &bandInfo
)))
547 *pdwBandID
= bandInfo
.wID
;
551 HRESULT STDMETHODCALLTYPE
CBaseBarSite::QueryBand(DWORD dwBandID
, IDeskBand
**ppstb
,
552 DWORD
*pdwState
, LPWSTR pszName
, int cchName
)
557 HRESULT STDMETHODCALLTYPE
CBaseBarSite::SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
)
562 HRESULT STDMETHODCALLTYPE
CBaseBarSite::RemoveBand(DWORD dwBandID
)
564 REBARBANDINFO bandInfo
;
567 CComPtr
<IObjectWithSite
> pSite
;
568 CComPtr
<IDeskBand
> pDockWnd
;
571 // Retrieve the right index of the coolbar knowing the id
572 index
= SendMessage(RB_IDTOINDEX
, dwBandID
, 0);
573 if (index
== 0xffffffff)
576 if (FAILED_UNEXPECTEDLY(GetInternalBandInfo(index
, &bandInfo
)))
579 pInfo
= reinterpret_cast<CBarInfo
*>(bandInfo
.lParam
);
583 hr
= pInfo
->fTheBar
->QueryInterface(IID_PPV_ARG(IDeskBand
, &pDockWnd
));
584 if (FAILED_UNEXPECTEDLY(hr
))
586 return E_NOINTERFACE
;
588 hr
= pInfo
->fTheBar
->QueryInterface(IID_PPV_ARG(IObjectWithSite
, &pSite
));
589 if (FAILED_UNEXPECTEDLY(hr
))
591 return E_NOINTERFACE
;
593 /* Windows sends a CloseDW before setting site to NULL */
594 pDockWnd
->CloseDW(0);
595 pSite
->SetSite(NULL
);
597 // Delete the band from rebar
598 if (!SendMessage(RB_DELETEBAND
, index
, 0))
600 ERR("Can't delete the band\n");
603 if (pInfo
== fCurrentActiveBar
)
605 // FIXME: what to do when we are deleting active bar ? Let's assume we remove it for now
606 fCurrentActiveBar
= NULL
;
612 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetBandObject(DWORD dwBandID
, REFIID riid
, void **ppv
)
614 REBARBANDINFO bandInfo
;
622 // Retrieve the right index of the coolbar knowing the id
623 index
= SendMessage(RB_IDTOINDEX
, dwBandID
, 0);
624 if (index
== 0xffffffff)
627 if (FAILED_UNEXPECTEDLY(GetInternalBandInfo(index
, &bandInfo
)))
630 pInfo
= reinterpret_cast<CBarInfo
*>(bandInfo
.lParam
);
631 hr
= pInfo
->fTheBar
->QueryInterface(riid
, ppv
);
633 return E_NOINTERFACE
;
637 HRESULT STDMETHODCALLTYPE
CBaseBarSite::SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
)
644 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetBandSiteInfo(BANDSITEINFO
*pbsinfo
)
651 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetClassID(CLSID
*pClassID
)
653 if (pClassID
== NULL
)
655 // TODO: what class to return here?
659 HRESULT STDMETHODCALLTYPE
CBaseBarSite::IsDirty()
664 HRESULT STDMETHODCALLTYPE
CBaseBarSite::Load(IStream
*pStm
)
669 HRESULT STDMETHODCALLTYPE
CBaseBarSite::Save(IStream
*pStm
, BOOL fClearDirty
)
674 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
681 LRESULT
CBaseBarSite::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
685 notifyHeader
= reinterpret_cast<NMHDR
*>(lParam
);
686 if (notifyHeader
->hwndFrom
== m_hWnd
)
689 bHandled
= FALSE
; /* forward notification to parent */
693 LRESULT
CBaseBarSite::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
695 if (HIWORD(wParam
) == BN_CLICKED
&& LOWORD(wParam
) == IDM_BASEBAR_CLOSE
)
697 /* Tell the base bar to hide */
698 IUnknown_Exec(fDeskBarSite
, IID_IDeskBarClient
, 0, 0, NULL
, NULL
);
704 LRESULT
CBaseBarSite::OnCustomDraw(LPNMCUSTOMDRAW pnmcd
)
706 switch (pnmcd
->dwDrawStage
)
710 return CDRF_NOTIFYITEMDRAW
;
711 case CDDS_ITEMPREPAINT
:
715 WCHAR wszTitle
[MAX_PATH
];
718 HFONT newFont
, oldFont
;
720 index
= SendMessage(RB_IDTOINDEX
, fCurrentActiveBar
->fBandID
, 0);
721 ZeroMemory(&info
, sizeof(info
));
722 ZeroMemory(wszTitle
, sizeof(wszTitle
));
723 DrawEdge(pnmcd
->hdc
, &pnmcd
->rc
, EDGE_ETCHED
, BF_BOTTOM
);
724 // We also resize our close button
725 ::SetWindowPos(toolbarWnd
, HWND_TOP
, pnmcd
->rc
.right
- 22, 0, 20, 18, SWP_SHOWWINDOW
);
728 info
.lpText
= wszTitle
;
732 if (FAILED_UNEXPECTEDLY(GetInternalBandInfo(index
, &info
, RBBIM_TEXT
)))
733 return CDRF_SKIPDEFAULT
;
734 newFont
= GetTitleFont();
736 oldFont
= (HFONT
)SelectObject(pnmcd
->hdc
, newFont
);
737 DrawText(pnmcd
->hdc
, info
.lpText
, -1, &rt
, DT_SINGLELINE
| DT_LEFT
);
738 SelectObject(pnmcd
->hdc
, oldFont
);
739 DeleteObject(newFont
);
740 return CDRF_SKIPDEFAULT
;
744 DrawEdge(pnmcd
->hdc
, &pnmcd
->rc
, EDGE_ETCHED
, BF_BOTTOM
);
745 // We also resize our close button
746 ::SetWindowPos(toolbarWnd
, HWND_TOP
, 0, 2, 20, 18, SWP_SHOWWINDOW
);
748 return CDRF_SKIPDEFAULT
;
752 return CDRF_DODEFAULT
;
755 HFONT
CBaseBarSite::GetTitleFont()
758 mt
.cbSize
= sizeof(mt
);
759 if (!SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, sizeof(mt
), &mt
, 0))
761 ERR("Can't get system parameters !\n");
764 return CreateFontIndirect(&mt
.lfMenuFont
);
768 HRESULT
CBaseBarSite::FindBandByGUID(REFGUID pGuid
, DWORD
*pdwBandID
)
773 REBARBANDINFO bandInfo
;
776 hr
= EnumBands(-1, &numBands
);
777 if (FAILED_UNEXPECTEDLY(hr
))
780 for(i
= 0; i
< numBands
; i
++)
782 if (FAILED_UNEXPECTEDLY(GetInternalBandInfo(i
, &bandInfo
)))
784 realInfo
= (CBarInfo
*)bandInfo
.lParam
;
785 if (IsEqualGUID(pGuid
, realInfo
->fBarClass
))
787 *pdwBandID
= realInfo
->fBandID
;
794 HRESULT
CBaseBarSite::ShowBand(DWORD dwBandID
)
797 CComPtr
<IDeskBand
> dockingWindow
;
799 REBARBANDINFO bandInfo
;
802 hResult
= GetBandObject(dwBandID
, IID_PPV_ARG(IDeskBand
, &dockingWindow
));
803 if (FAILED_UNEXPECTEDLY(hResult
))
806 hResult
= dockingWindow
->ShowDW(TRUE
);
808 // Hide old band while adding new one
809 if (fCurrentActiveBar
&& fCurrentActiveBar
->fBandID
!= dwBandID
)
812 index
= SendMessage(RB_IDTOINDEX
, fCurrentActiveBar
->fBandID
, 0);
813 if (index
!= 0xffffffff)
814 SendMessage(RB_SHOWBAND
, index
, 0);
816 if (FAILED_UNEXPECTEDLY(hResult
))
819 // Display the current band
820 index
= SendMessage(RB_IDTOINDEX
, dwBandID
, 0);
821 if (index
!= 0xffffffff)
822 SendMessage(RB_SHOWBAND
, index
, 1);
823 if (FAILED_UNEXPECTEDLY(GetInternalBandInfo(index
, &bandInfo
)))
825 fCurrentActiveBar
= (CBarInfo
*)bandInfo
.lParam
;
829 HRESULT
CBaseBarSite_CreateInstance(REFIID riid
, void **ppv
, BOOL bVertical
)
831 return ShellObjectCreatorInit
<CBaseBarSite
, BOOL
>(bVertical
, riid
, ppv
);