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 This class knows how to contain base bar site in a cabinet window.
25 #include "shellbars.h"
28 Base bar that contains a vertical or horizontal explorer band. It also
29 provides resizing abilities.
33 **Make base bar support resizing -- almost done (need to support integral ?)
34 Add context menu for base bar
35 Fix base bar to correctly initialize fVertical field
36 Fix base bar to correctly reposition its base bar site when resized -- done ?
40 public CWindowImpl
<CBaseBar
, CWindow
, CControlWinTraits
>,
41 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
42 public IInputObjectSite
,
43 public IOleCommandTarget
,
44 public IServiceProvider
,
47 public IDockingWindow
,
48 public IPersistStream
,
49 public IPersistStreamInit
,
50 public IPersistPropertyBag
,
51 public IObjectWithSite
54 CComPtr
<IUnknown
> fSite
;
55 CComPtr
<IUnknown
> fClient
;
59 int fNeededSize
; // width or height
61 // used by resize tracking loop
67 HRESULT
Initialize(BOOL
);
70 HRESULT
ReserveBorderSpace();
72 // *** IOleWindow methods ***
73 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
74 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
76 // *** IInputObjectSite specific methods ***
77 virtual HRESULT STDMETHODCALLTYPE
OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
);
79 // *** IOleCommandTarget specific methods ***
80 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
81 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
82 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
83 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
85 // *** IServiceProvider methods ***
86 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
88 // *** IInputObject methods ***
89 // forward the methods to the contained active bar
90 virtual HRESULT STDMETHODCALLTYPE
UIActivateIO(BOOL fActivate
, LPMSG lpMsg
);
91 virtual HRESULT STDMETHODCALLTYPE
HasFocusIO();
92 virtual HRESULT STDMETHODCALLTYPE
TranslateAcceleratorIO(LPMSG lpMsg
);
94 // *** IDeskBar methods ***
95 virtual HRESULT STDMETHODCALLTYPE
SetClient(IUnknown
*punkClient
);
96 virtual HRESULT STDMETHODCALLTYPE
GetClient(IUnknown
**ppunkClient
);
97 virtual HRESULT STDMETHODCALLTYPE
OnPosRectChangeDB(LPRECT prc
);
99 // *** IDockingWindow methods ***
100 virtual HRESULT STDMETHODCALLTYPE
ShowDW(BOOL fShow
);
101 virtual HRESULT STDMETHODCALLTYPE
CloseDW(DWORD dwReserved
);
102 virtual HRESULT STDMETHODCALLTYPE
ResizeBorderDW(LPCRECT prcBorder
, IUnknown
*punkToolbarSite
, BOOL fReserved
);
104 // *** IObjectWithSite methods ***
105 virtual HRESULT STDMETHODCALLTYPE
SetSite(IUnknown
*pUnkSite
);
106 virtual HRESULT STDMETHODCALLTYPE
GetSite(REFIID riid
, void **ppvSite
);
108 // *** IPersist methods ***
109 virtual HRESULT STDMETHODCALLTYPE
GetClassID(CLSID
*pClassID
);
111 // *** IPersistStream methods ***
112 virtual HRESULT STDMETHODCALLTYPE
IsDirty();
113 virtual HRESULT STDMETHODCALLTYPE
Load(IStream
*pStm
);
114 virtual HRESULT STDMETHODCALLTYPE
Save(IStream
*pStm
, BOOL fClearDirty
);
115 virtual HRESULT STDMETHODCALLTYPE
GetSizeMax(ULARGE_INTEGER
*pcbSize
);
117 // *** IPersistStreamInit methods ***
118 virtual HRESULT STDMETHODCALLTYPE
InitNew();
120 // *** IPersistPropertyBag methods ***
121 virtual HRESULT STDMETHODCALLTYPE
Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
);
122 virtual HRESULT STDMETHODCALLTYPE
Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
);
125 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
126 LRESULT
OnSetCursor(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
127 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
128 LRESULT
OnLButtonDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
129 LRESULT
OnLButtonUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
130 LRESULT
OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
131 LRESULT
OnCancelMode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
132 LRESULT
OnCaptureChanged(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
134 DECLARE_WND_CLASS_EX(_T("BaseBar"), 0, COLOR_3DFACE
)
136 BEGIN_MSG_MAP(CBaseBar
)
137 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
138 MESSAGE_HANDLER(WM_SETCURSOR
, OnSetCursor
)
139 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
140 MESSAGE_HANDLER(WM_LBUTTONDOWN
, OnLButtonDown
)
141 MESSAGE_HANDLER(WM_LBUTTONUP
, OnLButtonUp
)
142 MESSAGE_HANDLER(WM_MOUSEMOVE
, OnMouseMove
)
143 MESSAGE_HANDLER(WM_CANCELMODE
, OnCancelMode
)
144 MESSAGE_HANDLER(WM_CAPTURECHANGED
, OnCaptureChanged
)
147 BEGIN_COM_MAP(CBaseBar
)
148 COM_INTERFACE_ENTRY2_IID(IID_IOleWindow
, IOleWindow
, IDockingWindow
)
149 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite
, IInputObjectSite
)
150 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
151 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
152 COM_INTERFACE_ENTRY_IID(IID_IInputObject
, IInputObject
)
153 COM_INTERFACE_ENTRY_IID(IID_IDeskBar
, IDeskBar
)
154 COM_INTERFACE_ENTRY_IID(IID_IDockingWindow
, IDockingWindow
)
155 COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite
, IObjectWithSite
)
156 COM_INTERFACE_ENTRY2_IID(IID_IPersist
, IPersist
, IPersistStream
)
157 COM_INTERFACE_ENTRY_IID(IID_IPersistStream
, IPersistStream
)
158 COM_INTERFACE_ENTRY_IID(IID_IPersistStreamInit
, IPersistStreamInit
)
159 COM_INTERFACE_ENTRY_IID(IID_IPersistPropertyBag
, IPersistPropertyBag
)
165 fClientWindow
= NULL
;
172 CBaseBar::~CBaseBar()
176 HRESULT
CBaseBar::Initialize(BOOL vert
)
178 fVertical
= (vert
== TRUE
);
182 HRESULT
CBaseBar::ReserveBorderSpace()
184 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
185 RECT availableBorderSpace
;
186 RECT neededBorderSpace
;
189 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
190 if (FAILED_UNEXPECTEDLY(hResult
))
192 hResult
= dockingWindowSite
->GetBorderDW(static_cast<IDeskBar
*>(this), &availableBorderSpace
);
193 if (FAILED_UNEXPECTEDLY(hResult
))
195 memset(&neededBorderSpace
, 0, sizeof(neededBorderSpace
));
199 neededBorderSpace
.left
= fNeededSize
+ GetSystemMetrics(SM_CXFRAME
);
201 neededBorderSpace
.bottom
= fNeededSize
+ GetSystemMetrics(SM_CXFRAME
);
203 hResult
= dockingWindowSite
->SetBorderSpaceDW(static_cast<IDeskBar
*>(this), &neededBorderSpace
);
204 if (FAILED_UNEXPECTEDLY(hResult
))
209 // current bar size is stored in the registry under
210 // key=HKCU\Software\Microsoft\Internet Explorer\Explorer Bars
211 // value=current bar GUID
212 // result is 8 bytes of binary data, 2 longs. First is the size, second is reserved and will always be 0
213 /*HRESULT CBaseBar::StopCurrentBar()
215 CComPtr<IOleCommandTarget> commandTarget;
218 if (fCurrentBar.p != NULL)
220 hResult = fCurrentBar->QueryInterface(IID_IOleCommandTarget, (void **)&commandTarget);
221 hResult = commandTarget->Exec(NULL, 0x17, 0, NULL, NULL);
223 // hide the current bar
224 memcpy(&fCurrentActiveClass, &GUID_NULL, sizeof(fCurrentActiveClass));
228 HRESULT STDMETHODCALLTYPE
CBaseBar::GetWindow(HWND
*lphwnd
)
236 HRESULT STDMETHODCALLTYPE
CBaseBar::ContextSensitiveHelp(BOOL fEnterMode
)
241 HRESULT STDMETHODCALLTYPE
CBaseBar::OnFocusChangeIS (IUnknown
*punkObj
, BOOL fSetFocus
)
243 return IUnknown_OnFocusChangeIS(fSite
, punkObj
, fSetFocus
);
246 HRESULT STDMETHODCALLTYPE
CBaseBar::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
247 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
252 HRESULT STDMETHODCALLTYPE
CBaseBar::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
253 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
255 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
))
257 // pass through to the explorer ?
259 else if (IsEqualIID(*pguidCmdGroup
, IID_IDeskBarClient
))
276 HRESULT STDMETHODCALLTYPE
CBaseBar::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
278 CComPtr
<IServiceProvider
> serviceProvider
;
283 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
284 if (FAILED_UNEXPECTEDLY(hResult
))
286 // called for SID_STopLevelBrowser, IID_IBrowserService to find top level browser
287 // called for SID_IWebBrowserApp, IID_IConnectionPointContainer
288 // connection point called for DIID_DWebBrowserEvents2 to establish connection
289 return serviceProvider
->QueryService(guidService
, riid
, ppvObject
);
292 HRESULT STDMETHODCALLTYPE
CBaseBar::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
294 return IUnknown_UIActivateIO(fClient
, fActivate
, lpMsg
);
297 HRESULT STDMETHODCALLTYPE
CBaseBar::HasFocusIO()
299 return IUnknown_HasFocusIO(fClient
);
302 HRESULT STDMETHODCALLTYPE
CBaseBar::TranslateAcceleratorIO(LPMSG lpMsg
)
304 return IUnknown_TranslateAcceleratorIO(fClient
, lpMsg
);
307 HRESULT STDMETHODCALLTYPE
CBaseBar::SetClient(IUnknown
*punkClient
)
309 CComPtr
<IOleWindow
> oleWindow
;
313 /* Clean up old client */
318 hResult
= punkClient
->QueryInterface(IID_PPV_ARG(IUnknown
, &fClient
));
319 if (FAILED_UNEXPECTEDLY(hResult
))
321 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IOleWindow
, &oleWindow
));
322 if (FAILED_UNEXPECTEDLY(hResult
))
324 hResult
= oleWindow
->GetWindow(&ownerWindow
);
325 if (FAILED_UNEXPECTEDLY(hResult
))
327 Create(ownerWindow
, 0, NULL
,
328 WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
, WS_EX_TOOLWINDOW
);
329 ReserveBorderSpace();
338 HRESULT STDMETHODCALLTYPE
CBaseBar::GetClient(IUnknown
**ppunkClient
)
340 if (ppunkClient
== NULL
)
342 *ppunkClient
= fClient
;
343 if (fClient
.p
!= NULL
)
348 HRESULT STDMETHODCALLTYPE
CBaseBar::OnPosRectChangeDB(LPRECT prc
)
353 fNeededSize
= prc
->right
- prc
->left
;
355 fNeededSize
= prc
->bottom
- prc
->top
;
356 ReserveBorderSpace();
360 HRESULT STDMETHODCALLTYPE
CBaseBar::ShowDW(BOOL fShow
)
362 fVisible
= fShow
? true : false;
364 ReserveBorderSpace();
368 HRESULT STDMETHODCALLTYPE
CBaseBar::CloseDW(DWORD dwReserved
)
371 // Detach from our client
378 HRESULT STDMETHODCALLTYPE
CBaseBar::ResizeBorderDW(LPCRECT prcBorder
, IUnknown
*punkToolbarSite
, BOOL fReserved
)
380 ReserveBorderSpace();
384 HRESULT STDMETHODCALLTYPE
CBaseBar::SetSite(IUnknown
*pUnkSite
)
390 HRESULT STDMETHODCALLTYPE
CBaseBar::GetSite(REFIID riid
, void **ppvSite
)
400 HRESULT STDMETHODCALLTYPE
CBaseBar::GetClassID(CLSID
*pClassID
)
402 if (pClassID
== NULL
)
404 // TODO: what class to return here?
408 HRESULT STDMETHODCALLTYPE
CBaseBar::IsDirty()
413 HRESULT STDMETHODCALLTYPE
CBaseBar::Load(IStream
*pStm
)
418 HRESULT STDMETHODCALLTYPE
CBaseBar::Save(IStream
*pStm
, BOOL fClearDirty
)
423 HRESULT STDMETHODCALLTYPE
CBaseBar::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
430 HRESULT STDMETHODCALLTYPE
CBaseBar::InitNew()
435 HRESULT STDMETHODCALLTYPE
CBaseBar::Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
)
440 HRESULT STDMETHODCALLTYPE
CBaseBar::Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
)
445 LRESULT
CBaseBar::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
449 CComPtr
<IOleWindow
> pClient
;
455 dwWidth
= LOWORD(lParam
);
456 dwHeight
= HIWORD(lParam
);
458 // substract resizing grips to child's window size
460 dwWidth
-= GetSystemMetrics(SM_CXFRAME
);
462 dwHeight
-= GetSystemMetrics(SM_CXFRAME
);
463 hr
= fClient
->QueryInterface(IID_PPV_ARG(IOleWindow
, &pClient
));
464 if (FAILED_UNEXPECTEDLY(hr
))
466 hr
= pClient
->GetWindow(&clientHwnd
);
467 if (FAILED_UNEXPECTEDLY(hr
))
469 ::SetWindowPos(clientHwnd
, NULL
, 0, (fVertical
) ? 0 : GetSystemMetrics(SM_CXFRAME
), dwWidth
, dwHeight
, NULL
);
475 LRESULT
CBaseBar::OnSetCursor(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
477 if ((short)lParam
!= HTCLIENT
|| (HWND
)wParam
!= m_hWnd
)
483 SetCursor(LoadCursor(NULL
, IDC_SIZEWE
));
485 SetCursor(LoadCursor(NULL
, IDC_SIZENS
));
489 LRESULT
CBaseBar::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
491 CComPtr
<IWinEventHandler
> winEventHandler
;
496 if (fClient
.p
!= NULL
)
498 hResult
= fClient
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &winEventHandler
));
499 if (SUCCEEDED(hResult
) && winEventHandler
.p
!= NULL
)
500 hResult
= winEventHandler
->OnWinEvent(NULL
, uMsg
, wParam
, lParam
, &result
);
505 LRESULT
CBaseBar::OnLButtonDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
509 fLastLocation
.x
= (short)LOWORD(lParam
);
510 fLastLocation
.y
= (short)HIWORD(lParam
);
514 LRESULT
CBaseBar::OnLButtonUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
521 LRESULT
CBaseBar::OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
528 newLocation
.x
= (short)LOWORD(lParam
);
529 newLocation
.y
= (short)HIWORD(lParam
);
531 delta
= newLocation
.x
- fLastLocation
.x
;
533 delta
= fLastLocation
.y
- newLocation
.y
;
534 if (fNeededSize
+ delta
< 0)
536 fNeededSize
+= delta
;
537 fLastLocation
= newLocation
;
538 ReserveBorderSpace();
543 LRESULT
CBaseBar::OnCancelMode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
549 LRESULT
CBaseBar::OnCaptureChanged(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
555 HRESULT
CBaseBar_CreateInstance(REFIID riid
, void **ppv
, BOOL vertical
)
557 return ShellObjectCreatorInit
<CBaseBar
, BOOL
>(vertical
, riid
, ppv
);