[BROWSEUI] -Remove a couple of lines that shouldn't have been committed.
[reactos.git] / reactos / dll / win32 / browseui / shellbars / CBandSiteMenu.cpp
1 /*
2 * Band site menu
3 *
4 * Copyright 2007 Hervé Poussineua
5 * Copyright 2009 Andrew Hill
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "shellbars.h"
23 #include <strsafe.h>
24
25 CBandSiteMenu::CBandSiteMenu():
26 m_menuDsa(NULL),
27 m_hmenu(NULL)
28 {
29 }
30
31 CBandSiteMenu::~CBandSiteMenu()
32 {
33 if (m_hmenu)
34 DestroyMenu(m_hmenu);
35
36 if (m_menuDsa)
37 DSA_Destroy(m_menuDsa);
38
39 m_BandSite = NULL;
40 }
41
42
43 HRESULT CBandSiteMenu::CreateMenuPart()
44 {
45 WCHAR wszBandName[MAX_PATH];
46 WCHAR wszBandGUID[MAX_PATH];
47 WCHAR wRegKey[MAX_PATH];
48 UINT cBands;
49 DWORD dwDataSize;
50 CATID category = CATID_DeskBand;
51 HMENU hmenuToolbars;
52 DWORD dwRead;
53 CComPtr<IEnumGUID> pEnumGUID;
54 HRESULT hr;
55
56 if (m_hmenu)
57 DestroyMenu(m_hmenu);
58
59 if (m_menuDsa)
60 DSA_Destroy(m_menuDsa);
61
62 /* Load the template we will fill in */
63 m_hmenu = LoadMenuW(GetModuleHandleW(L"browseui.dll"), MAKEINTRESOURCEW(IDM_TASKBAR_TOOLBARS));
64 if (!m_hmenu)
65 return HRESULT_FROM_WIN32(GetLastError());
66
67 m_menuDsa = DSA_Create(sizeof(GUID), 5);
68 if (!m_menuDsa)
69 return E_OUTOFMEMORY;
70
71 /* Get the handle of the submenu where the available items will be shown */
72 hmenuToolbars = GetSubMenu(m_hmenu, 0);
73
74 /* Create the category enumerator */
75 hr = SHEnumClassesOfCategories(1, &category, 0, NULL, &pEnumGUID);
76 if (FAILED_UNEXPECTEDLY(hr))
77 return hr;
78
79 /* Enumerate the classes in the CATID_DeskBand category */
80 cBands = 0;
81 do
82 {
83 GUID iter;
84 pEnumGUID->Next(1, &iter, &dwRead);
85 if (!dwRead)
86 continue;
87
88 if (!StringFromGUID2(iter, wszBandGUID, MAX_PATH))
89 continue;
90
91 /* Get the band name */
92 StringCchPrintfW(wRegKey, MAX_PATH, L"CLSID\\%s", wszBandGUID);
93 dwDataSize = MAX_PATH;
94 SHGetValue(HKEY_CLASSES_ROOT, wRegKey, NULL, NULL, wszBandName, &dwDataSize);
95
96 /* Insert it */
97 InsertMenu(hmenuToolbars, cBands, MF_BYPOSITION, DSA_GetItemCount(m_menuDsa), wszBandName);
98 DSA_AppendItem(m_menuDsa, &iter);
99 cBands++;
100 }
101 while (dwRead > 0);
102
103 return S_OK;
104 }
105
106 HRESULT STDMETHODCALLTYPE CBandSiteMenu::SetOwner(IUnknown *pOwner)
107 {
108 TRACE("CBandSiteMenu::SetOwner(%p, %p)\n", this, pOwner);
109
110 /* Cache the menu that will be merged every time QueryContextMenu is called */
111 CreateMenuPart();
112
113 return pOwner->QueryInterface(IID_PPV_ARG(IBandSite, &m_BandSite));
114 }
115
116 HRESULT STDMETHODCALLTYPE CBandSiteMenu::QueryContextMenu(
117 HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
118 {
119 CComPtr<IPersist> pBand;
120 CLSID BandCLSID;
121 DWORD dwBandID;
122 UINT uBand = 0;
123
124 TRACE("CBandSiteMenu::QueryContextMenu(%p, %p, %u, %u, %u, 0x%x)\n", this, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
125
126 /* First Merge the menu with the available bands */
127 Shell_MergeMenus(hmenu, m_hmenu, indexMenu, idCmdFirst, idCmdLast, MM_DONTREMOVESEPS | MM_SUBMENUSHAVEIDS);
128
129 HMENU hmenuToolbars = GetSubMenu(hmenu, indexMenu);
130
131 /* Enumerate all present bands and mark them as checked in the menu */
132 while (SUCCEEDED(m_BandSite->EnumBands(uBand, &dwBandID)))
133 {
134 if (FAILED(m_BandSite->GetBandObject(dwBandID, IID_PPV_ARG(IPersist, &pBand))))
135 continue;
136
137 if (FAILED(pBand->GetClassID(&BandCLSID)))
138 continue;
139
140 /* Try to find the clsid of the band in the dsa */
141 UINT count = DSA_GetItemCount(m_menuDsa);
142 for (UINT i = 0; i < count; i++)
143 {
144 GUID* pdsaGUID = (GUID*)DSA_GetItemPtr(m_menuDsa, i);
145 if (memcmp(pdsaGUID, &BandCLSID, sizeof(GUID)) == 0)
146 {
147 /* The index in the dsa is also the index in the menu */
148 CheckMenuItem(hmenuToolbars, i, MF_CHECKED | MF_BYPOSITION);
149 }
150 }
151
152 uBand++;
153 }
154
155 return S_OK;
156 }
157
158 HRESULT STDMETHODCALLTYPE CBandSiteMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
159 {
160 /* FIXME: do we need to handle this and how? */
161 if (HIWORD(lpici->lpVerb) != NULL)
162 return E_FAIL;
163
164 /* Get the GUID of the item that was clicked */
165 UINT uID = LOWORD(lpici->lpVerb);
166 GUID *pguidToolbar = (GUID *)DSA_GetItemPtr(m_menuDsa, uID);
167 if (!pguidToolbar)
168 return E_FAIL;
169
170 /* Try to find if a band with a guid is present. If it is remove it and return */
171 CComPtr<IPersist> pBand;
172 CLSID BandCLSID;
173 DWORD dwBandID;
174 UINT uBand = 0;
175 while (SUCCEEDED(m_BandSite->EnumBands(uBand, &dwBandID)))
176 {
177 if (FAILED(m_BandSite->GetBandObject(dwBandID, IID_PPV_ARG(IPersist, &pBand))))
178 continue;
179
180 if (FAILED(pBand->GetClassID(&BandCLSID)))
181 continue;
182
183 if (memcmp(pguidToolbar, &BandCLSID, sizeof(GUID)) == 0)
184 {
185 /* We found it, remove it */
186 m_BandSite->RemoveBand(dwBandID);
187 return S_OK;
188 }
189
190 uBand++;
191 }
192
193 /* It is not present. Add it. */
194 CComPtr<IDeskBand> pDeskBand;
195 HRESULT hRet = CoCreateInstance(*pguidToolbar, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IDeskBand, &pDeskBand));
196 if (FAILED(hRet))
197 return hRet;
198
199 hRet = m_BandSite->AddBand(pDeskBand);
200 if (FAILED_UNEXPECTEDLY(hRet))
201 return hRet;
202
203 return S_OK;
204 }
205
206 HRESULT STDMETHODCALLTYPE CBandSiteMenu::GetCommandString(UINT_PTR idCmd, UINT uType,
207 UINT *pwReserved, LPSTR pszName, UINT cchMax)
208 {
209 FIXME("CBandSiteMenu::GetCommandString is UNIMPLEMENTED (%p, %p, %u, %p, %p, %u)\n", this, idCmd, uType, pwReserved, pszName, cchMax);
210 return E_NOTIMPL;
211 }
212
213 HRESULT STDMETHODCALLTYPE CBandSiteMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
214 {
215 FIXME("CBandSiteMenu::HandleMenuMsg is UNIMPLEMENTED (%p, %u, %p, %p)\n", this, uMsg, wParam, lParam);
216 return E_NOTIMPL;
217 }
218
219 HRESULT STDMETHODCALLTYPE CBandSiteMenu::HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
220 {
221 FIXME("CBandSiteMenu::HandleMenuMsg2 is UNIMPLEMENTED(%p, %u, %p, %p, %p)\n", this, uMsg, wParam, lParam, plResult);
222 return E_NOTIMPL;
223 }
224
225 extern "C"
226 HRESULT WINAPI CBandSiteMenu_CreateInstance(REFIID riid, void **ppv)
227 {
228 return ShellObjectCreator<CBandSiteMenu>(riid, ppv);
229 }