* Sync up to trunk r55544.
[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 #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