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 class CToolsBand :
28 public CWindowImpl<CToolsBand, CWindow, CControlWinTraits>,
29 public CComObjectRootEx<CComMultiThreadModelNoCS>,
30 public IDeskBand,
31 public IObjectWithSite,
32 public IInputObject,
33 public IPersistStream
34 {
35 private:
36 CComPtr<IDockingWindowSite> fDockSite;
37 HIMAGELIST m_himlNormal;
38 HIMAGELIST m_himlHot;
39 public:
40 CToolsBand();
41 virtual ~CToolsBand();
42 public:
43 // *** IDeskBand methods ***
44 STDMETHOD(GetBandInfo)(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi) override;
45
46 // *** IObjectWithSite methods ***
47 STDMETHOD(SetSite)(IUnknown* pUnkSite) override;
48 STDMETHOD(GetSite)(REFIID riid, void **ppvSite) override;
49
50 // *** IOleWindow methods ***
51 STDMETHOD(GetWindow)(HWND *lphwnd) override;
52 STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode) override;
53
54 // *** IDockingWindow methods ***
55 STDMETHOD(CloseDW)(DWORD dwReserved) override;
56 STDMETHOD(ResizeBorderDW)(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved) override;
57 STDMETHOD(ShowDW)(BOOL fShow) override;
58
59 // *** IInputObject methods ***
60 STDMETHOD(HasFocusIO)() override;
61 STDMETHOD(TranslateAcceleratorIO)(LPMSG lpMsg) override;
62 STDMETHOD(UIActivateIO)(BOOL fActivate, LPMSG lpMsg) override;
63
64 // *** IPersist methods ***
65 STDMETHOD(GetClassID)(CLSID *pClassID) override;
66
67 // *** IPersistStream methods ***
68 STDMETHOD(IsDirty)() override;
69 STDMETHOD(Load)(IStream *pStm) override;
70 STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty) override;
71 STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize) override;
72
73 // message handlers
74 LRESULT OnGetButtonInfo(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled);
75
76 BEGIN_MSG_MAP(CToolsBand)
77 // MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
78 // MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
79 NOTIFY_HANDLER(0, TBN_GETBUTTONINFOW, OnGetButtonInfo)
80 END_MSG_MAP()
81
82 BEGIN_COM_MAP(CToolsBand)
83 COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
84 COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
85 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
86 COM_INTERFACE_ENTRY_IID(IID_IDockingWindow, IDockingWindow)
87 COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject)
88 COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
89 COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
90 END_COM_MAP()
91 };
92
CToolsBand()93 CToolsBand::CToolsBand()
94 : fDockSite(NULL)
95 {
96 }
97
~CToolsBand()98 CToolsBand::~CToolsBand()
99 {
100 }
101
GetBandInfo(DWORD dwBandID,DWORD dwViewMode,DESKBANDINFO * pdbi)102 HRESULT STDMETHODCALLTYPE CToolsBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi)
103 {
104 RECT actualRect;
105 POINTL actualSize;
106 POINTL idealSize;
107 POINTL maxSize;
108 POINTL itemSize;
109
110 ::GetWindowRect(m_hWnd, &actualRect);
111 actualSize.x = actualRect.right - actualRect.left;
112 actualSize.y = actualRect.bottom - actualRect.top;
113
114 /* Obtain the ideal size, to be used as min and max */
115 SendMessageW(m_hWnd, TB_AUTOSIZE, 0, 0);
116 SendMessageW(m_hWnd, TB_GETMAXSIZE, 0, reinterpret_cast<LPARAM>(&maxSize));
117
118 idealSize = maxSize;
119 SendMessageW(m_hWnd, TB_GETIDEALSIZE, FALSE, reinterpret_cast<LPARAM>(&idealSize));
120
121 /* Obtain the button size, to be used as the integral size */
122 DWORD size = SendMessageW(m_hWnd, TB_GETBUTTONSIZE, 0, 0);
123 itemSize.x = GET_X_LPARAM(size);
124 itemSize.y = GET_Y_LPARAM(size);
125
126 if (pdbi->dwMask & DBIM_MINSIZE)
127 {
128 pdbi->ptMinSize = idealSize;
129 }
130 if (pdbi->dwMask & DBIM_MAXSIZE)
131 {
132 pdbi->ptMaxSize = maxSize;
133 }
134 if (pdbi->dwMask & DBIM_INTEGRAL)
135 {
136 pdbi->ptIntegral = itemSize;
137 }
138 if (pdbi->dwMask & DBIM_ACTUAL)
139 {
140 pdbi->ptActual = actualSize;
141 }
142 if (pdbi->dwMask & DBIM_TITLE)
143 wcscpy(pdbi->wszTitle, L"");
144 if (pdbi->dwMask & DBIM_MODEFLAGS)
145 pdbi->dwModeFlags = DBIMF_UNDELETEABLE;
146 if (pdbi->dwMask & DBIM_BKCOLOR)
147 pdbi->crBkgnd = 0;
148 return S_OK;
149 }
150
151 static const int backImageIndex = 0;
152 static const int forwardImageIndex = 1;
153 static const int favoritesImageIndex = 2;
154 // 3
155 // 4
156 static const int cutImageIndex = 5;
157 static const int copyImageIndex = 6;
158 static const int pasteImageIndex = 7;
159 static const int undoImageIndex = 8;
160 //static const int redoImageIndex = 9;
161 static const int deleteImageIndex = 10;
162 // 11
163 // 12
164 // 13
165 // 14
166 static const int propertiesImageIndex = 15;
167 // 16
168 static const int searchImageIndex = 17;
169 // 18
170 // 19
171 // 20
172 // 21
173 static const int viewsImageIndex = 22;
174 // 23
175 // 24
176 // 25
177 // 26
178 // 27
179 static const int upImageIndex = 28;
180 static const int mapDriveImageIndex = 29;
181 static const int disconnectImageIndex = 30;
182 // 31
183 //static const int viewsAltImageIndex = 32; // same image as viewsImageIndex
184 // 33
185 // 34
186 // 35
187 // 36
188 // 37
189 //static const int viewsAlt2ImageIndex = 38; // same image as viewsAltImageIndex & viewsImageIndex
190 // 39
191 // 40
192 // 41
193 // 42
194 static const int foldersImageIndex = 43;
195 static const int moveToImageIndex = 44;
196 static const int copyToImageIndex = 45;
197 static const int folderOptionsImageIndex = 46;
198
199 enum StandardToolbarButtons {
200 BtnIdx_Back = 0,
201 BtnIdx_Forward,
202 BtnIdx_Up,
203 BtnIdx_Search,
204 BtnIdx_Folders,
205 BtnIdx_MoveTo,
206 BtnIdx_CopyTo,
207 BtnIdx_Delete,
208 BtnIdx_Undo,
209 BtnIdx_Views,
210 BtnIdx_Stop,
211 BtnIdx_Refresh,
212 BtnIdx_Home,
213 BtnIdx_MapDrive,
214 BtnIdx_Disconnect,
215 BtnIdx_Favorites,
216 BtnIdx_History,
217 BtnIdx_FullScreen,
218 BtnIdx_Properties,
219 BtnIdx_Cut,
220 BtnIdx_Copy,
221 BtnIdx_Paste,
222 BtnIdx_FolderOptions,
223 };
224
225 const int numShownButtons = 13;
226 const int numHiddenButtons = 13;
227 TBBUTTON tbButtonsAdd[numShownButtons + numHiddenButtons] =
228 {
229 { backImageIndex, IDM_GOTO_BACK, TBSTATE_ENABLED, BTNS_DROPDOWN | BTNS_SHOWTEXT, { 0 }, 0, BtnIdx_Back },
230 { forwardImageIndex, IDM_GOTO_FORWARD, TBSTATE_ENABLED, BTNS_DROPDOWN, { 0 }, 0, BtnIdx_Forward },
231 { upImageIndex, IDM_GOTO_UPONELEVEL, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Up },
232 { 6, -1, TBSTATE_ENABLED, BTNS_SEP },
233 { searchImageIndex, gSearchCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, { 0 }, 0, BtnIdx_Search },
234 { foldersImageIndex, gFoldersCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, { 0 }, 0, BtnIdx_Folders },
235 { 6, -1, TBSTATE_ENABLED, BTNS_SEP },
236 { moveToImageIndex, gMoveToCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_MoveTo },
237 { copyToImageIndex, gCopyToCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_CopyTo },
238 { deleteImageIndex, gDeleteCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Delete },
239 { undoImageIndex, gUndoCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Undo },
240 { 6, -1, TBSTATE_ENABLED, BTNS_SEP },
241 { viewsImageIndex, gViewsCommandID, TBSTATE_ENABLED, BTNS_WHOLEDROPDOWN, { 0 }, 0, BtnIdx_Views },
242
243 { 0, gStopCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Stop },
244 { 0, IDM_VIEW_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Refresh },
245 { 0, gHomeCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Home },
246 { mapDriveImageIndex, IDM_TOOLS_MAPNETWORKDRIVE, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_MapDrive },
247 { disconnectImageIndex, IDM_TOOLS_DISCONNECTNETWORKDRIVE, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Disconnect },
248 { favoritesImageIndex, gFavoritesCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, { 0 }, 0, BtnIdx_Favorites },
249 { 0, gHistoryCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_History },
250 { 0, gFullScreenCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_FullScreen },
251 { propertiesImageIndex, gPropertiesCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Properties },
252 { cutImageIndex, gCutCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Cut },
253 { copyImageIndex, gCopyCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Copy },
254 { pasteImageIndex, gPasteCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Paste },
255 { folderOptionsImageIndex, IDM_TOOLS_FOLDEROPTIONS, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_FolderOptions },
256 };
257
SetSite(IUnknown * pUnkSite)258 HRESULT STDMETHODCALLTYPE CToolsBand::SetSite(IUnknown* pUnkSite){
259 HWND parentWindow;
260 HWND toolbar;
261 HRESULT hResult;
262
263 if(fDockSite) fDockSite.Release();
264
265 if (pUnkSite == NULL)
266 return S_OK;
267 hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &fDockSite));
268 if (FAILED_UNEXPECTEDLY(hResult))
269 return hResult;
270 parentWindow = NULL;
271 hResult = IUnknown_GetWindow(pUnkSite, &parentWindow);
272 if (FAILED(hResult) || !::IsWindow(parentWindow))
273 return E_FAIL;
274
275 toolbar = CreateWindowEx(
276 TBSTYLE_EX_DOUBLEBUFFER,
277 TOOLBARCLASSNAMEW, NULL,
278 WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
279 TBSTYLE_TOOLTIPS | TBSTYLE_TRANSPARENT | TBSTYLE_REGISTERDROP | TBSTYLE_LIST | TBSTYLE_FLAT |
280 CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_TOP,
281 0, 0, 500, 20, parentWindow, NULL, _AtlBaseModule.GetModuleInstance(), 0);
282 if (toolbar == NULL)
283 return E_FAIL;
284 SubclassWindow(toolbar);
285 SendMessage(TB_ADDSTRINGW, (WPARAM) GetModuleHandle(L"browseui.dll"), IDS_STANDARD_TOOLBAR);
286
287 SendMessage(WM_USER + 100, GetSystemMetrics(SM_CXEDGE) / 2, 0);
288 SendMessage(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
289 SendMessage(TB_SETMAXTEXTROWS, 1, 0);
290 SendMessage(TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS | TBSTYLE_EX_MIXEDBUTTONS | TBSTYLE_EX_DRAWDDARROWS);
291
292 m_himlNormal = ImageList_LoadImageW(_AtlBaseModule.GetResourceInstance(),
293 MAKEINTRESOURCEW(IDB_SHELL_EXPLORER_LG),
294 0, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
295
296 m_himlHot = ImageList_LoadImageW(_AtlBaseModule.GetResourceInstance(),
297 MAKEINTRESOURCEW(IDB_SHELL_EXPLORER_LG_HOT),
298 0, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
299
300 SendMessage(TB_SETIMAGELIST, 0, (LPARAM) m_himlNormal);
301 SendMessage(TB_SETHOTIMAGELIST, 0, (LPARAM) m_himlHot);
302 SendMessage(TB_ADDBUTTONSW, numShownButtons, (LPARAM)&tbButtonsAdd);
303
304 return hResult;
305 }
306
GetSite(REFIID riid,void ** ppvSite)307 HRESULT STDMETHODCALLTYPE CToolsBand::GetSite(REFIID riid, void **ppvSite)
308 {
309 if (fDockSite == NULL)
310 return E_FAIL;
311 return fDockSite->QueryInterface(riid, ppvSite);
312 }
313
GetWindow(HWND * lphwnd)314 HRESULT STDMETHODCALLTYPE CToolsBand::GetWindow(HWND *lphwnd)
315 {
316 if (lphwnd == NULL)
317 return E_POINTER;
318 *lphwnd = m_hWnd;
319 return S_OK;
320 }
321
ContextSensitiveHelp(BOOL fEnterMode)322 HRESULT STDMETHODCALLTYPE CToolsBand::ContextSensitiveHelp(BOOL fEnterMode)
323 {
324 return E_NOTIMPL;
325 }
326
CloseDW(DWORD dwReserved)327 HRESULT STDMETHODCALLTYPE CToolsBand::CloseDW(DWORD dwReserved)
328 {
329 ShowDW(FALSE);
330
331 if (IsWindow())
332 DestroyWindow();
333
334 m_hWnd = NULL;
335
336 if (fDockSite)
337 fDockSite.Release();
338
339 if (m_himlNormal)
340 ImageList_Destroy(m_himlNormal);
341
342 if (m_himlHot)
343 ImageList_Destroy(m_himlHot);
344
345 return S_OK;
346 }
347
ResizeBorderDW(const RECT * prcBorder,IUnknown * punkToolbarSite,BOOL fReserved)348 HRESULT STDMETHODCALLTYPE CToolsBand::ResizeBorderDW(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved)
349 {
350 return E_NOTIMPL;
351 }
352
ShowDW(BOOL fShow)353 HRESULT STDMETHODCALLTYPE CToolsBand::ShowDW(BOOL fShow)
354 {
355 if (m_hWnd)
356 {
357 if (fShow)
358 ShowWindow(SW_SHOW);
359 else
360 ShowWindow(SW_HIDE);
361 }
362 return S_OK;
363 }
364
HasFocusIO()365 HRESULT STDMETHODCALLTYPE CToolsBand::HasFocusIO()
366 {
367 return S_FALSE;
368 }
369
TranslateAcceleratorIO(LPMSG lpMsg)370 HRESULT STDMETHODCALLTYPE CToolsBand::TranslateAcceleratorIO(LPMSG lpMsg)
371 {
372 return S_FALSE;
373 }
374
UIActivateIO(BOOL fActivate,LPMSG lpMsg)375 HRESULT STDMETHODCALLTYPE CToolsBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
376 {
377 return E_NOTIMPL;
378 }
379
GetClassID(CLSID * pClassID)380 HRESULT STDMETHODCALLTYPE CToolsBand::GetClassID(CLSID *pClassID)
381 {
382 return E_NOTIMPL;
383 }
384
IsDirty()385 HRESULT STDMETHODCALLTYPE CToolsBand::IsDirty()
386 {
387 return E_NOTIMPL;
388 }
389
Load(IStream * pStm)390 HRESULT STDMETHODCALLTYPE CToolsBand::Load(IStream *pStm)
391 {
392 return E_NOTIMPL;
393 }
394
Save(IStream * pStm,BOOL fClearDirty)395 HRESULT STDMETHODCALLTYPE CToolsBand::Save(IStream *pStm, BOOL fClearDirty)
396 {
397 return E_NOTIMPL;
398 }
399
GetSizeMax(ULARGE_INTEGER * pcbSize)400 HRESULT STDMETHODCALLTYPE CToolsBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
401 {
402 return E_NOTIMPL;
403 }
404
OnGetButtonInfo(UINT idControl,NMHDR * pNMHDR,BOOL & bHandled)405 LRESULT CToolsBand::OnGetButtonInfo(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
406 {
407 TBNOTIFYW *pTBntf = reinterpret_cast<TBNOTIFYW *>(pNMHDR);
408
409 if (pTBntf->iItem >= 0 && pTBntf->iItem < (numShownButtons + numHiddenButtons))
410 {
411 pTBntf->tbButton = tbButtonsAdd[pTBntf->iItem];
412 return TRUE;
413 }
414 else
415 return FALSE;
416 return 0;
417 }
418
CToolsBand_CreateInstance(REFIID riid,void ** ppv)419 HRESULT CToolsBand_CreateInstance(REFIID riid, void **ppv)
420 {
421 return ShellObjectCreator<CToolsBand>(riid, ppv);
422 }
423
424