4 * Copyright 2007 Hervé Poussineua
5 * Copyright 2009 Andrew Hill
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.
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.
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
22 #include "shellbars.h"
25 #define IDM_DESKBAND_BEGINCUSTOM 0x10
26 #define IDM_DESKBAND_ENDCUSTOM 0x25
28 CBandSiteMenu::CBandSiteMenu():
34 CBandSiteMenu::~CBandSiteMenu()
40 DSA_Destroy(m_menuDsa
);
46 HRESULT
CBandSiteMenu::CreateMenuPart()
48 WCHAR wszBandName
[MAX_PATH
];
49 WCHAR wszBandGUID
[MAX_PATH
];
50 WCHAR wRegKey
[MAX_PATH
];
53 CATID category
= CATID_DeskBand
;
56 CComPtr
<IEnumGUID
> pEnumGUID
;
63 DSA_Destroy(m_menuDsa
);
65 /* Load the template we will fill in */
66 m_hmenu
= LoadMenuW(GetModuleHandleW(L
"browseui.dll"), MAKEINTRESOURCEW(IDM_TASKBAR_TOOLBARS
));
68 return HRESULT_FROM_WIN32(GetLastError());
70 m_menuDsa
= DSA_Create(sizeof(GUID
), 5);
74 /* Get the handle of the submenu where the available items will be shown */
75 hmenuToolbars
= GetSubMenu(m_hmenu
, 0);
77 /* Create the category enumerator */
78 hr
= SHEnumClassesOfCategories(1, &category
, 0, NULL
, &pEnumGUID
);
79 if (FAILED_UNEXPECTEDLY(hr
))
82 /* Enumerate the classes in the CATID_DeskBand category */
87 pEnumGUID
->Next(1, &iter
, &dwRead
);
91 if (!StringFromGUID2(iter
, wszBandGUID
, MAX_PATH
))
94 /* Get the band name */
95 StringCchPrintfW(wRegKey
, MAX_PATH
, L
"CLSID\\%s", wszBandGUID
);
96 dwDataSize
= MAX_PATH
;
97 SHGetValue(HKEY_CLASSES_ROOT
, wRegKey
, NULL
, NULL
, wszBandName
, &dwDataSize
);
100 InsertMenu(hmenuToolbars
, cBands
, MF_BYPOSITION
, DSA_GetItemCount(m_menuDsa
), wszBandName
);
101 DSA_AppendItem(m_menuDsa
, &iter
);
109 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::SetOwner(IUnknown
*pOwner
)
111 TRACE("CBandSiteMenu::SetOwner(%p, %p)\n", this, pOwner
);
113 /* Cache the menu that will be merged every time QueryContextMenu is called */
116 return pOwner
->QueryInterface(IID_PPV_ARG(IBandSite
, &m_BandSite
));
119 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::QueryContextMenu(
120 HMENU hmenu
, UINT indexMenu
, UINT idCmdFirst
, UINT idCmdLast
, UINT uFlags
)
122 CComPtr
<IPersist
> pBand
;
127 TRACE("CBandSiteMenu::QueryContextMenu(%p, %p, %u, %u, %u, 0x%x)\n", this, hmenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
129 /* First Merge the menu with the available bands */
130 Shell_MergeMenus(hmenu
, m_hmenu
, indexMenu
, idCmdFirst
, idCmdLast
, MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
132 HMENU hmenuToolbars
= GetSubMenu(hmenu
, indexMenu
);
134 /* Enumerate all present bands and mark them as checked in the menu */
135 while (SUCCEEDED(m_BandSite
->EnumBands(uBand
, &dwBandID
)))
137 if (FAILED(m_BandSite
->GetBandObject(dwBandID
, IID_PPV_ARG(IPersist
, &pBand
))))
140 if (FAILED(pBand
->GetClassID(&BandCLSID
)))
143 /* Try to find the clsid of the band in the dsa */
144 UINT count
= DSA_GetItemCount(m_menuDsa
);
145 for (UINT i
= 0; i
< count
; i
++)
147 GUID
* pdsaGUID
= (GUID
*)DSA_GetItemPtr(m_menuDsa
, i
);
148 if (memcmp(pdsaGUID
, &BandCLSID
, sizeof(GUID
)) == 0)
150 /* The index in the dsa is also the index in the menu */
151 CheckMenuItem(hmenuToolbars
, i
, MF_CHECKED
| MF_BYPOSITION
);
161 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici
)
163 /* FIXME: do we need to handle this and how? */
164 if (HIWORD(lpici
->lpVerb
) != NULL
)
167 /* Get the GUID of the item that was clicked */
168 UINT uID
= LOWORD(lpici
->lpVerb
);
169 GUID
*pguidToolbar
= (GUID
*)DSA_GetItemPtr(m_menuDsa
, uID
);
173 /* Try to find if a band with a guid is present. If it is remove it and return */
174 CComPtr
<IPersist
> pBand
;
178 while (SUCCEEDED(m_BandSite
->EnumBands(uBand
, &dwBandID
)))
180 if (FAILED(m_BandSite
->GetBandObject(dwBandID
, IID_PPV_ARG(IPersist
, &pBand
))))
183 if (FAILED(pBand
->GetClassID(&BandCLSID
)))
186 if (memcmp(pguidToolbar
, &BandCLSID
, sizeof(GUID
)) == 0)
188 /* We found it, remove it */
189 m_BandSite
->RemoveBand(dwBandID
);
196 /* It is not present. Add it. */
197 CComPtr
<IDeskBand
> pDeskBand
;
198 HRESULT hRet
= CoCreateInstance(*pguidToolbar
, NULL
, CLSCTX_INPROC_SERVER
, IID_PPV_ARG(IDeskBand
, &pDeskBand
));
202 hRet
= m_BandSite
->AddBand(pDeskBand
);
203 if (FAILED_UNEXPECTEDLY(hRet
))
209 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::GetCommandString(UINT_PTR idCmd
, UINT uType
,
210 UINT
*pwReserved
, LPSTR pszName
, UINT cchMax
)
212 FIXME("CBandSiteMenu::GetCommandString is UNIMPLEMENTED (%p, %p, %u, %p, %p, %u)\n", this, idCmd
, uType
, pwReserved
, pszName
, cchMax
);
216 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::HandleMenuMsg(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
218 FIXME("CBandSiteMenu::HandleMenuMsg is UNIMPLEMENTED (%p, %u, %p, %p)\n", this, uMsg
, wParam
, lParam
);
222 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::HandleMenuMsg2(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*plResult
)
224 FIXME("CBandSiteMenu::HandleMenuMsg2 is UNIMPLEMENTED(%p, %u, %p, %p, %p)\n", this, uMsg
, wParam
, lParam
, plResult
);
229 HRESULT WINAPI
CBandSiteMenu_CreateInstance(REFIID riid
, void **ppv
)
231 return ShellObjectCreator
<CBandSiteMenu
>(riid
, ppv
);