diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2020-01-22 01:40:56 -0500 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2020-02-04 03:33:21 -0500 |
| commit | 6005da618775d545c664371f53571a75eacab7f2 (patch) | |
| tree | c5cba8758389a557f64c5af0dd8731f042ccbdb6 | |
| parent | a7a406e5538b343d87b3221b13b7bf3503bbfd70 (diff) | |
ShellMenuCollection, events not processed yet
| -rw-r--r-- | src/envshell.cpp | 89 | ||||
| -rw-r--r-- | src/envshell.h | 26 | ||||
| -rw-r--r-- | src/filetree.cpp | 12 |
3 files changed, 109 insertions, 18 deletions
diff --git a/src/envshell.cpp b/src/envshell.cpp index 992ce1ef..58948d31 100644 --- a/src/envshell.cpp +++ b/src/envshell.cpp @@ -237,6 +237,30 @@ private: }; +QMainWindow* getMainWindow(QWidget* w) +{ + QWidget* p = w; + + while (p) { + if (auto* mw=dynamic_cast<QMainWindow*>(p)) { + return mw; + } + + p = p->parentWidget(); + } + + return nullptr; +} + +HWND getHWND(QMainWindow* mw) +{ + if (mw) { + return (HWND)mw->winId(); + } else { + return 0; + } +} + void ShellMenu::addFile(QFileInfo fi) { @@ -351,21 +375,6 @@ HMenuPtr ShellMenu::createDummyMenu(const QString& what) } } -QMainWindow* ShellMenu::getMainWindow(QWidget* w) -{ - QWidget* p = w; - - while (p) { - if (auto* mw=dynamic_cast<QMainWindow*>(p)) { - return mw; - } - - p = p->parentWidget(); - } - - return nullptr; -} - COMPtr<IShellItem> ShellMenu::createShellItem(const std::wstring& path) { IShellItem* item = nullptr; @@ -481,7 +490,7 @@ HMenuPtr ShellMenu::createMenu(IContextMenu* cm) int ShellMenu::runMenu( QMainWindow* mw, IContextMenu* cm, HMENU menu, const QPoint& p) { - const auto hwnd = (HWND)mw->winId(); + const auto hwnd = getHWND(mw); auto filter = std::make_unique<WndProcFilter>(mw, cm); QCoreApplication::instance()->installNativeEventFilter(filter.get()); @@ -492,7 +501,7 @@ int ShellMenu::runMenu( void ShellMenu::invoke( QMainWindow* mw, const QPoint& p, int cmd, IContextMenu* cm) { - const auto hwnd = (HWND)mw->winId(); + const auto hwnd = getHWND(mw); CMINVOKECOMMANDINFOEX info = {}; @@ -523,4 +532,50 @@ void ShellMenu::invoke( } } + +void ShellMenuCollection::add(QString name, ShellMenu m) +{ + m_menus.push_back({name, std::move(m)}); +} + +void ShellMenuCollection::exec(QWidget* parent, const QPoint& pos) +{ + HMENU menu = ::CreatePopupMenu(); + if (!menu) { + const auto e = GetLastError(); + + log::error( + "CreatePopupMenu for merged menus failed, {}", + formatSystemMessage(e)); + + return; + } + + for (auto&& m : m_menus) { + auto hmenu = m.menu.getMenu(); + if (!hmenu) { + continue; + } + + const auto r = AppendMenuW( + menu, MF_POPUP | MF_STRING, + reinterpret_cast<UINT_PTR>(hmenu), m.name.toStdWString().c_str()); + + if (!r) { + const auto e = GetLastError(); + + log::error( + "AppendMenuW failed for merged menu {}, {}", + m.name, formatSystemMessage(e)); + + continue; + } + } + + auto* mw = getMainWindow(parent); + auto hwnd = getHWND(mw); + + TrackPopupMenuEx(menu, TPM_RETURNCMD, pos.x(), pos.y(), hwnd, nullptr); +} + } // namespace diff --git a/src/envshell.h b/src/envshell.h index f25aeda7..79dce552 100644 --- a/src/envshell.h +++ b/src/envshell.h @@ -11,6 +11,14 @@ namespace env class ShellMenu { public: + ShellMenu() = default; + + // noncopyable + ShellMenu(const ShellMenu&) = delete; + ShellMenu& operator=(const ShellMenu&) = delete; + ShellMenu(ShellMenu&&) = default; + ShellMenu& operator=(ShellMenu&&) = default; + void addFile(QFileInfo fi); void exec(QWidget* parent, const QPoint& pos); @@ -23,7 +31,6 @@ private: void createMenu(); - QMainWindow* getMainWindow(QWidget* w); COMPtr<IShellItem> createShellItem(const std::wstring& path); COMPtr<IPersistIDList> getPersistIDList(IShellItem* item); CoTaskMemPtr<LPITEMIDLIST> getIDList(IPersistIDList* pidlist); @@ -37,6 +44,23 @@ private: void invoke(QMainWindow* mw, const QPoint& p, int cmd, IContextMenu* cm); }; + +class ShellMenuCollection +{ +public: + void add(QString name, ShellMenu m); + void exec(QWidget* parent, const QPoint& pos); + +private: + struct MenuInfo + { + QString name; + ShellMenu menu; + }; + + std::vector<MenuInfo> m_menus; +}; + } // namespace #endif // ENV_SHELL_H diff --git a/src/filetree.cpp b/src/filetree.cpp index 7128665d..543be82b 100644 --- a/src/filetree.cpp +++ b/src/filetree.cpp @@ -540,7 +540,19 @@ void FileTree::showShellMenu(QPoint pos) auto& menu = menus.begin()->second; menu.exec(m_tree, m_tree->viewport()->mapToGlobal(pos)); } else { + env::ShellMenuCollection mc; + for (auto&& m : menus) { + const auto* origin = m_core.directoryStructure()->findOriginByID(m.first); + if (!origin) { + log::error("origin {} not found for merged menus", m.first); + continue; + } + + mc.add(QString::fromStdWString(origin->getName()), std::move(m.second)); + } + + mc.exec(m_tree, m_tree->viewport()->mapToGlobal(pos)); } } |
