mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
generic support for owner drawn context menus
svn path=/trunk/; revision=13437
This commit is contained in:
parent
b98bef3c5f
commit
ac1bda4c72
20 changed files with 193 additions and 110 deletions
|
@ -473,11 +473,6 @@ DesktopShellView::DesktopShellView(HWND hwnd, IShellView* pShellView)
|
||||||
: super(hwnd),
|
: super(hwnd),
|
||||||
_pShellView(pShellView)
|
_pShellView(pShellView)
|
||||||
{
|
{
|
||||||
_pctxmenu2 = NULL;
|
|
||||||
#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005)
|
|
||||||
_pctxmenu3 = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_hwndListView = ::GetNextWindow(hwnd, GW_CHILD);
|
_hwndListView = ::GetNextWindow(hwnd, GW_CHILD);
|
||||||
|
|
||||||
SetWindowStyle(_hwndListView, GetWindowStyle(_hwndListView)&~LVS_ALIGNMASK);//|LVS_ALIGNTOP|LVS_AUTOARRANGE);
|
SetWindowStyle(_hwndListView, GetWindowStyle(_hwndListView)&~LVS_ALIGNMASK);//|LVS_ALIGNTOP|LVS_AUTOARRANGE);
|
||||||
|
@ -531,7 +526,7 @@ LRESULT DesktopShellView::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
||||||
{
|
{
|
||||||
switch(nmsg) {
|
switch(nmsg) {
|
||||||
case WM_CONTEXTMENU:
|
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));
|
DoDesktopContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -546,36 +541,6 @@ LRESULT DesktopShellView::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
||||||
case PM_DISPLAY_VERSION:
|
case PM_DISPLAY_VERSION:
|
||||||
return SendMessage(_hwndListView, nmsg, wparam, lparam);
|
return SendMessage(_hwndListView, nmsg, wparam, lparam);
|
||||||
|
|
||||||
#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005)
|
|
||||||
case WM_MENUCHAR: // only supported by IContextMenu3
|
|
||||||
if (_pctxmenu3) {
|
|
||||||
LRESULT lResult = 0;
|
|
||||||
|
|
||||||
_pctxmenu3->HandleMenuMsg2(nmsg, wparam, lparam, &lResult);
|
|
||||||
|
|
||||||
return lResult;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case WM_DRAWITEM:
|
|
||||||
case WM_MEASUREITEM:
|
|
||||||
if (wparam)
|
|
||||||
break; // If wParam != 0 then the message is not menu-related.
|
|
||||||
|
|
||||||
// fall through
|
|
||||||
|
|
||||||
case WM_INITMENUPOPUP:
|
|
||||||
#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005)
|
|
||||||
if (_pctxmenu3)
|
|
||||||
_pctxmenu3->HandleMenuMsg(nmsg, wparam, lparam);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (_pctxmenu2)
|
|
||||||
_pctxmenu2->HandleMenuMsg(nmsg, wparam, lparam);
|
|
||||||
|
|
||||||
return nmsg==WM_INITMENUPOPUP? 0: TRUE; // Inform caller that we handled WM_INITPOPUPMENU by ourself.
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return super::WndProc(nmsg, wparam, lparam);
|
return super::WndProc(nmsg, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
@ -593,7 +558,7 @@ int DesktopShellView::Notify(int id, NMHDR* pnmh)
|
||||||
return super::Notify(id, 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;
|
IDataObject* selection;
|
||||||
|
|
||||||
|
@ -623,7 +588,7 @@ bool DesktopShellView::DoContextMenu(int x, int y)
|
||||||
for(int i=pida->cidl; i>0; --i)
|
for(int i=pida->cidl; i>0; --i)
|
||||||
apidl[i-1] = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[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();
|
selection->Release();
|
||||||
|
|
||||||
|
@ -635,27 +600,11 @@ bool DesktopShellView::DoContextMenu(int x, int y)
|
||||||
HRESULT DesktopShellView::DoDesktopContextMenu(int x, int y)
|
HRESULT DesktopShellView::DoDesktopContextMenu(int x, int y)
|
||||||
{
|
{
|
||||||
IContextMenu* pcm1;
|
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*)&pcm1);
|
||||||
|
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
// Get the higher version context menu interfaces.
|
IContextMenu* pcm = _cm_ifs.query_interfaces(pcm1);
|
||||||
_pctxmenu2 = NULL;
|
|
||||||
#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005)
|
|
||||||
_pctxmenu3 = NULL;
|
|
||||||
|
|
||||||
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();
|
|
||||||
else
|
|
||||||
pcm = pcm1;
|
|
||||||
|
|
||||||
HMENU hmenu = CreatePopupMenu();
|
HMENU hmenu = CreatePopupMenu();
|
||||||
|
|
||||||
|
@ -668,10 +617,7 @@ HRESULT DesktopShellView::DoDesktopContextMenu(int x, int y)
|
||||||
|
|
||||||
UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, _hwnd, NULL);
|
UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, _hwnd, NULL);
|
||||||
|
|
||||||
_pctxmenu2 = NULL;
|
_cm_ifs.reset();
|
||||||
#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005)
|
|
||||||
_pctxmenu3 = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (idCmd == FCIDM_SHVIEWLAST-1) {
|
if (idCmd == FCIDM_SHVIEWLAST-1) {
|
||||||
explorer_about(_hwnd);
|
explorer_about(_hwnd);
|
||||||
|
|
|
@ -165,9 +165,9 @@ public:
|
||||||
|
|
||||||
|
|
||||||
/// subclassed ShellView window
|
/// subclassed ShellView window
|
||||||
struct DesktopShellView : public SubclassedWindow
|
struct DesktopShellView : public ExtContextMenuHandlerT<SubclassedWindow>
|
||||||
{
|
{
|
||||||
typedef SubclassedWindow super;
|
typedef ExtContextMenuHandlerT<SubclassedWindow> super;
|
||||||
|
|
||||||
DesktopShellView(HWND hwnd, IShellView* pShellView);
|
DesktopShellView(HWND hwnd, IShellView* pShellView);
|
||||||
|
|
||||||
|
@ -180,16 +180,11 @@ protected:
|
||||||
int Command(int id, int code);
|
int Command(int id, int code);
|
||||||
int Notify(int id, NMHDR* pnmh);
|
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);
|
HRESULT DoDesktopContextMenu(int x, int y);
|
||||||
void PositionIcons(int dir=1);
|
void PositionIcons(int dir=1);
|
||||||
|
|
||||||
DesktopDropTarget* _pDropTarget;
|
DesktopDropTarget* _pDropTarget;
|
||||||
HWND _hwndListView;
|
HWND _hwndListView;
|
||||||
int _icon_algo;
|
int _icon_algo;
|
||||||
|
|
||||||
IContextMenu2* _pctxmenu2;
|
|
||||||
#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005)
|
|
||||||
IContextMenu3* _pctxmenu3;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,4 +24,7 @@
|
||||||
- hide desktop bar when showing full screen applications
|
- hide desktop bar when showing full screen applications
|
||||||
- new start menu entry "Filemanager" close to "Explore" -> display C: and D: drive in MDI window
|
- new start menu entry "Filemanager" close to "Explore" -> display C: and D: drive in MDI window
|
||||||
- Startmenu: You can open the start menu by pressing Win-key, but can't close with another hit of Win-key.
|
- Startmenu: You can open the start menu by pressing Win-key, but can't close with another hit of Win-key.
|
||||||
|
- Export von Bookmarks für IE (+ Mozilla)
|
||||||
|
|
||||||
|
- Search Programs -> performance monitor.msv -> Abort
|
||||||
|
|
||||||
|
|
|
@ -401,7 +401,7 @@ BOOL Entry::launch_entry(HWND hwnd, UINT nCmdShow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT Entry::do_context_menu(HWND hwnd, const POINT& pos)
|
HRESULT Entry::do_context_menu(HWND hwnd, const POINT& pos, CtxMenuInterfaces& cm_ifs)
|
||||||
{
|
{
|
||||||
ShellPath shell_path = create_absolute_pidl();
|
ShellPath shell_path = create_absolute_pidl();
|
||||||
LPCITEMIDLIST pidl_abs = shell_path;
|
LPCITEMIDLIST pidl_abs = shell_path;
|
||||||
|
@ -419,7 +419,7 @@ HRESULT Entry::do_context_menu(HWND hwnd, const POINT& pos)
|
||||||
HRESULT hr = (*SHBindToParent)(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast);
|
HRESULT hr = (*SHBindToParent)(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast);
|
||||||
|
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pos.x, pos.y);
|
hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pos.x, pos.y, cm_ifs);
|
||||||
|
|
||||||
parentFolder->Release();
|
parentFolder->Release();
|
||||||
}
|
}
|
||||||
|
@ -442,7 +442,7 @@ HRESULT Entry::do_context_menu(HWND hwnd, const POINT& pos)
|
||||||
ShellFolder parent_folder = parent_path;
|
ShellFolder parent_folder = parent_path;
|
||||||
return ShellFolderContextMenu(parent_folder, hwnd, 1, &pidl, pos.x, pos.y);
|
return ShellFolderContextMenu(parent_folder, hwnd, 1, &pidl, pos.x, pos.y);
|
||||||
*/
|
*/
|
||||||
return ShellFolderContextMenu(GetDesktopFolder(), hwnd, 1, &pidl_abs, pos.x, pos.y);
|
return ShellFolderContextMenu(GetDesktopFolder(), hwnd, 1, &pidl_abs, pos.x, pos.y, cm_ifs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ public:
|
||||||
virtual ShellPath create_absolute_pidl() const {return (LPCITEMIDLIST)NULL;}
|
virtual ShellPath create_absolute_pidl() const {return (LPCITEMIDLIST)NULL;}
|
||||||
virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
|
virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
|
||||||
virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
|
virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
|
||||||
virtual HRESULT do_context_menu(HWND hwnd, const POINT& pos);
|
virtual HRESULT do_context_menu(HWND hwnd, const POINT& pos, 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -123,7 +123,7 @@ INT_PTR CALLBACK ExecuteDialog::WndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPA
|
||||||
// FileChildWindow
|
// FileChildWindow
|
||||||
|
|
||||||
FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info)
|
FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info)
|
||||||
: ChildWindow(hwnd, info)
|
: super(hwnd, info)
|
||||||
{
|
{
|
||||||
CONTEXT("FileChildWindow::FileChildWindow()");
|
CONTEXT("FileChildWindow::FileChildWindow()");
|
||||||
|
|
||||||
|
@ -433,7 +433,7 @@ LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
||||||
|
|
||||||
if (dis->CtlID == IDW_TREE_LEFT)
|
if (dis->CtlID == IDW_TREE_LEFT)
|
||||||
_left->draw_item(dis, entry);
|
_left->draw_item(dis, entry);
|
||||||
else
|
else if (dis->CtlID == IDW_TREE_RIGHT)
|
||||||
_right->draw_item(dis, entry);
|
_right->draw_item(dis, entry);
|
||||||
|
|
||||||
return TRUE;}
|
return TRUE;}
|
||||||
|
@ -507,7 +507,7 @@ LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx);
|
Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx);
|
||||||
|
|
||||||
CHECKERROR(entry->do_context_menu(_hwnd, pt_screen));
|
CHECKERROR(entry->do_context_menu(_hwnd, pt_screen, _cm_ifs));
|
||||||
}
|
}
|
||||||
break;}
|
break;}
|
||||||
|
|
||||||
|
|
|
@ -85,9 +85,9 @@ struct WebChildWndInfo : public FileChildWndInfo
|
||||||
|
|
||||||
|
|
||||||
/// MDI child window displaying file lists
|
/// MDI child window displaying file lists
|
||||||
struct FileChildWindow : public ChildWindow
|
struct FileChildWindow : public ExtContextMenuHandlerT<ChildWindow>
|
||||||
{
|
{
|
||||||
typedef ChildWindow super;
|
typedef ExtContextMenuHandlerT<ChildWindow> super;
|
||||||
|
|
||||||
FileChildWindow(HWND hwnd, const FileChildWndInfo& info);
|
FileChildWindow(HWND hwnd, const FileChildWndInfo& info);
|
||||||
|
|
||||||
|
|
|
@ -1564,7 +1564,7 @@ void SDIMainFrame::update_shell_browser()
|
||||||
}
|
}
|
||||||
|
|
||||||
_shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
|
_shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
|
||||||
_shellpath_info, _himlSmall, this));
|
_shellpath_info, _himlSmall, this, _cm_ifs));
|
||||||
|
|
||||||
_shellBrowser->Init(_hwnd);
|
_shellBrowser->Init(_hwnd);
|
||||||
|
|
||||||
|
|
|
@ -124,9 +124,13 @@ protected:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct SDIMainFrame : public ShellBrowserChildT<MainFrameBase>
|
struct SDIMainFrame : public ExtContextMenuHandlerT<
|
||||||
|
ShellBrowserChildT<MainFrameBase>
|
||||||
|
>
|
||||||
{
|
{
|
||||||
typedef ShellBrowserChildT<MainFrameBase> super;
|
typedef ExtContextMenuHandlerT<
|
||||||
|
ShellBrowserChildT<MainFrameBase>
|
||||||
|
> super;
|
||||||
|
|
||||||
SDIMainFrame(HWND hwnd);
|
SDIMainFrame(HWND hwnd);
|
||||||
|
|
||||||
|
|
|
@ -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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -491,9 +491,9 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
|
||||||
// output type/class name
|
// output type/class name
|
||||||
if (visible_cols & COL_TYPE) {
|
if (visible_cols & COL_TYPE) {
|
||||||
if (calcWidthCol == -1)
|
if (calcWidthCol == -1)
|
||||||
_out_wrkr.output_text(dis, _positions, col, entry->_type_name&&entry->_type_name!=LPSTR_TEXTCALLBACK? entry->_type_name: TEXT(""), 0);
|
_out_wrkr.output_text(dis, _positions, col, entry->_type_name? entry->_type_name: TEXT(""), 0);
|
||||||
else if (calcWidthCol==col || calcWidthCol==COLUMNS)
|
else if (calcWidthCol==col || calcWidthCol==COLUMNS)
|
||||||
calc_width(dis, col, entry->_type_name&&entry->_type_name!=LPSTR_TEXTCALLBACK? entry->_type_name: TEXT(""));
|
calc_width(dis, col, entry->_type_name? entry->_type_name: TEXT(""));
|
||||||
}
|
}
|
||||||
++col;
|
++col;
|
||||||
|
|
||||||
|
@ -623,9 +623,9 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
|
||||||
// output content / symbolic link target / comment
|
// output content / symbolic link target / comment
|
||||||
if (visible_cols & COL_CONTENT) {
|
if (visible_cols & COL_CONTENT) {
|
||||||
if (calcWidthCol == -1)
|
if (calcWidthCol == -1)
|
||||||
_out_wrkr.output_text(dis, _positions, col, entry->_content&&entry->_content!=LPSTR_TEXTCALLBACK? entry->_content: TEXT(""), 0);
|
_out_wrkr.output_text(dis, _positions, col, entry->_content? entry->_content: TEXT(""), 0);
|
||||||
else if (calcWidthCol==col || calcWidthCol==COLUMNS)
|
else if (calcWidthCol==col || calcWidthCol==COLUMNS)
|
||||||
calc_width(dis, col, entry->_content&&entry->_content!=LPSTR_TEXTCALLBACK? entry->_content: TEXT(""));
|
calc_width(dis, col, entry->_content? entry->_content: TEXT(""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,13 +31,15 @@
|
||||||
#include "../explorer_intres.h"
|
#include "../explorer_intres.h"
|
||||||
|
|
||||||
|
|
||||||
ShellBrowser::ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, HIMAGELIST himl, BrowserCallback* cb)
|
ShellBrowser::ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info,
|
||||||
|
HIMAGELIST himl, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs)
|
||||||
: _hwnd(hwnd),
|
: _hwnd(hwnd),
|
||||||
_left_hwnd(left_hwnd),
|
_left_hwnd(left_hwnd),
|
||||||
_right_hwnd(right_hwnd),
|
_right_hwnd(right_hwnd),
|
||||||
_create_info(create_info),
|
_create_info(create_info),
|
||||||
_himl(himl),
|
_himl(himl),
|
||||||
_callback(cb)
|
_callback(cb),
|
||||||
|
_cm_ifs(cm_ifs)
|
||||||
{
|
{
|
||||||
_pShellView = NULL;
|
_pShellView = NULL;
|
||||||
_pDropTarget = NULL;
|
_pDropTarget = NULL;
|
||||||
|
@ -204,7 +206,7 @@ void ShellBrowser::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh)
|
||||||
Entry* entry = (Entry*)itemData;
|
Entry* entry = (Entry*)itemData;
|
||||||
ClientToScreen(_left_hwnd, &tvhti.pt);
|
ClientToScreen(_left_hwnd, &tvhti.pt);
|
||||||
|
|
||||||
CHECKERROR(entry->do_context_menu(_hwnd, tvhti.pt));
|
CHECKERROR(entry->do_context_menu(_hwnd, tvhti.pt, _cm_ifs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -574,7 +576,7 @@ void MDIShellBrowserChild::update_shell_browser()
|
||||||
}
|
}
|
||||||
|
|
||||||
_shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
|
_shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
|
||||||
_shellpath_info, _himlSmall, this));
|
_shellpath_info, _himlSmall, this, _cm_ifs));
|
||||||
|
|
||||||
_shellBrowser->Init(_hwndFrame);
|
_shellBrowser->Init(_hwndFrame);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,8 @@ struct BrowserCallback
|
||||||
/// Implementation of IShellBrowserImpl interface in explorer child windows
|
/// Implementation of IShellBrowserImpl interface in explorer child windows
|
||||||
struct ShellBrowser : public IShellBrowserImpl
|
struct ShellBrowser : public IShellBrowserImpl
|
||||||
{
|
{
|
||||||
ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, HIMAGELIST himl, BrowserCallback* cb);
|
ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info,
|
||||||
|
HIMAGELIST himl, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs);
|
||||||
virtual ~ShellBrowser();
|
virtual ~ShellBrowser();
|
||||||
|
|
||||||
//IOleWindow
|
//IOleWindow
|
||||||
|
@ -153,6 +154,8 @@ protected:
|
||||||
Root _root;
|
Root _root;
|
||||||
ShellDirectory* _cur_dir;
|
ShellDirectory* _cur_dir;
|
||||||
|
|
||||||
|
CtxMenuInterfaces& _cm_ifs;
|
||||||
|
|
||||||
void InitializeTree(HIMAGELIST himl);
|
void InitializeTree(HIMAGELIST himl);
|
||||||
bool InitDragDrop();
|
bool InitDragDrop();
|
||||||
|
|
||||||
|
@ -231,9 +234,13 @@ protected:
|
||||||
|
|
||||||
#ifndef _NO_MDI
|
#ifndef _NO_MDI
|
||||||
|
|
||||||
struct MDIShellBrowserChild : public ShellBrowserChildT<ChildWindow>
|
struct MDIShellBrowserChild : public ExtContextMenuHandlerT<
|
||||||
|
ShellBrowserChildT<ChildWindow>
|
||||||
|
>
|
||||||
{
|
{
|
||||||
typedef ShellBrowserChildT<ChildWindow> super;
|
typedef ExtContextMenuHandlerT<
|
||||||
|
ShellBrowserChildT<ChildWindow>
|
||||||
|
> super;
|
||||||
|
|
||||||
MDIShellBrowserChild(HWND hwnd, const ShellChildWndInfo& info);
|
MDIShellBrowserChild(HWND hwnd, const ShellChildWndInfo& info);
|
||||||
|
|
||||||
|
|
|
@ -202,14 +202,14 @@ BOOL ShellEntry::launch_entry(HWND hwnd, UINT nCmdShow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT ShellEntry::do_context_menu(HWND hwnd, LPPOINT pptScreen)
|
HRESULT ShellEntry::do_context_menu(HWND hwnd, LPPOINT pptScreen, CtxMenuInterfaces& cm_ifs)
|
||||||
{
|
{
|
||||||
ShellDirectory* dir = static_cast<ShellDirectory*>(_up);
|
ShellDirectory* dir = static_cast<ShellDirectory*>(_up);
|
||||||
|
|
||||||
ShellFolder folder = dir? dir->_folder: GetDesktopFolder();
|
ShellFolder folder = dir? dir->_folder: GetDesktopFolder();
|
||||||
LPCITEMIDLIST pidl = _pidl;
|
LPCITEMIDLIST pidl = _pidl;
|
||||||
|
|
||||||
return ShellFolderContextMenu(folder, hwnd, 1, &pidl, pptScreen->x, pptScreen->y);
|
return ShellFolderContextMenu(folder, hwnd, 1, &pidl, pptScreen->x, pptScreen->y, cm_ifs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct ShellEntry : public Entry
|
||||||
virtual ShellPath create_absolute_pidl() const;
|
virtual ShellPath create_absolute_pidl() const;
|
||||||
virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
|
virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
|
||||||
virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
|
virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
|
||||||
virtual HRESULT do_context_menu(HWND hwnd, LPPOINT pptScreen);
|
virtual HRESULT do_context_menu(HWND hwnd, LPPOINT pptScreen, CtxMenuInterfaces& cm_ifs);
|
||||||
|
|
||||||
IShellFolder* get_parent_folder() const;
|
IShellFolder* get_parent_folder() const;
|
||||||
|
|
||||||
|
|
|
@ -247,7 +247,7 @@ LRESULT QuickLaunchBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry) // entry is NULL for desktop switch buttons
|
if (entry) // entry is NULL for desktop switch buttons
|
||||||
CHECKERROR(entry->do_context_menu(_hwnd, screen_pt));
|
CHECKERROR(entry->do_context_menu(_hwnd, screen_pt, _cm_ifs));
|
||||||
else
|
else
|
||||||
goto def;
|
goto def;
|
||||||
break;}
|
break;}
|
||||||
|
|
|
@ -57,9 +57,9 @@ struct QuickLaunchMap : public map<int, QuickLaunchEntry>
|
||||||
|
|
||||||
|
|
||||||
/// quick launch bar window
|
/// quick launch bar window
|
||||||
struct QuickLaunchBar : public SubclassedWindow
|
struct QuickLaunchBar : public ExtContextMenuHandlerT<SubclassedWindow>
|
||||||
{
|
{
|
||||||
typedef SubclassedWindow super;
|
typedef ExtContextMenuHandlerT<SubclassedWindow> super;
|
||||||
|
|
||||||
QuickLaunchBar(HWND hwnd);
|
QuickLaunchBar(HWND hwnd);
|
||||||
~QuickLaunchBar();
|
~QuickLaunchBar();
|
||||||
|
|
|
@ -442,7 +442,7 @@ LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
||||||
Entry* entry = *it;
|
Entry* entry = *it;
|
||||||
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
CHECKERROR(entry->do_context_menu(_hwnd, screen_pt)); // may close start menu because of focus loss
|
CHECKERROR(entry->do_context_menu(_hwnd, screen_pt, _cm_ifs)); // may close start menu because of focus loss
|
||||||
break; ///@todo handle context menu for more than one entry
|
break; ///@todo handle context menu for more than one entry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,15 +202,15 @@ extern void DrawStartMenuButton(HDC hdc, const RECT& rect, LPCTSTR title, HICON
|
||||||
*/
|
*/
|
||||||
struct StartMenu :
|
struct StartMenu :
|
||||||
#ifdef _LIGHT_STARTMENU
|
#ifdef _LIGHT_STARTMENU
|
||||||
public OwnerDrawParent<Window>
|
public ExtContextMenuHandlerT<OwnerDrawParent<Window> >
|
||||||
#else
|
#else
|
||||||
public OwnerDrawParent<DialogWindow>
|
public ExtContextMenuHandlerT<OwnerDrawParent<DialogWindow> >
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef _LIGHT_STARTMENU
|
#ifdef _LIGHT_STARTMENU
|
||||||
typedef OwnerDrawParent<Window> super;
|
typedef ExtContextMenuHandlerT<OwnerDrawParent<Window> > super;
|
||||||
#else
|
#else
|
||||||
typedef OwnerDrawParent<DialogWindow> super;
|
typedef ExtContextMenuHandlerT<OwnerDrawParent<DialogWindow> > super;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
StartMenu(HWND hwnd);
|
StartMenu(HWND hwnd);
|
||||||
|
|
|
@ -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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -472,14 +472,65 @@ SpecialFolderFSPath::SpecialFolderFSPath(int folder, HWND hwnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, LPCITEMIDLIST* apidl, int x, int y)
|
void CtxMenuInterfaces::reset()
|
||||||
{
|
{
|
||||||
IContextMenu* pcm;
|
_pctxmenu2 = NULL;
|
||||||
|
|
||||||
HRESULT hr = shell_folder->GetUIObjectOf(hwndParent, cidl, apidl, IID_IContextMenu, NULL, (LPVOID*)&pcm);
|
#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005)
|
||||||
// HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm);
|
_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* pcm1;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
|
IContextMenu* pcm = cm_ifs.query_interfaces(pcm1);
|
||||||
|
|
||||||
HMENU hmenu = CreatePopupMenu();
|
HMENU hmenu = CreatePopupMenu();
|
||||||
|
|
||||||
if (hmenu) {
|
if (hmenu) {
|
||||||
|
@ -488,6 +539,8 @@ HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, hwndParent, NULL);
|
UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, hwndParent, NULL);
|
||||||
|
|
||||||
|
cm_ifs.reset();
|
||||||
|
|
||||||
if (idCmd) {
|
if (idCmd) {
|
||||||
CMINVOKECOMMANDINFO cmi;
|
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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -1003,4 +1003,77 @@ protected:
|
||||||
LPIDA _pIDList;
|
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);
|
||||||
|
|
Loading…
Reference in a new issue