mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 12:23:31 +00:00
owner drawn context menus for lean explorer version
svn path=/branches/lean-explorer/; revision=13440
This commit is contained in:
@@ -439,11 +439,11 @@ bool DesktopShellView::InitDragDrop()
|
||||
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 @@ int DesktopShellView::Notify(int id, NMHDR* pnmh)
|
||||
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 @@ bool DesktopShellView::DoContextMenu(int x, int y)
|
||||
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 DesktopShellView::DoDesktopContextMenu(int x, int y)
|
||||
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 @@ HRESULT DesktopShellView::DoDesktopContextMenu(int x, int y)
|
||||
|
||||
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) {
|
||||
|
||||
@@ -163,9 +163,9 @@ public:
|
||||
|
||||
|
||||
/// 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 @@ protected:
|
||||
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;
|
||||
|
||||
@@ -103,7 +103,7 @@ void MainFrame::update_explorer_view()
|
||||
}
|
||||
}
|
||||
|
||||
_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);
|
||||
|
||||
@@ -31,9 +31,9 @@ enum OPEN_WINDOW_MODE {OWM_EXPLORE=1, OWM_DETAILS=2, OWM_PIDL=4};
|
||||
|
||||
|
||||
/// Explorer frame window
|
||||
struct MainFrame : public PreTranslateWindow
|
||||
struct MainFrame : public ExtContextMenuHandlerT<PreTranslateWindow>
|
||||
{
|
||||
typedef PreTranslateWindow super;
|
||||
typedef ExtContextMenuHandlerT<PreTranslateWindow> super;
|
||||
|
||||
MainFrame(HWND hwnd);
|
||||
~MainFrame();
|
||||
|
||||
@@ -45,11 +45,13 @@ static LPARAM TreeView_GetItemData(HWND hwndTreeView, HTREEITEM hItem)
|
||||
}
|
||||
|
||||
|
||||
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 @@ void ShellBrowserChild::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPO
|
||||
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 @@ void ShellBrowserChild::OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh)
|
||||
|
||||
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;
|
||||
|
||||
@@ -44,7 +44,8 @@ struct ShellPathInfo
|
||||
/// 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 @@ public:
|
||||
|
||||
protected:
|
||||
ShellDirectory* _cur_dir;
|
||||
CtxMenuInterfaces& _cm_ifs;
|
||||
};
|
||||
|
||||
@@ -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,7 +468,56 @@ SpecialFolderFSPath::SpecialFolderFSPath(int folder, HWND hwnd)
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
@@ -476,6 +525,8 @@ HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int
|
||||
// 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 @@ HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int
|
||||
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;
|
||||
|
||||
|
||||
@@ -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 @@ protected:
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user