owner drawn context menus for lean explorer version Modified: branches/lean-explorer/reactos/subsys/system/explorer/desktop/desktop.cp p Modified: branches/lean-explorer/reactos/subsys/system/explorer/desktop/desktop.h Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/mainframe.cp p Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/mainframe.h Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser .cpp Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser .h Modified: branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass es.cpp Modified: branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass es.h Modified: trunk/reactos/subsys/system/explorer/desktop/desktop.cpp Modified: trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp _____
Modified: branches/lean-explorer/reactos/subsys/system/explorer/desktop/desktop.cp p --- branches/lean-explorer/reactos/subsys/system/explorer/desktop/desktop.cp p 2005-02-06 13:28:34 UTC (rev 13439) +++ branches/lean-explorer/reactos/subsys/system/explorer/desktop/desktop.cp p 2005-02-06 14:03:25 UTC (rev 13440) @@ -439,11 +439,11 @@
return true; }
-LRESULT DesktopShellView::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) +LRESULT DesktopShellView::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { switch(nmsg) { case WM_CONTEXTMENU: - if (!DoContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam))) + if (!DoContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam), _cm_ifs)) DoDesktopContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)); break;
@@ -467,7 +467,7 @@ return super::Notify(id, pnmh); }
-bool DesktopShellView::DoContextMenu(int x, int y) +bool DesktopShellView::DoContextMenu(int x, int y, CtxMenuInterfaces& cm_ifs) { IDataObject* selection;
@@ -497,7 +497,7 @@ for(int i=pida->cidl; i>0; --i) apidl[i-1] = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[i]);
- hr = ShellFolderContextMenu(ShellFolder(parent_pidl), _hwnd, pida->cidl, apidl, x, y); + hr = ShellFolderContextMenu(ShellFolder(parent_pidl), _hwnd, pida->cidl, apidl, x, y, cm_ifs);
selection->Release();
@@ -513,6 +513,8 @@ HRESULT hr = DesktopFolder()->GetUIObjectOf(_hwnd, 0, NULL, IID_IContextMenu, NULL, (LPVOID*)&pcm);
if (SUCCEEDED(hr)) { + pcm = _cm_ifs.query_interfaces(pcm); + HMENU hmenu = CreatePopupMenu();
if (hmenu) { @@ -524,6 +526,8 @@
UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, _hwnd, NULL);
+ _cm_ifs.reset(); + if (idCmd == FCIDM_SHVIEWLAST-1) { explorer_about(_hwnd); } else if (idCmd) { _____
Modified: branches/lean-explorer/reactos/subsys/system/explorer/desktop/desktop.h --- branches/lean-explorer/reactos/subsys/system/explorer/desktop/desktop.h 2005-02-06 13:28:34 UTC (rev 13439) +++ branches/lean-explorer/reactos/subsys/system/explorer/desktop/desktop.h 2005-02-06 14:03:25 UTC (rev 13440) @@ -163,9 +163,9 @@
/// subclassed ShellView window -struct DesktopShellView : public SubclassedWindow +struct DesktopShellView : public ExtContextMenuHandlerT<SubclassedWindow> { - typedef SubclassedWindow super; + typedef ExtContextMenuHandlerT<SubclassedWindow> super;
DesktopShellView(HWND hwnd, IShellView* pShellView);
@@ -178,7 +178,7 @@ int Command(int id, int code); int Notify(int id, NMHDR* pnmh);
- bool DoContextMenu(int x, int y); + bool DoContextMenu(int x, int y, CtxMenuInterfaces& cm_ifs); HRESULT DoDesktopContextMenu(int x, int y);
DesktopDropTarget* _pDropTarget; _____
Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/mainframe.cp p --- branches/lean-explorer/reactos/subsys/system/explorer/shell/mainframe.cp p 2005-02-06 13:28:34 UTC (rev 13439) +++ branches/lean-explorer/reactos/subsys/system/explorer/shell/mainframe.cp p 2005-02-06 14:03:25 UTC (rev 13440) @@ -103,7 +103,7 @@
} }
- _shellBrowser = auto_ptr<ShellBrowserChild>(new ShellBrowserChild(_hwnd, _left_hwnd, _right_hwnd, _create_info)); + _shellBrowser = auto_ptr<ShellBrowserChild>(new ShellBrowserChild(_hwnd, _left_hwnd, _right_hwnd, _create_info, _cm_ifs));
// update _shellBrowser->_clnt_rect ClientRect rect(_hwnd); _____
Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/mainframe.h --- branches/lean-explorer/reactos/subsys/system/explorer/shell/mainframe.h 2005-02-06 13:28:34 UTC (rev 13439) +++ branches/lean-explorer/reactos/subsys/system/explorer/shell/mainframe.h 2005-02-06 14:03:25 UTC (rev 13440) @@ -31,9 +31,9 @@
/// Explorer frame window -struct MainFrame : public PreTranslateWindow +struct MainFrame : public ExtContextMenuHandlerT<PreTranslateWindow> { - typedef PreTranslateWindow super; + typedef ExtContextMenuHandlerT<PreTranslateWindow> super;
MainFrame(HWND hwnd); ~MainFrame(); _____
Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser .cpp --- branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser .cpp 2005-02-06 13:28:34 UTC (rev 13439) +++ branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser .cpp 2005-02-06 14:03:25 UTC (rev 13440) @@ -45,11 +45,13 @@
}
-ShellBrowserChild::ShellBrowserChild(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info) +ShellBrowserChild::ShellBrowserChild(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, + ShellPathInfo& create_info, CtxMenuInterfaces& cm_ifs) : _hwnd(hwnd), _left_hwnd(left_hwnd), _right_hwnd(right_hwnd), - _create_info(create_info) + _create_info(create_info), + _cm_ifs(_cm_ifs) { _pShellView = NULL; _pDropTarget = NULL; @@ -212,13 +214,13 @@ ShellFolder folder = dir? dir->_folder: GetDesktopFolder(); LPCITEMIDLIST pidl = static_cast<ShellEntry*>(entry)->_pidl;
- CHECKERROR(ShellFolderContextMenu(folder, ::GetParent(hwndTreeView), 1, &pidl, pptScreen->x, pptScreen->y)); + CHECKERROR(ShellFolderContextMenu(folder, ::GetParent(hwndTreeView), 1, &pidl, pptScreen->x, pptScreen->y, _cm_ifs)); } else { ShellPath shell_path = entry->create_absolute_pidl(); LPCITEMIDLIST pidl = shell_path;
///@todo use parent folder instead of desktop - CHECKERROR(ShellFolderContextMenu(GetDesktopFolder(), _hwnd, 1, &pidl, pptScreen->x, pptScreen->y)); + CHECKERROR(ShellFolderContextMenu(GetDesktopFolder(), _hwnd, 1, &pidl, pptScreen->x, pptScreen->y, _cm_ifs)); } } } @@ -229,6 +231,8 @@
LPNMTVDISPINFO lpdi = (LPNMTVDISPINFO)pnmh; ShellEntry* entry = (ShellEntry*)lpdi->item.lParam; + if (!entry) + return;
if (lpdi->item.mask & TVIF_TEXT) lpdi->item.pszText = entry->_display_name; _____
Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser .h --- branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser .h 2005-02-06 13:28:34 UTC (rev 13439) +++ branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser .h 2005-02-06 14:03:25 UTC (rev 13440) @@ -44,7 +44,8 @@
/// Implementation of IShellBrowserImpl interface in explorer child windows struct ShellBrowserChild : public IShellBrowserImpl { - ShellBrowserChild(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info); + ShellBrowserChild(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, + ShellPathInfo& create_info, CtxMenuInterfaces& cm_ifs); virtual ~ShellBrowserChild();
//IOleWindow @@ -152,4 +153,5 @@
protected: ShellDirectory* _cur_dir; + CtxMenuInterfaces& _cm_ifs; }; _____
Modified: branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass es.cpp --- branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass es.cpp 2005-02-06 13:28:34 UTC (rev 13439) +++ branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass es.cpp 2005-02-06 14:03:25 UTC (rev 13440) @@ -1,5 +1,5 @@
/* - * Copyright 2003, 2004 Martin Fuchs + * Copyright 2003, 2004, 2005 Martin Fuchs * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -468,14 +468,65 @@ }
-HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, LPCITEMIDLIST* apidl, int x, int y) +void CtxMenuInterfaces::reset() { + _pctxmenu2 = NULL; + +#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) + _pctxmenu3 = NULL; +#endif +} + +bool CtxMenuInterfaces::HandleMenuMsg(UINT nmsg, WPARAM wparam, LPARAM lparam) +{ +#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) + if (_pctxmenu3) { + if (SUCCEEDED(_pctxmenu3->HandleMenuMsg(nmsg, wparam, lparam))) + return true; + } +#endif + + if (_pctxmenu2) + if (SUCCEEDED(_pctxmenu2->HandleMenuMsg(nmsg, wparam, lparam))) + return true; + + return false; +} + +IContextMenu* CtxMenuInterfaces::query_interfaces(IContextMenu* pcm1) +{ + IContextMenu* pcm = NULL; + + reset(); + + // Get the higher version context menu interfaces. +#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) + if (pcm1->QueryInterface(IID_IContextMenu3, (void**)&pcm) == NOERROR) + _pctxmenu3 = (LPCONTEXTMENU3)pcm; + else +#endif + if (pcm1->QueryInterface (IID_IContextMenu2, (void**)&pcm) == NOERROR) + _pctxmenu2 = (LPCONTEXTMENU2)pcm; + + if (pcm) { + pcm1->Release(); + return pcm; + } else + return pcm1; +} + + +HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, + LPCITEMIDLIST* apidl, int x, int y, CtxMenuInterfaces& cm_ifs) +{ IContextMenu* pcm;
HRESULT hr = shell_folder->GetUIObjectOf(hwndParent, cidl, apidl, IID_IContextMenu, NULL, (LPVOID*)&pcm); // HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm);
if (SUCCEEDED(hr)) { + pcm = cm_ifs.query_interfaces(pcm); + HMENU hmenu = CreatePopupMenu();
if (hmenu) { @@ -484,6 +535,8 @@ if (SUCCEEDED(hr)) { UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, hwndParent, NULL);
+ cm_ifs.reset(); + if (idCmd) { CMINVOKECOMMANDINFO cmi;
_____
Modified: branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass es.h --- branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass es.h 2005-02-06 13:28:34 UTC (rev 13439) +++ branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass es.h 2005-02-06 14:03:25 UTC (rev 13440) @@ -1,5 +1,5 @@
/* - * Copyright 2003, 2004 Martin Fuchs + * Copyright 2003, 2004, 2005 Martin Fuchs * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1007,4 +1007,77 @@ LPIDA _pIDList; };
-extern HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, LPCITEMIDLIST* ppidl, int x, int y); + +struct CtxMenuInterfaces +{ + CtxMenuInterfaces() + { + reset(); + } + + void reset(); + bool HandleMenuMsg(UINT nmsg, WPARAM wparam, LPARAM lparam); + IContextMenu* query_interfaces(IContextMenu* pcm1); + + IContextMenu2* _pctxmenu2; + +#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) + IContextMenu3* _pctxmenu3; +#endif +}; + +template<typename BASE> struct ExtContextMenuHandlerT + : public BASE +{ + typedef BASE super; + + ExtContextMenuHandlerT(HWND hwnd) + : super(hwnd) + { + } + + template<typename PARA> ExtContextMenuHandlerT(HWND hwnd, const PARA& info) + : super(hwnd, info) + { + } + + LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) + { + switch(nmsg) { + case WM_DRAWITEM: + case WM_MEASUREITEM: + if (!wparam) // Is the message menu-related? + if (_cm_ifs.HandleMenuMsg(nmsg, wparam, lparam)) + return TRUE; + + break; + + case WM_INITMENUPOPUP: + if (_cm_ifs.HandleMenuMsg(nmsg, wparam, lparam)) + return 0; + + break; + +#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) + case WM_MENUCHAR: // only supported by IContextMenu3 + if (_cm_ifs._pctxmenu3) { + LRESULT lResult = 0; + + _cm_ifs._pctxmenu3->HandleMenuMsg2(nmsg, wparam, lparam, &lResult); + + return lResult; + } + + return 0; +#endif + } + + return super::WndProc(nmsg, wparam, lparam); + } + +protected: + CtxMenuInterfaces _cm_ifs; +}; + +extern HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, + LPCITEMIDLIST* ppidl, int x, int y, CtxMenuInterfaces& cm_ifs); _____
Modified: trunk/reactos/subsys/system/explorer/desktop/desktop.cpp --- trunk/reactos/subsys/system/explorer/desktop/desktop.cpp 2005-02-06 13:28:34 UTC (rev 13439) +++ trunk/reactos/subsys/system/explorer/desktop/desktop.cpp 2005-02-06 14:03:25 UTC (rev 13440) @@ -522,7 +522,7 @@
return true; }
-LRESULT DesktopShellView::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) +LRESULT DesktopShellView::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { switch(nmsg) { case WM_CONTEXTMENU: @@ -599,12 +599,12 @@
HRESULT DesktopShellView::DoDesktopContextMenu(int x, int y) { - IContextMenu* pcm1; + IContextMenu* pcm;
- HRESULT hr = DesktopFolder()->GetUIObjectOf(_hwnd, 0, NULL, IID_IContextMenu, NULL, (LPVOID*)&pcm1); + HRESULT hr = DesktopFolder()->GetUIObjectOf(_hwnd, 0, NULL, IID_IContextMenu, NULL, (LPVOID*)&pcm);
if (SUCCEEDED(hr)) { - IContextMenu* pcm = _cm_ifs.query_interfaces(pcm1); + pcm = _cm_ifs.query_interfaces(pcm);
HMENU hmenu = CreatePopupMenu();
_____
Modified: trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp --- trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp 2005-02-06 13:28:34 UTC (rev 13439) +++ trunk/reactos/subsys/system/explorer/utility/shellclasses.cpp 2005-02-06 14:03:25 UTC (rev 13440) @@ -523,13 +523,13 @@
HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl,
LPCITEMIDLIST* apidl, int x, int y, CtxMenuInterfaces& cm_ifs) { - IContextMenu* pcm1; + IContextMenu* pcm;
- HRESULT hr = shell_folder->GetUIObjectOf(hwndParent, cidl, apidl, IID_IContextMenu, NULL, (LPVOID*)&pcm1); -// HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm1); + HRESULT hr = shell_folder->GetUIObjectOf(hwndParent, cidl, apidl, IID_IContextMenu, NULL, (LPVOID*)&pcm); +// HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm);
if (SUCCEEDED(hr)) { - IContextMenu* pcm = cm_ifs.query_interfaces(pcm1); + pcm = cm_ifs.query_interfaces(pcm);
HMENU hmenu = CreatePopupMenu();