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 CBandSiteMenu::CBandSiteMenu():
31 CBandSiteMenu::~CBandSiteMenu()
37 DSA_Destroy(m_menuDsa
);
43 HRESULT
CBandSiteMenu::CreateMenuPart()
45 WCHAR wszBandName
[MAX_PATH
];
46 WCHAR wszBandGUID
[MAX_PATH
];
47 WCHAR wRegKey
[MAX_PATH
];
50 CATID category
= CATID_DeskBand
;
53 CComPtr
<IEnumGUID
> pEnumGUID
;
60 DSA_Destroy(m_menuDsa
);
62 /* Load the template we will fill in */
63 m_hmenu
= LoadMenuW(GetModuleHandleW(L
"browseui.dll"), MAKEINTRESOURCEW(IDM_TASKBAR_TOOLBARS
));
65 return HRESULT_FROM_WIN32(GetLastError());
67 m_menuDsa
= DSA_Create(sizeof(GUID
), 5);
71 /* Get the handle of the submenu where the available items will be shown */
72 hmenuToolbars
= GetSubMenu(m_hmenu
, 0);
74 /* Create the category enumerator */
75 hr
= SHEnumClassesOfCategories(1, &category
, 0, NULL
, &pEnumGUID
);
76 if (FAILED_UNEXPECTEDLY(hr
))
79 /* Enumerate the classes in the CATID_DeskBand category */
84 pEnumGUID
->Next(1, &iter
, &dwRead
);
88 if (!StringFromGUID2(iter
, wszBandGUID
, MAX_PATH
))
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
);
97 InsertMenu(hmenuToolbars
, cBands
, MF_BYPOSITION
, DSA_GetItemCount(m_menuDsa
), wszBandName
);
98 DSA_AppendItem(m_menuDsa
, &iter
);
106 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::SetOwner(IUnknown
*pOwner
)
108 TRACE("CBandSiteMenu::SetOwner(%p, %p)\n", this, pOwner
);
110 /* Cache the menu that will be merged every time QueryContextMenu is called */
113 return pOwner
->QueryInterface(IID_PPV_ARG(IBandSite
, &m_BandSite
));
116 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::QueryContextMenu(
117 HMENU hmenu
, UINT indexMenu
, UINT idCmdFirst
, UINT idCmdLast
, UINT uFlags
)
119 CComPtr
<IPersist
> pBand
;
124 TRACE("CBandSiteMenu::QueryContextMenu(%p, %p, %u, %u, %u, 0x%x)\n", this, hmenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
126 /* First Merge the menu with the available bands */
127 Shell_MergeMenus(hmenu
, m_hmenu
, indexMenu
, idCmdFirst
, idCmdLast
, MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
129 HMENU hmenuToolbars
= GetSubMenu(hmenu
, indexMenu
);
131 /* Enumerate all present bands and mark them as checked in the menu */
132 while (SUCCEEDED(m_BandSite
->EnumBands(uBand
, &dwBandID
)))
134 if (FAILED(m_BandSite
->GetBandObject(dwBandID
, IID_PPV_ARG(IPersist
, &pBand
))))
137 if (FAILED(pBand
->GetClassID(&BandCLSID
)))
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
++)
144 GUID
* pdsaGUID
= (GUID
*)DSA_GetItemPtr(m_menuDsa
, i
);
145 if (memcmp(pdsaGUID
, &BandCLSID
, sizeof(GUID
)) == 0)
147 /* The index in the dsa is also the index in the menu */
148 CheckMenuItem(hmenuToolbars
, i
, MF_CHECKED
| MF_BYPOSITION
);
158 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici
)
160 /* FIXME: do we need to handle this and how? */
161 if (HIWORD(lpici
->lpVerb
) != NULL
)
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
);
170 /* Try to find if a band with a guid is present. If it is remove it and return */
171 CComPtr
<IPersist
> pBand
;
175 while (SUCCEEDED(m_BandSite
->EnumBands(uBand
, &dwBandID
)))
177 if (FAILED(m_BandSite
->GetBandObject(dwBandID
, IID_PPV_ARG(IPersist
, &pBand
))))
180 if (FAILED(pBand
->GetClassID(&BandCLSID
)))
183 if (memcmp(pguidToolbar
, &BandCLSID
, sizeof(GUID
)) == 0)
185 /* We found it, remove it */
186 m_BandSite
->RemoveBand(dwBandID
);
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
));
199 hRet
= m_BandSite
->AddBand(pDeskBand
);
200 if (FAILED_UNEXPECTEDLY(hRet
))
206 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::GetCommandString(UINT_PTR idCmd
, UINT uType
,
207 UINT
*pwReserved
, LPSTR pszName
, UINT cchMax
)
209 FIXME("CBandSiteMenu::GetCommandString is UNIMPLEMENTED (%p, %p, %u, %p, %p, %u)\n", this, idCmd
, uType
, pwReserved
, pszName
, cchMax
);
213 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::HandleMenuMsg(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
215 FIXME("CBandSiteMenu::HandleMenuMsg is UNIMPLEMENTED (%p, %u, %p, %p)\n", this, uMsg
, wParam
, lParam
);
219 HRESULT STDMETHODCALLTYPE
CBandSiteMenu::HandleMenuMsg2(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*plResult
)
221 FIXME("CBandSiteMenu::HandleMenuMsg2 is UNIMPLEMENTED(%p, %u, %p, %p, %p)\n", this, uMsg
, wParam
, lParam
, plResult
);
226 HRESULT WINAPI
CBandSiteMenu_CreateInstance(REFIID riid
, void **ppv
)
228 return ShellObjectCreator
<CBandSiteMenu
>(riid
, ppv
);