xref: /reactos/dll/win32/browseui/toolsband.cpp (revision 8a978a17)
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     virtual HRESULT STDMETHODCALLTYPE GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi);
45 
46     // *** IObjectWithSite methods ***
47     virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown* pUnkSite);
48     virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite);
49 
50     // *** IOleWindow methods ***
51     virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
52     virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
53 
54     // *** IDockingWindow methods ***
55     virtual HRESULT STDMETHODCALLTYPE CloseDW(DWORD dwReserved);
56     virtual HRESULT STDMETHODCALLTYPE ResizeBorderDW(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved);
57     virtual HRESULT STDMETHODCALLTYPE ShowDW(BOOL fShow);
58 
59     // *** IInputObject methods ***
60     virtual HRESULT STDMETHODCALLTYPE HasFocusIO();
61     virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO(LPMSG lpMsg);
62     virtual HRESULT STDMETHODCALLTYPE UIActivateIO(BOOL fActivate, LPMSG lpMsg);
63 
64     // *** IPersist methods ***
65     virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
66 
67     // *** IPersistStream methods ***
68     virtual HRESULT STDMETHODCALLTYPE IsDirty();
69     virtual HRESULT STDMETHODCALLTYPE Load(IStream *pStm);
70     virtual HRESULT STDMETHODCALLTYPE Save(IStream *pStm, BOOL fClearDirty);
71     virtual HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize);
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 
93 CToolsBand::CToolsBand()
94     : fDockSite(NULL)
95 {
96 }
97 
98 CToolsBand::~CToolsBand()
99 {
100 }
101 
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 
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 
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 
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 
322 HRESULT STDMETHODCALLTYPE CToolsBand::ContextSensitiveHelp(BOOL fEnterMode)
323 {
324     return E_NOTIMPL;
325 }
326 
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 
348 HRESULT STDMETHODCALLTYPE CToolsBand::ResizeBorderDW(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved)
349 {
350     return E_NOTIMPL;
351 }
352 
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 
365 HRESULT STDMETHODCALLTYPE CToolsBand::HasFocusIO()
366 {
367     return S_FALSE;
368 }
369 
370 HRESULT STDMETHODCALLTYPE CToolsBand::TranslateAcceleratorIO(LPMSG lpMsg)
371 {
372     return S_FALSE;
373 }
374 
375 HRESULT STDMETHODCALLTYPE CToolsBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
376 {
377     return E_NOTIMPL;
378 }
379 
380 HRESULT STDMETHODCALLTYPE CToolsBand::GetClassID(CLSID *pClassID)
381 {
382     return E_NOTIMPL;
383 }
384 
385 HRESULT STDMETHODCALLTYPE CToolsBand::IsDirty()
386 {
387     return E_NOTIMPL;
388 }
389 
390 HRESULT STDMETHODCALLTYPE CToolsBand::Load(IStream *pStm)
391 {
392     return E_NOTIMPL;
393 }
394 
395 HRESULT STDMETHODCALLTYPE CToolsBand::Save(IStream *pStm, BOOL fClearDirty)
396 {
397     return E_NOTIMPL;
398 }
399 
400 HRESULT STDMETHODCALLTYPE CToolsBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
401 {
402     return E_NOTIMPL;
403 }
404 
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 
419 HRESULT CToolsBand_CreateInstance(REFIID riid, void **ppv)
420 {
421     return ShellObjectCreator<CToolsBand>(riid, ppv);
422 }
423 
424