xref: /reactos/dll/win32/browseui/toolsband.cpp (revision c2d0d784)
1 /*
2  * ReactOS Explorer
3  *
4  * Copyright 2009 Andrew Hill <ash77 at domain reactos.org>
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 /*
22 Implements the toolbar band of a cabinet window
23 */
24 #include "precomp.h"
25 
26 /*
27 TODO:
28   **Fix GetBandInfo to calculate size correctly
29 */
30 
31 class CToolsBand :
32 	public CWindowImpl<CToolsBand, CWindow, CControlWinTraits>,
33 	public CComObjectRootEx<CComMultiThreadModelNoCS>,
34 	public IDeskBand,
35 	public IObjectWithSite,
36 	public IInputObject,
37 	public IPersistStream
38 {
39 private:
40 	IDockingWindowSite			*fDockSite;
41 	GUID						fExecCommandCategory;
42 	CComPtr<IOleCommandTarget>	fExecCommandTarget;
43 public:
44 	CToolsBand();
45 	~CToolsBand();
46 public:
47 	// *** IDeskBand methods ***
48 	virtual HRESULT STDMETHODCALLTYPE GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi);
49 
50 	// *** IObjectWithSite methods ***
51 	virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown* pUnkSite);
52 	virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite);
53 
54 	// *** IOleWindow methods ***
55 	virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
56 	virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
57 
58 	// *** IDockingWindow methods ***
59 	virtual HRESULT STDMETHODCALLTYPE CloseDW(DWORD dwReserved);
60 	virtual HRESULT STDMETHODCALLTYPE ResizeBorderDW(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved);
61 	virtual HRESULT STDMETHODCALLTYPE ShowDW(BOOL fShow);
62 
63 	// *** IInputObject methods ***
64 	virtual HRESULT STDMETHODCALLTYPE HasFocusIO();
65 	virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO(LPMSG lpMsg);
66 	virtual HRESULT STDMETHODCALLTYPE UIActivateIO(BOOL fActivate, LPMSG lpMsg);
67 
68 	// *** IPersist methods ***
69 	virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
70 
71 	// *** IPersistStream methods ***
72 	virtual HRESULT STDMETHODCALLTYPE IsDirty();
73 	virtual HRESULT STDMETHODCALLTYPE Load(IStream *pStm);
74 	virtual HRESULT STDMETHODCALLTYPE Save(IStream *pStm, BOOL fClearDirty);
75 	virtual HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize);
76 
77 	// message handlers
78 	LRESULT OnGetButtonInfo(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled);
79 
80 BEGIN_MSG_MAP(CToolsBand)
81 //	MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
82 //	MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
83 	NOTIFY_HANDLER(0, TBN_GETBUTTONINFOW, OnGetButtonInfo)
84 END_MSG_MAP()
85 
86 BEGIN_COM_MAP(CToolsBand)
87 	COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
88 	COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
89 	COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
90 	COM_INTERFACE_ENTRY_IID(IID_IDockingWindow, IDockingWindow)
91 	COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject)
92 	COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
93 	COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
94 END_COM_MAP()
95 };
96 
97 CToolsBand::CToolsBand()
98 {
99 	fDockSite = NULL;
100 }
101 
102 CToolsBand::~CToolsBand()
103 {
104 	if (fDockSite)
105 		fDockSite->Release();
106 }
107 
108 HRESULT STDMETHODCALLTYPE CToolsBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi)
109 {
110 	if (pdbi->dwMask & DBIM_MINSIZE)
111 	{
112 		pdbi->ptMinSize.x = 400;
113 		pdbi->ptMinSize.y = 38;
114 	}
115 	if (pdbi->dwMask & DBIM_MAXSIZE)
116 	{
117 		pdbi->ptMaxSize.x = 0;
118 		pdbi->ptMaxSize.y = 0;
119 	}
120 	if (pdbi->dwMask & DBIM_INTEGRAL)
121 	{
122 		pdbi->ptIntegral.x = 0;
123 		pdbi->ptIntegral.y = 0;
124 	}
125 	if (pdbi->dwMask & DBIM_ACTUAL)
126 	{
127 		pdbi->ptActual.x = 400;
128 		pdbi->ptActual.y = 38;
129 	}
130 	if (pdbi->dwMask & DBIM_TITLE)
131 		wcscpy(pdbi->wszTitle, L"");
132 	if (pdbi->dwMask & DBIM_MODEFLAGS)
133 		pdbi->dwModeFlags = DBIMF_UNDELETEABLE;
134 	if (pdbi->dwMask & DBIM_BKCOLOR)
135 		pdbi->crBkgnd = 0;
136 	return S_OK;
137 }
138 
139 static const int backImageIndex = 0;
140 static const int forwardImageIndex = 1;
141 static const int favoritesImageIndex = 2;
142 // 3
143 // 4
144 static const int cutImageIndex = 5;
145 static const int copyImageIndex = 6;
146 static const int pasteImageIndex = 7;
147 static const int undoImageIndex = 8;
148 static const int redoImageIndex = 9;
149 static const int deleteImageIndex = 10;
150 // 11
151 // 12
152 // 13
153 // 14
154 static const int propertiesImageIndex = 15;
155 // 16
156 static const int searchImageIndex = 17;
157 // 18
158 // 19
159 // 20
160 // 21
161 static const int viewsImageIndex = 22;
162 // 23
163 // 24
164 // 25
165 // 26
166 // 27
167 static const int upImageIndex = 28;
168 static const int mapDriveImageIndex = 29;
169 static const int disconnectImageIndex = 30;
170 // 31
171 static const int viewsAltImageIndex = 32;		// same image as viewsImageIndex
172 // 33
173 // 34
174 // 35
175 // 36
176 // 37
177 static const int viewsAlt2ImageIndex = 38;		// same image as viewsAltImageIndex & viewsImageIndex
178 // 39
179 // 40
180 // 41
181 // 42
182 static const int foldersImageIndex = 43;
183 static const int moveToImageIndex = 44;
184 static const int copyToImageIndex = 45;
185 static const int folderOptionsImageIndex = 46;
186 
187 const int numShownButtons = 13;
188 const int numHiddenButtons = 13;
189 TBBUTTON tbButtonsAdd[numShownButtons + numHiddenButtons] =
190 {
191 	{backImageIndex, gBackCommandID, TBSTATE_ENABLED, BTNS_DROPDOWN | BTNS_SHOWTEXT, {0}, 0, (INT_PTR)_T("Back")},
192 	{forwardImageIndex, gForwardCommandID, TBSTATE_ENABLED, BTNS_DROPDOWN, {0}, 0, (INT_PTR)_T("Forward")},
193 	{upImageIndex, gUpLevelCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Up")},
194 	{6, -1, TBSTATE_ENABLED, BTNS_SEP},
195 	{searchImageIndex, gSearchCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, {0}, 0, (INT_PTR)_T("Search")},
196 	{foldersImageIndex, gFoldersCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, {0}, 0, (INT_PTR)_T("Folders")},
197 	{6, -1, TBSTATE_ENABLED, BTNS_SEP},
198 	{moveToImageIndex, gMoveToCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Move To")},
199 	{copyToImageIndex, gCopyToCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Copy To")},
200 	{deleteImageIndex, gDeleteCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Delete")},
201 	{undoImageIndex, gUndoCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Undo")},
202 	{6, -1, TBSTATE_ENABLED, BTNS_SEP},
203 	{viewsImageIndex, gViewsCommandID, TBSTATE_ENABLED, BTNS_WHOLEDROPDOWN, {0}, 0, (INT_PTR)_T("Views")},
204 
205 	{0, gStopCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Stop")},
206 	{0, gRefreshCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Refresh")},
207 	{0, gHomeCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Home")},
208 	{mapDriveImageIndex, gMapDriveCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Map Drive")},
209 	{disconnectImageIndex, gDisconnectCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Disconnect")},
210 	{favoritesImageIndex, gFavoritesCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, {0}, 0, (INT_PTR)_T("Favorites")},
211 	{0, gHistoryCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("History")},
212 	{0, gFullScreenCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Full Screen")},
213 	{propertiesImageIndex, gPropertiesCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Properties")},
214 	{cutImageIndex, gCutCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Cut")},
215 	{copyImageIndex, gCopyCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Copy")},
216 	{pasteImageIndex, gPasteCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Paste")},
217 	{folderOptionsImageIndex, gFolderOptionsCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Folder Options")},
218 };
219 
220 HRESULT STDMETHODCALLTYPE CToolsBand::SetSite(IUnknown* pUnkSite)
221 {
222 	HWND					parentWindow;
223 	IOleWindow				*oleWindow;
224 	HWND					toolbar;
225 	HRESULT					hResult;
226 
227 	if (fDockSite != NULL)
228 		fDockSite->Release();
229 	if (pUnkSite == NULL)
230 		return S_OK;
231 	hResult = pUnkSite->QueryInterface(IID_IDockingWindowSite, (void **)&fDockSite);
232 	if (FAILED(hResult))
233 		return hResult;
234 	parentWindow = NULL;
235 	hResult = pUnkSite->QueryInterface(IID_IOleWindow, (void **)&oleWindow);
236 	if (SUCCEEDED(hResult))
237 	{
238 		oleWindow->GetWindow(&parentWindow);
239 		oleWindow->Release();
240 	}
241 	if (!::IsWindow(parentWindow))
242 		return E_FAIL;
243 
244 	toolbar = CreateWindowEx(TBSTYLE_EX_DOUBLEBUFFER, TOOLBARCLASSNAMEW, _T(""), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
245 					WS_CLIPCHILDREN | TBSTYLE_TOOLTIPS | TBSTYLE_TRANSPARENT | TBSTYLE_REGISTERDROP | TBSTYLE_LIST | TBSTYLE_FLAT |
246 					CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_TOP, 0, 0, 500, 20, parentWindow, NULL,
247 					_AtlBaseModule.GetModuleInstance(), 0);
248 	if (toolbar == NULL)
249 		return E_FAIL;
250 	SubclassWindow(toolbar);
251 
252 	SendMessage(WM_USER + 100, GetSystemMetrics(SM_CXEDGE) / 2, 0);
253 	SendMessage(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
254 	SendMessage(TB_SETMAXTEXTROWS, 1, 0);
255 	SendMessage(TB_SETEXTENDEDSTYLE, TBSTYLE_EX_HIDECLIPPEDBUTTONS | TBSTYLE_EX_MIXEDBUTTONS | TBSTYLE_EX_DRAWDDARROWS, TBSTYLE_EX_HIDECLIPPEDBUTTONS | TBSTYLE_EX_MIXEDBUTTONS | TBSTYLE_EX_DRAWDDARROWS);
256 
257 	HINSTANCE shell32Instance = GetModuleHandle(_T("shell32.dll"));
258 	HBITMAP imageBitmap = (HBITMAP)LoadImage(shell32Instance, MAKEINTRESOURCE(214), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
259 
260 	DIBSECTION bitmapInfo;
261 	GetObjectW(imageBitmap, sizeof(bitmapInfo), &bitmapInfo);
262 	HIMAGELIST imageList = ImageList_Create(bitmapInfo.dsBm.bmHeight, bitmapInfo.dsBm.bmHeight, ILC_COLOR32, 4, 4);
263 
264 	ImageList_Add(imageList, imageBitmap, NULL);
265 	DeleteObject(imageBitmap);
266 
267 	SendMessage(TB_SETIMAGELIST, 0, (LPARAM)imageList);
268 
269 	SendMessage(TB_ADDBUTTONSW, numShownButtons, (LPARAM)&tbButtonsAdd);
270 
271 	return hResult;
272 }
273 
274 HRESULT STDMETHODCALLTYPE CToolsBand::GetSite(REFIID riid, void **ppvSite)
275 {
276 	if (fDockSite == NULL)
277 		return E_FAIL;
278 	return fDockSite->QueryInterface(riid, ppvSite);
279 }
280 
281 HRESULT STDMETHODCALLTYPE CToolsBand::GetWindow(HWND *lphwnd)
282 {
283 	if (lphwnd == NULL)
284 		return E_POINTER;
285 	*lphwnd = m_hWnd;
286 	return S_OK;
287 }
288 
289 HRESULT STDMETHODCALLTYPE CToolsBand::ContextSensitiveHelp(BOOL fEnterMode)
290 {
291 
292 	return E_NOTIMPL;
293 }
294 
295 HRESULT STDMETHODCALLTYPE CToolsBand::CloseDW(DWORD dwReserved)
296 {
297     ShowDW(FALSE);
298 
299     if (IsWindow())
300         DestroyWindow();
301 
302     m_hWnd = NULL;
303 
304     return S_OK;
305 }
306 
307 HRESULT STDMETHODCALLTYPE CToolsBand::ResizeBorderDW(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved)
308 {
309 	return E_NOTIMPL;
310 }
311 
312 HRESULT STDMETHODCALLTYPE CToolsBand::ShowDW(BOOL fShow)
313 {
314     if (m_hWnd)
315     {
316         if (fShow)
317             ShowWindow(SW_SHOW);
318         else
319             ShowWindow(SW_HIDE);
320     }
321     return S_OK;
322 }
323 
324 HRESULT STDMETHODCALLTYPE CToolsBand::HasFocusIO()
325 {
326 	return E_NOTIMPL;
327 }
328 
329 HRESULT STDMETHODCALLTYPE CToolsBand::TranslateAcceleratorIO(LPMSG lpMsg)
330 {
331 	return E_NOTIMPL;
332 }
333 
334 HRESULT STDMETHODCALLTYPE CToolsBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
335 {
336 	return E_NOTIMPL;
337 }
338 
339 HRESULT STDMETHODCALLTYPE CToolsBand::GetClassID(CLSID *pClassID)
340 {
341 	return E_NOTIMPL;
342 }
343 
344 HRESULT STDMETHODCALLTYPE CToolsBand::IsDirty()
345 {
346 	return E_NOTIMPL;
347 }
348 
349 HRESULT STDMETHODCALLTYPE CToolsBand::Load(IStream *pStm)
350 {
351 	return E_NOTIMPL;
352 }
353 
354 HRESULT STDMETHODCALLTYPE CToolsBand::Save(IStream *pStm, BOOL fClearDirty)
355 {
356 	return E_NOTIMPL;
357 }
358 
359 HRESULT STDMETHODCALLTYPE CToolsBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
360 {
361 	return E_NOTIMPL;
362 }
363 
364 LRESULT CToolsBand::OnGetButtonInfo(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
365 {
366 	TBNOTIFYW *pTBntf = (TBNOTIFYW *)pNMHDR;
367 
368 	if (pTBntf->iItem >= 0 && pTBntf->iItem < (numShownButtons + numHiddenButtons))
369 	{
370 		pTBntf->tbButton = tbButtonsAdd[pTBntf->iItem];
371 		return TRUE;
372 	}
373 	else
374 		return FALSE;
375 	return 0;
376 }
377 
378 HRESULT CreateToolsBar(REFIID riid, void **ppv)
379 {
380 	CComObject<CToolsBand>					*theMenuBar;
381 	HRESULT									hResult;
382 
383 	if (ppv == NULL)
384 		return E_POINTER;
385 	*ppv = NULL;
386 	ATLTRY (theMenuBar = new CComObject<CToolsBand>);
387 	if (theMenuBar == NULL)
388 		return E_OUTOFMEMORY;
389 	hResult = theMenuBar->QueryInterface (riid, (void **)ppv);
390 	if (FAILED (hResult))
391 	{
392 		delete theMenuBar;
393 		return hResult;
394 	}
395 	return S_OK;
396 }
397 
398