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.
28 Base bar that contains a vertical or horizontal explorer band. It also
29 provides resizing abilities.
33 **Make base bar support resizing
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
41 public CWindowImpl
<CBaseBar
, CWindow
, CControlWinTraits
>,
42 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
43 public IInputObjectSite
,
44 public IOleCommandTarget
,
45 public IServiceProvider
,
48 public IDockingWindow
,
49 public IPersistStream
,
50 public IPersistStreamInit
,
51 public IPersistPropertyBag
,
52 public IObjectWithSite
55 CComPtr
<IUnknown
> fSite
;
56 CComPtr
<IUnknown
> fClient
;
60 int fNeededSize
; // width or height
62 // used by resize tracking loop
69 HRESULT
ReserveBorderSpace();
71 // *** IOleWindow methods ***
72 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
73 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
75 // *** IInputObjectSite specific methods ***
76 virtual HRESULT STDMETHODCALLTYPE
OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
);
78 // *** IOleCommandTarget specific methods ***
79 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
80 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
81 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
82 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
84 // *** IServiceProvider methods ***
85 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
87 // *** IInputObject methods ***
88 // forward the methods to the contained active bar
89 virtual HRESULT STDMETHODCALLTYPE
UIActivateIO(BOOL fActivate
, LPMSG lpMsg
);
90 virtual HRESULT STDMETHODCALLTYPE
HasFocusIO();
91 virtual HRESULT STDMETHODCALLTYPE
TranslateAcceleratorIO(LPMSG lpMsg
);
93 // *** IDeskBar methods ***
94 virtual HRESULT STDMETHODCALLTYPE
SetClient(IUnknown
*punkClient
);
95 virtual HRESULT STDMETHODCALLTYPE
GetClient(IUnknown
**ppunkClient
);
96 virtual HRESULT STDMETHODCALLTYPE
OnPosRectChangeDB(LPRECT prc
);
98 // *** IDockingWindow methods ***
99 virtual HRESULT STDMETHODCALLTYPE
ShowDW(BOOL fShow
);
100 virtual HRESULT STDMETHODCALLTYPE
CloseDW(DWORD dwReserved
);
101 virtual HRESULT STDMETHODCALLTYPE
ResizeBorderDW(LPCRECT prcBorder
, IUnknown
*punkToolbarSite
, BOOL fReserved
);
103 // *** IObjectWithSite methods ***
104 virtual HRESULT STDMETHODCALLTYPE
SetSite(IUnknown
*pUnkSite
);
105 virtual HRESULT STDMETHODCALLTYPE
GetSite(REFIID riid
, void **ppvSite
);
107 // *** IPersist methods ***
108 virtual HRESULT STDMETHODCALLTYPE
GetClassID(CLSID
*pClassID
);
110 // *** IPersistStream methods ***
111 virtual HRESULT STDMETHODCALLTYPE
IsDirty();
112 virtual HRESULT STDMETHODCALLTYPE
Load(IStream
*pStm
);
113 virtual HRESULT STDMETHODCALLTYPE
Save(IStream
*pStm
, BOOL fClearDirty
);
114 virtual HRESULT STDMETHODCALLTYPE
GetSizeMax(ULARGE_INTEGER
*pcbSize
);
116 // *** IPersistStreamInit methods ***
117 virtual HRESULT STDMETHODCALLTYPE
InitNew();
119 // *** IPersistPropertyBag methods ***
120 virtual HRESULT STDMETHODCALLTYPE
Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
);
121 virtual HRESULT STDMETHODCALLTYPE
Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
);
124 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
125 LRESULT
OnSetCursor(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
126 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
127 LRESULT
OnLButtonDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
128 LRESULT
OnLButtonUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
129 LRESULT
OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
130 LRESULT
OnCancelMode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
131 LRESULT
OnCaptureChanged(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
133 DECLARE_WND_CLASS_EX(_T("BaseBar"), 0, COLOR_3DFACE
)
135 BEGIN_MSG_MAP(CBaseBar
)
136 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
137 MESSAGE_HANDLER(WM_SETCURSOR
, OnSetCursor
)
138 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
139 MESSAGE_HANDLER(WM_LBUTTONDOWN
, OnLButtonDown
)
140 MESSAGE_HANDLER(WM_LBUTTONUP
, OnLButtonUp
)
141 MESSAGE_HANDLER(WM_MOUSEMOVE
, OnMouseMove
)
142 MESSAGE_HANDLER(WM_CANCELMODE
, OnCancelMode
)
143 MESSAGE_HANDLER(WM_CAPTURECHANGED
, OnCaptureChanged
)
146 BEGIN_COM_MAP(CBaseBar
)
147 COM_INTERFACE_ENTRY2_IID(IID_IOleWindow
, IOleWindow
, IDockingWindow
)
148 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite
, IInputObjectSite
)
149 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
150 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
151 COM_INTERFACE_ENTRY_IID(IID_IInputObject
, IInputObject
)
152 COM_INTERFACE_ENTRY_IID(IID_IDeskBar
, IDeskBar
)
153 COM_INTERFACE_ENTRY_IID(IID_IDockingWindow
, IDockingWindow
)
154 COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite
, IObjectWithSite
)
155 COM_INTERFACE_ENTRY2_IID(IID_IPersist
, IPersist
, IPersistStream
)
156 COM_INTERFACE_ENTRY_IID(IID_IPersistStream
, IPersistStream
)
157 COM_INTERFACE_ENTRY_IID(IID_IPersistStreamInit
, IPersistStreamInit
)
158 COM_INTERFACE_ENTRY_IID(IID_IPersistPropertyBag
, IPersistPropertyBag
)
164 fClientWindow
= NULL
;
171 CBaseBar::~CBaseBar()
175 HRESULT
CBaseBar::ReserveBorderSpace()
177 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
178 RECT availableBorderSpace
;
179 RECT neededBorderSpace
;
182 hResult
= fSite
->QueryInterface(IID_IDockingWindowSite
, reinterpret_cast<void **>(&dockingWindowSite
));
185 hResult
= dockingWindowSite
->GetBorderDW(static_cast<IDeskBar
*>(this), &availableBorderSpace
);
188 memset(&neededBorderSpace
, 0, sizeof(neededBorderSpace
));
192 neededBorderSpace
.left
= fNeededSize
+ GetSystemMetrics(SM_CXFRAME
);
194 neededBorderSpace
.bottom
= fNeededSize
+ GetSystemMetrics(SM_CXFRAME
);
196 hResult
= dockingWindowSite
->SetBorderSpaceDW(static_cast<IDeskBar
*>(this), &neededBorderSpace
);
202 // current bar size is stored in the registry under
203 // key=HKCU\Software\Microsoft\Internet Explorer\Explorer Bars
204 // value=current bar GUID
205 // result is 8 bytes of binary data, 2 longs. First is the size, second is reserved and will always be 0
206 /*HRESULT CBaseBar::StopCurrentBar()
208 CComPtr<IOleCommandTarget> commandTarget;
211 if (fCurrentBar.p != NULL)
213 hResult = fCurrentBar->QueryInterface(IID_IOleCommandTarget, (void **)&commandTarget);
214 hResult = commandTarget->Exec(NULL, 0x17, 0, NULL, NULL);
216 // hide the current bar
217 memcpy(&fCurrentActiveClass, &GUID_NULL, sizeof(fCurrentActiveClass));
221 HRESULT STDMETHODCALLTYPE
CBaseBar::GetWindow(HWND
*lphwnd
)
229 HRESULT STDMETHODCALLTYPE
CBaseBar::ContextSensitiveHelp(BOOL fEnterMode
)
234 HRESULT STDMETHODCALLTYPE
CBaseBar::OnFocusChangeIS (IUnknown
*punkObj
, BOOL fSetFocus
)
240 HRESULT STDMETHODCALLTYPE
CBaseBar::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
241 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
246 HRESULT STDMETHODCALLTYPE
CBaseBar::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
247 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
249 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
))
252 else if (IsEqualIID(*pguidCmdGroup
, IID_IDeskBarClient
))
268 HRESULT STDMETHODCALLTYPE
CBaseBar::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
270 CComPtr
<IServiceProvider
> serviceProvider
;
275 hResult
= fSite
->QueryInterface(IID_IServiceProvider
, reinterpret_cast<void **>(&serviceProvider
));
278 // called for SID_STopLevelBrowser, IID_IBrowserService to find top level browser
279 // called for SID_IWebBrowserApp, IID_IConnectionPointContainer
280 // connection point called for DIID_DWebBrowserEvents2 to establish connection
281 return serviceProvider
->QueryService(guidService
, riid
, ppvObject
);
284 HRESULT STDMETHODCALLTYPE
CBaseBar::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
286 // forward to contained bar
290 HRESULT STDMETHODCALLTYPE
CBaseBar::HasFocusIO()
292 // forward to contained bar
296 HRESULT STDMETHODCALLTYPE
CBaseBar::TranslateAcceleratorIO(LPMSG lpMsg
)
298 // forward to contained bar
302 HRESULT STDMETHODCALLTYPE
CBaseBar::SetClient(IUnknown
*punkClient
)
304 CComPtr
<IOleWindow
> oleWindow
;
308 if (punkClient
== NULL
)
312 hResult
= punkClient
->QueryInterface(IID_IUnknown
, reinterpret_cast<void **>(&fClient
));
315 hResult
= fSite
->QueryInterface(IID_IOleWindow
, reinterpret_cast<void **>(&oleWindow
));
318 hResult
= oleWindow
->GetWindow(&ownerWindow
);
321 Create(ownerWindow
, 0, NULL
,
322 WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
, WS_EX_TOOLWINDOW
);
323 ReserveBorderSpace();
328 HRESULT STDMETHODCALLTYPE
CBaseBar::GetClient(IUnknown
**ppunkClient
)
330 if (ppunkClient
== NULL
)
332 *ppunkClient
= fClient
;
333 if (fClient
.p
!= NULL
)
338 HRESULT STDMETHODCALLTYPE
CBaseBar::OnPosRectChangeDB(LPRECT prc
)
343 fNeededSize
= prc
->right
- prc
->left
;
345 fNeededSize
= prc
->bottom
- prc
->top
;
346 ReserveBorderSpace();
350 HRESULT STDMETHODCALLTYPE
CBaseBar::ShowDW(BOOL fShow
)
352 fVisible
= fShow
? true : false;
353 ReserveBorderSpace();
357 HRESULT STDMETHODCALLTYPE
CBaseBar::CloseDW(DWORD dwReserved
)
360 ReserveBorderSpace();
364 HRESULT STDMETHODCALLTYPE
CBaseBar::ResizeBorderDW(LPCRECT prcBorder
, IUnknown
*punkToolbarSite
, BOOL fReserved
)
366 ReserveBorderSpace();
370 HRESULT STDMETHODCALLTYPE
CBaseBar::SetSite(IUnknown
*pUnkSite
)
376 HRESULT STDMETHODCALLTYPE
CBaseBar::GetSite(REFIID riid
, void **ppvSite
)
386 HRESULT STDMETHODCALLTYPE
CBaseBar::GetClassID(CLSID
*pClassID
)
388 if (pClassID
== NULL
)
390 // TODO: what class to return here?
394 HRESULT STDMETHODCALLTYPE
CBaseBar::IsDirty()
399 HRESULT STDMETHODCALLTYPE
CBaseBar::Load(IStream
*pStm
)
404 HRESULT STDMETHODCALLTYPE
CBaseBar::Save(IStream
*pStm
, BOOL fClearDirty
)
409 HRESULT STDMETHODCALLTYPE
CBaseBar::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
416 HRESULT STDMETHODCALLTYPE
CBaseBar::InitNew()
421 HRESULT STDMETHODCALLTYPE
CBaseBar::Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
)
426 HRESULT STDMETHODCALLTYPE
CBaseBar::Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
)
431 LRESULT
CBaseBar::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
433 /* CComPtr<IOleWindow> oleWindow;
437 if (fClientWindow == NULL && fClient.p != NULL)
439 hResult = fClient->QueryInterface(IID_IOleWindow, (void **)&oleWindow);
440 hResult = oleWindow->GetWindow(&fClientWindow);
442 if (fClientWindow != NULL)
444 GetClientRect(&clientRect);
445 ::SetWindowPos(fClientWindow, NULL, clientRect.left, clientRect.top, clientRect.right - clientRect.left - GetSystemMetrics(SM_CXFRAME),
446 clientRect.bottom - clientRect.top, SWP_NOOWNERZORDER | SWP_NOZORDER);
451 LRESULT
CBaseBar::OnSetCursor(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
453 if ((short)lParam
!= HTCLIENT
|| (HWND
)wParam
!= m_hWnd
)
459 SetCursor(LoadCursor(NULL
, IDC_SIZEWE
));
461 SetCursor(LoadCursor(NULL
, IDC_SIZENS
));
465 LRESULT
CBaseBar::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
467 CComPtr
<IWinEventHandler
> winEventHandler
;
472 if (fClient
.p
!= NULL
)
474 hResult
= fClient
->QueryInterface(IID_IWinEventHandler
, reinterpret_cast<void **>(&winEventHandler
));
475 if (SUCCEEDED(hResult
) && winEventHandler
.p
!= NULL
)
476 hResult
= winEventHandler
->OnWinEvent(NULL
, uMsg
, wParam
, lParam
, &result
);
481 LRESULT
CBaseBar::OnLButtonDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
485 fLastLocation
.x
= (short)LOWORD(lParam
);
486 fLastLocation
.y
= (short)HIWORD(lParam
);
490 LRESULT
CBaseBar::OnLButtonUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
497 LRESULT
CBaseBar::OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
504 newLocation
.x
= (short)LOWORD(lParam
);
505 newLocation
.y
= (short)HIWORD(lParam
);
508 delta
= newLocation
.x
- fLastLocation
.x
;
510 delta
= newLocation
.y
- fLastLocation
.y
;
513 fLastLocation
= newLocation
;
518 LRESULT
CBaseBar::OnCancelMode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
524 LRESULT
CBaseBar::OnCaptureChanged(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
530 HRESULT
CreateBaseBar(REFIID riid
, void **ppv
)
532 CComObject
<CBaseBar
> *theBaseBar
;
538 ATLTRY (theBaseBar
= new CComObject
<CBaseBar
>);
539 if (theBaseBar
== NULL
)
540 return E_OUTOFMEMORY
;
541 hResult
= theBaseBar
->QueryInterface (riid
, reinterpret_cast<void **>(ppv
));