+LPITEMIDLIST CMenuSFToolbar::GetPidlFromId(UINT uItem, INT* pIndex)
+{
+ TBBUTTONINFO info = { 0 };
+ info.cbSize = sizeof(TBBUTTONINFO);
+ info.dwMask = 0;
+ int index = SendMessage(m_hwndToolbar, TB_GETBUTTONINFO, uItem, reinterpret_cast<LPARAM>(&info));
+ if (index < 0)
+ return NULL;
+
+ if (pIndex)
+ *pIndex = index;
+
+ TBBUTTON btn = { 0 };
+ if (!SendMessage(m_hwndToolbar, TB_GETBUTTON, index, reinterpret_cast<LPARAM>(&btn)))
+ return NULL;
+
+ return reinterpret_cast<LPITEMIDLIST>(btn.dwData);
+}
+
+HRESULT CMenuSFToolbar::OnContextMenu(NMMOUSE * rclick)
+{
+ HRESULT hr;
+ CComPtr<IContextMenu> contextMenu;
+ LPCITEMIDLIST pidl = reinterpret_cast<LPCITEMIDLIST>(rclick->dwItemData);
+
+ hr = m_shellFolder->GetUIObjectOf(m_hwndToolbar, 1, &pidl, IID_IContextMenu, NULL, reinterpret_cast<VOID **>(&contextMenu));
+ if (hr != S_OK)
+ return hr;
+
+ return DoContextMenu(contextMenu);
+}
+
+HRESULT CMenuSFToolbar::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult)
+{
+ HRESULT hr;
+ hr = CMenuToolbarBase::OnCommand(wParam, lParam, theResult);
+ if (FAILED(hr))
+ return hr;
+
+ // in case the clicked item has a submenu, we do not need to execute the item
+ if (hr == S_FALSE)
+ return hr;
+
+ return m_menuBand->_CallCBWithItemPidl(GetPidlFromId(wParam), SMC_SFEXEC, 0, 0);
+}
+
+HRESULT CMenuSFToolbar::PopupItem(UINT uItem)
+{
+ HRESULT hr;
+ UINT uId;
+ UINT uIdAncestor;
+ DWORD flags;
+ int index;
+ CComPtr<IShellMenuCallback> psmc;
+ CComPtr<IShellMenu> shellMenu;
+
+ LPITEMIDLIST pidl = GetPidlFromId(uItem, &index);
+
+ if (!pidl)
+ return E_FAIL;
+
+#if USE_SYSTEM_MENUBAND
+ hr = CoCreateInstance(CLSID_MenuBand,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_PPV_ARG(IShellMenu, &shellMenu));
+#else
+ hr = CMenuBand_Constructor(IID_PPV_ARG(IShellMenu, &shellMenu));
+#endif
+ if (FAILED(hr))
+ return hr;
+#if WRAP_MENUBAND
+ hr = CMenuBand_Wrapper(shellMenu, IID_PPV_ARG(IShellMenu, &shellMenu));
+ if (FAILED(hr))
+ return hr;
+#endif
+
+ m_menuBand->GetMenuInfo(&psmc, &uId, &uIdAncestor, &flags);
+
+ // FIXME: not sure what to use as uId/uIdAncestor here
+ hr = shellMenu->Initialize(psmc, 0, uId, SMINIT_VERTICAL);
+ if (FAILED(hr))
+ return hr;
+
+ CComPtr<IShellFolder> childFolder;
+ hr = m_shellFolder->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &childFolder));
+ if (FAILED(hr))
+ return hr;
+
+ hr = shellMenu->SetShellFolder(childFolder, NULL, NULL, 0);
+ if (FAILED(hr))
+ return hr;
+
+ return PopupSubMenu(uItem, index, shellMenu);
+}
+
+HRESULT CMenuSFToolbar::HasSubMenu(UINT uItem)
+{
+ HRESULT hr;
+ CComPtr<IShellItem> psi;
+ hr = SHCreateShellItem(NULL, m_shellFolder, GetPidlFromId(uItem), &psi);
+ if (FAILED(hr))
+ return S_FALSE;
+
+ SFGAOF attrs;
+ hr = psi->GetAttributes(SFGAO_FOLDER, &attrs);
+ if (FAILED(hr))
+ return hr;
+
+ return (attrs != 0) ? S_OK : S_FALSE;
+}
+