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.
29 ****Fix so an already created bar will be detected and just shown instead of added again
30 ****When a new bar is added, initiate a resize
31 **Add owner draw for base bar
32 **Make label text in base bar always draw in black
33 **Make base bar show close box
34 **Create close toolbar button
35 **Fix to delete all CBarInfo on deletion
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
;
71 HRESULT
InsertBar(IUnknown
*newBar
);
73 // *** IOleWindow methods ***
74 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
75 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
77 // *** IInputObject methods ***
78 virtual HRESULT STDMETHODCALLTYPE
UIActivateIO(BOOL fActivate
, LPMSG lpMsg
);
79 virtual HRESULT STDMETHODCALLTYPE
HasFocusIO();
80 virtual HRESULT STDMETHODCALLTYPE
TranslateAcceleratorIO(LPMSG lpMsg
);
82 // *** IServiceProvider methods ***
83 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
85 // *** IWinEventHandler methods ***
86 virtual HRESULT STDMETHODCALLTYPE
OnWinEvent(
87 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
);
88 virtual HRESULT STDMETHODCALLTYPE
IsWindowOwner(HWND hWnd
);
90 // *** IInputObjectSite specific methods ***
91 virtual HRESULT STDMETHODCALLTYPE
OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
);
93 // *** IDeskBarClient methods ***
94 virtual HRESULT STDMETHODCALLTYPE
SetDeskBarSite(IUnknown
*punkSite
);
95 virtual HRESULT STDMETHODCALLTYPE
SetModeDBC(DWORD dwMode
);
96 virtual HRESULT STDMETHODCALLTYPE
UIActivateDBC(DWORD dwState
);
97 virtual HRESULT STDMETHODCALLTYPE
GetSize(DWORD dwWhich
, LPRECT prc
);
99 // *** IOleCommandTarget methods ***
100 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
101 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
102 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
103 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
105 // *** IBandSite specific methods ***
106 virtual HRESULT STDMETHODCALLTYPE
AddBand(IUnknown
*punk
);
107 virtual HRESULT STDMETHODCALLTYPE
EnumBands(UINT uBand
, DWORD
*pdwBandID
);
108 virtual HRESULT STDMETHODCALLTYPE
QueryBand(DWORD dwBandID
, IDeskBand
**ppstb
, DWORD
*pdwState
,
109 LPWSTR pszName
, int cchName
);
110 virtual HRESULT STDMETHODCALLTYPE
SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
);
111 virtual HRESULT STDMETHODCALLTYPE
RemoveBand(DWORD dwBandID
);
112 virtual HRESULT STDMETHODCALLTYPE
GetBandObject(DWORD dwBandID
, REFIID riid
, void **ppv
);
113 virtual HRESULT STDMETHODCALLTYPE
SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
);
114 virtual HRESULT STDMETHODCALLTYPE
GetBandSiteInfo(BANDSITEINFO
*pbsinfo
);
116 // *** IPersist methods ***
117 virtual HRESULT STDMETHODCALLTYPE
GetClassID(CLSID
*pClassID
);
119 // *** IPersistStream methods ***
120 virtual HRESULT STDMETHODCALLTYPE
IsDirty();
121 virtual HRESULT STDMETHODCALLTYPE
Load(IStream
*pStm
);
122 virtual HRESULT STDMETHODCALLTYPE
Save(IStream
*pStm
, BOOL fClearDirty
);
123 virtual HRESULT STDMETHODCALLTYPE
GetSizeMax(ULARGE_INTEGER
*pcbSize
);
126 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
128 BEGIN_MSG_MAP(CBaseBarSite
)
129 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
132 BEGIN_COM_MAP(CBaseBarSite
)
133 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
134 // COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite, IDockingWindowSite)
135 COM_INTERFACE_ENTRY_IID(IID_IInputObject
, IInputObject
)
136 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
137 COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler
, IWinEventHandler
)
138 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite
, IInputObjectSite
)
139 COM_INTERFACE_ENTRY_IID(IID_IDeskBarClient
, IDeskBarClient
)
140 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
141 COM_INTERFACE_ENTRY_IID(IID_IBandSite
, IBandSite
)
142 // COM_INTERFACE_ENTRY_IID(IID_IBandSiteHelper, IBandSiteHelper)
143 // COM_INTERFACE_ENTRY_IID(IID_IExplorerToolbar, IExplorerToolbar)
144 COM_INTERFACE_ENTRY_IID(IID_IPersist
, IPersist
)
145 COM_INTERFACE_ENTRY_IID(IID_IPersistStream
, IPersistStream
)
149 CBaseBarSite::CBaseBarSite()
151 fCurrentActiveBar
= NULL
;
155 CBaseBarSite::~CBaseBarSite()
159 HRESULT
CBaseBarSite::InsertBar(IUnknown
*newBar
)
161 CComPtr
<IPersist
> persist
;
162 CComPtr
<IObjectWithSite
> site
;
163 CComPtr
<IOleWindow
> oleWindow
;
164 CComPtr
<IDeskBand
> deskBand
;
165 CComPtr
<IDockingWindow
> dockingWindow
;
167 REBARBANDINFOW bandInfo
;
168 DESKBANDINFO deskBandInfo
;
172 hResult
= newBar
->QueryInterface(IID_IPersist
, reinterpret_cast<void **>(&persist
));
175 hResult
= newBar
->QueryInterface(IID_IObjectWithSite
, reinterpret_cast<void **>(&site
));
178 hResult
= newBar
->QueryInterface(IID_IOleWindow
, reinterpret_cast<void **>(&oleWindow
));
181 hResult
= newBar
->QueryInterface(IID_IDeskBand
, reinterpret_cast<void **>(&deskBand
));
184 hResult
= newBar
->QueryInterface(IID_IDockingWindow
, reinterpret_cast<void **>(&dockingWindow
));
187 hResult
= site
->SetSite(static_cast<IOleWindow
*>(this));
190 ATLTRY(newInfo
= new CBarInfo
);
192 return E_OUTOFMEMORY
;
195 thisBandID
= fNextBandID
++;
196 newInfo
->fTheBar
= newBar
;
197 newInfo
->fBandID
= thisBandID
;
198 hResult
= persist
->GetClassID(&newInfo
->fBarClass
);
201 deskBandInfo
.dwMask
= DBIM_MINSIZE
| DBIM_ACTUAL
| DBIM_TITLE
;
202 deskBandInfo
.wszTitle
[0] = 0;
203 hResult
= deskBand
->GetBandInfo(0, 0, &deskBandInfo
);
206 memset(&bandInfo
, 0, sizeof(bandInfo
));
207 bandInfo
.cbSize
= sizeof(bandInfo
);
208 bandInfo
.fMask
= RBBIM_STYLE
| RBBIM_CHILD
| RBBIM_CHILDSIZE
| RBBIM_IDEALSIZE
| RBBIM_TEXT
|
209 RBBIM_LPARAM
| RBBIM_ID
;
210 bandInfo
.fStyle
= RBBS_NOGRIPPER
| RBBS_VARIABLEHEIGHT
;
211 bandInfo
.lpText
= deskBandInfo
.wszTitle
;
212 hResult
= oleWindow
->GetWindow(&bandInfo
.hwndChild
);
213 bandInfo
.cxMinChild
= 200; //deskBandInfo.ptMinSize.x;
214 bandInfo
.cyMinChild
= 200; //deskBandInfo.ptMinSize.y;
216 bandInfo
.wID
= thisBandID
;
217 bandInfo
.cyChild
= -1; //deskBandInfo.ptActual.y;
218 bandInfo
.cyMaxChild
= 32000;
219 bandInfo
.cyIntegral
= 1;
220 bandInfo
.cxIdeal
= 0; //deskBandInfo.ptActual.x;
221 bandInfo
.lParam
= reinterpret_cast<LPARAM
>(newInfo
);
222 SendMessage(RB_INSERTBANDW
, -1, reinterpret_cast<LPARAM
>(&bandInfo
));
224 // this call is what makes the tree fill with contents
225 hResult
= dockingWindow
->ShowDW(TRUE
);
229 fCurrentActiveBar
= newInfo
;
233 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetWindow(HWND
*lphwnd
)
241 HRESULT STDMETHODCALLTYPE
CBaseBarSite::ContextSensitiveHelp(BOOL fEnterMode
)
246 HRESULT STDMETHODCALLTYPE
CBaseBarSite::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
251 HRESULT STDMETHODCALLTYPE
CBaseBarSite::HasFocusIO()
256 HRESULT STDMETHODCALLTYPE
CBaseBarSite::TranslateAcceleratorIO(LPMSG lpMsg
)
261 HRESULT STDMETHODCALLTYPE
CBaseBarSite::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
263 CComPtr
<IServiceProvider
> serviceProvider
;
266 if (fDeskBarSite
== NULL
)
268 hResult
= fDeskBarSite
->QueryInterface(IID_IServiceProvider
, reinterpret_cast<void **>(&serviceProvider
));
271 // called for SID_STopLevelBrowser, IID_IBrowserService to find top level browser
272 // called for SID_IWebBrowserApp, IID_IConnectionPointContainer
273 // connection point called for DIID_DWebBrowserEvents2 to establish connection
274 return serviceProvider
->QueryService(guidService
, riid
, ppvObject
);
277 HRESULT STDMETHODCALLTYPE
CBaseBarSite::OnWinEvent(
278 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
280 CComPtr
<IDeskBar
> deskBar
;
281 CComPtr
<IWinEventHandler
> winEventHandler
;
287 if (uMsg
== WM_NOTIFY
)
289 notifyHeader
= (NMHDR
*)lParam
;
290 if (notifyHeader
->hwndFrom
== m_hWnd
&& notifyHeader
->code
== RBN_AUTOSIZE
)
292 hResult
= fDeskBarSite
->QueryInterface(IID_IDeskBar
, reinterpret_cast<void **>(&deskBar
));
293 GetClientRect(&newBounds
);
294 hResult
= deskBar
->OnPosRectChangeDB(&newBounds
);
297 if (fCurrentActiveBar
!= NULL
)
299 hResult
= fCurrentActiveBar
->fTheBar
->QueryInterface(
300 IID_IWinEventHandler
, reinterpret_cast<void **>(&winEventHandler
));
301 if (SUCCEEDED(hResult
) && winEventHandler
.p
!= NULL
)
302 hResult
= winEventHandler
->OnWinEvent(hWnd
, uMsg
, wParam
, lParam
, theResult
);
307 HRESULT STDMETHODCALLTYPE
CBaseBarSite::IsWindowOwner(HWND hWnd
)
312 HRESULT STDMETHODCALLTYPE
CBaseBarSite::OnFocusChangeIS (IUnknown
*punkObj
, BOOL fSetFocus
)
317 HRESULT STDMETHODCALLTYPE
CBaseBarSite::SetDeskBarSite(IUnknown
*punkSite
)
319 CComPtr
<IOleWindow
> oleWindow
;
323 if (punkSite
== NULL
)
324 fDeskBarSite
.Release();
327 hResult
= punkSite
->QueryInterface(IID_IOleWindow
, reinterpret_cast<void **>(&oleWindow
));
330 hResult
= punkSite
->QueryInterface(IID_IUnknown
, reinterpret_cast<void **>(&fDeskBarSite
));
333 hResult
= oleWindow
->GetWindow(&ownerWindow
);
336 m_hWnd
= CreateWindow(REBARCLASSNAMEW
, NULL
, WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
|
338 RBS_VARHEIGHT
| RBS_REGISTERDROP
| RBS_AUTOSIZE
| RBS_VERTICALGRIPPER
| RBS_DBLCLKTOGGLE
|
339 CCS_LEFT
| CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_NORESIZE
, 0, 0, 0, 0, ownerWindow
, NULL
,
340 _AtlBaseModule
.GetModuleInstance(), NULL
);
341 SendMessage(RB_SETTEXTCOLOR
, 0, CLR_DEFAULT
);
342 SendMessage(RB_SETBKCOLOR
, 0, CLR_DEFAULT
);
347 HRESULT STDMETHODCALLTYPE
CBaseBarSite::SetModeDBC(DWORD dwMode
)
352 HRESULT STDMETHODCALLTYPE
CBaseBarSite::UIActivateDBC(DWORD dwState
)
357 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetSize(DWORD dwWhich
, LPRECT prc
)
362 HRESULT STDMETHODCALLTYPE
CBaseBarSite::QueryStatus(const GUID
*pguidCmdGroup
,
363 ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
368 HRESULT STDMETHODCALLTYPE
CBaseBarSite::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
369 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
371 if (IsEqualIID(*pguidCmdGroup
, IID_IDeskBand
))
375 case 1: // insert a new band
376 if (V_VT(pvaIn
) != VT_UNKNOWN
)
378 return InsertBar(V_UNKNOWN(pvaIn
));
384 HRESULT STDMETHODCALLTYPE
CBaseBarSite::AddBand(IUnknown
*punk
)
386 return InsertBar(punk
);
389 HRESULT STDMETHODCALLTYPE
CBaseBarSite::EnumBands(UINT uBand
, DWORD
*pdwBandID
)
391 if (uBand
== 0xffffffff)
393 *pdwBandID
= (DWORD
)SendMessage(RB_GETBANDCOUNT
, 0, 0);
399 HRESULT STDMETHODCALLTYPE
CBaseBarSite::QueryBand(DWORD dwBandID
, IDeskBand
**ppstb
,
400 DWORD
*pdwState
, LPWSTR pszName
, int cchName
)
405 HRESULT STDMETHODCALLTYPE
CBaseBarSite::SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
)
410 HRESULT STDMETHODCALLTYPE
CBaseBarSite::RemoveBand(DWORD dwBandID
)
415 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetBandObject(DWORD dwBandID
, REFIID riid
, void **ppv
)
422 HRESULT STDMETHODCALLTYPE
CBaseBarSite::SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
)
429 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetBandSiteInfo(BANDSITEINFO
*pbsinfo
)
436 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetClassID(CLSID
*pClassID
)
438 if (pClassID
== NULL
)
440 // TODO: what class to return here?
444 HRESULT STDMETHODCALLTYPE
CBaseBarSite::IsDirty()
449 HRESULT STDMETHODCALLTYPE
CBaseBarSite::Load(IStream
*pStm
)
454 HRESULT STDMETHODCALLTYPE
CBaseBarSite::Save(IStream
*pStm
, BOOL fClearDirty
)
459 HRESULT STDMETHODCALLTYPE
CBaseBarSite::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
466 LRESULT
CBaseBarSite::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
470 notifyHeader
= reinterpret_cast<NMHDR
*>(lParam
);
471 if (notifyHeader
->hwndFrom
== m_hWnd
)
477 HRESULT
CreateBaseBarSite(REFIID riid
, void **ppv
)
479 CComObject
<CBaseBarSite
> *theBaseBarSite
;
485 ATLTRY (theBaseBarSite
= new CComObject
<CBaseBarSite
>);
486 if (theBaseBarSite
== NULL
)
487 return E_OUTOFMEMORY
;
488 hResult
= theBaseBarSite
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
491 delete theBaseBarSite
;