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