mirror of
https://github.com/reactos/reactos.git
synced 2025-08-01 18:23:42 +00:00
Sync brsfolder.c with keyboard shortcut code from wine (#2290)
* [SHELL32] Add shortcut to rename folders with the F2 key. Sync Wine Commit 2e25a43f3fb6230460447bae6fb5db2edbd4a42f by Fabian Maurer * [SHELL32] Add shortcut to delete folders with the delete key. Sync Wine Commit 43f44ffb3779ff23c863d9b3297f92720e7e3733 by Fabian Maurer * Disable the code for file deletion. The Wine way doesn't work on ROS. Add an explaining comment why we can't use the Wine code, as requested by Amine
This commit is contained in:
parent
1816e4f6cb
commit
fc4c4d4911
1 changed files with 133 additions and 7 deletions
|
@ -41,6 +41,8 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||
|
||||
#define SHV_CHANGE_NOTIFY (WM_USER + 0x1111)
|
||||
|
||||
/* original margins and control size */
|
||||
typedef struct tagLAYOUT_DATA
|
||||
{
|
||||
|
@ -56,6 +58,7 @@ typedef struct tagbrowse_info
|
|||
LPITEMIDLIST pidlRet;
|
||||
LAYOUT_DATA *layout; /* filled by LayoutInit, used by LayoutUpdate */
|
||||
SIZE szMin;
|
||||
ULONG hNotify; /* change notification handle */
|
||||
} browse_info;
|
||||
|
||||
typedef struct tagTV_ITEMDATA
|
||||
|
@ -615,6 +618,67 @@ static LRESULT BrsFolder_Treeview_Rename(browse_info *info, NMTVDISPINFOW *pnmtv
|
|||
return 0;
|
||||
}
|
||||
|
||||
static HRESULT BrsFolder_Rename(browse_info *info, HTREEITEM rename)
|
||||
{
|
||||
SendMessageW(info->hwndTreeView, TVM_SELECTITEM, TVGN_CARET, (LPARAM)rename);
|
||||
SendMessageW(info->hwndTreeView, TVM_EDITLABELW, 0, (LPARAM)rename);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static LRESULT BrsFolder_Treeview_Keydown(browse_info *info, LPNMTVKEYDOWN keydown)
|
||||
{
|
||||
HTREEITEM selected_item;
|
||||
|
||||
/* Old dialog doesn't support those advanced features */
|
||||
if (!(info->lpBrowseInfo->ulFlags & BIF_NEWDIALOGSTYLE))
|
||||
return 0;
|
||||
|
||||
selected_item = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_CARET, 0);
|
||||
|
||||
switch (keydown->wVKey)
|
||||
{
|
||||
case VK_F2:
|
||||
BrsFolder_Rename(info, selected_item);
|
||||
break;
|
||||
case VK_DELETE:
|
||||
{
|
||||
#ifdef __REACTOS__
|
||||
/*********************************************************
|
||||
FIXME: Add a proper alternative implementation for ReactOS
|
||||
|
||||
NOTES: Wine makes use of the ISFHelper interface, which we
|
||||
don't have in ReactOS.
|
||||
It's defined in dlls/shell32/shellfolder.h and implemented
|
||||
in dlls/shell32/shfldr_fs.c on Wine's side.
|
||||
*********************************************************/
|
||||
#else
|
||||
const ITEMIDLIST *item_id;
|
||||
ISFHelper *psfhlp;
|
||||
HRESULT hr;
|
||||
TVITEMW item;
|
||||
TV_ITEMDATA *item_data;
|
||||
|
||||
item.mask = TVIF_PARAM;
|
||||
item.mask = TVIF_HANDLE|TVIF_PARAM;
|
||||
item.hItem = selected_item;
|
||||
SendMessageW(info->hwndTreeView, TVM_GETITEMW, 0, (LPARAM)&item);
|
||||
item_data = (TV_ITEMDATA *)item.lParam;
|
||||
item_id = item_data->lpi;
|
||||
|
||||
hr = IShellFolder_QueryInterface(item_data->lpsfParent, &IID_ISFHelper, (void**)&psfhlp);
|
||||
if(FAILED(hr))
|
||||
return 0;
|
||||
|
||||
/* perform the item deletion - tree view gets updated over shell notification */
|
||||
ISFHelper_DeleteItems(psfhlp, 1, &item_id);
|
||||
ISFHelper_Release(psfhlp);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LRESULT BrsFolder_OnNotify( browse_info *info, UINT CtlID, LPNMHDR lpnmh )
|
||||
{
|
||||
NMTREEVIEWW *pnmtv = (NMTREEVIEWW *)lpnmh;
|
||||
|
@ -641,6 +705,9 @@ static LRESULT BrsFolder_OnNotify( browse_info *info, UINT CtlID, LPNMHDR lpnmh
|
|||
case TVN_ENDLABELEDITA:
|
||||
case TVN_ENDLABELEDITW:
|
||||
return BrsFolder_Treeview_Rename( info, (LPNMTVDISPINFOW)pnmtv );
|
||||
|
||||
case TVN_KEYDOWN:
|
||||
return BrsFolder_Treeview_Keydown( info, (LPNMTVKEYDOWN)pnmtv );
|
||||
|
||||
default:
|
||||
WARN("unhandled (%d)\n", pnmtv->hdr.code);
|
||||
|
@ -653,6 +720,8 @@ static LRESULT BrsFolder_OnNotify( browse_info *info, UINT CtlID, LPNMHDR lpnmh
|
|||
|
||||
static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
|
||||
{
|
||||
LPITEMIDLIST computer_pidl;
|
||||
SHChangeNotifyEntry ntreg;
|
||||
LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
|
||||
|
||||
info->hWnd = hWnd;
|
||||
|
@ -718,18 +787,19 @@ static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
|
|||
else
|
||||
ERR("treeview control missing!\n");
|
||||
|
||||
/* Register for change notifications */
|
||||
SHGetFolderLocation(NULL, CSIDL_DESKTOP, NULL, 0, &computer_pidl);
|
||||
|
||||
ntreg.pidl = computer_pidl;
|
||||
ntreg.fRecursive = TRUE;
|
||||
|
||||
info->hNotify = SHChangeNotifyRegister(hWnd, SHCNRF_InterruptLevel, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
|
||||
|
||||
browsefolder_callback( info->lpBrowseInfo, hWnd, BFFM_INITIALIZED, 0 );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static HRESULT BrsFolder_Rename(browse_info *info, HTREEITEM rename)
|
||||
{
|
||||
SendMessageW(info->hwndTreeView, TVM_SELECTITEM, TVGN_CARET, (LPARAM)rename);
|
||||
SendMessageW(info->hwndTreeView, TVM_EDITLABELW, 0, (LPARAM)rename);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT BrsFolder_NewFolder(browse_info *info)
|
||||
{
|
||||
DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags);
|
||||
|
@ -1024,9 +1094,62 @@ static INT BrsFolder_OnDestroy(browse_info *info)
|
|||
info->layout = NULL;
|
||||
}
|
||||
|
||||
SHChangeNotifyDeregister(info->hNotify);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find a treeview node by recursively walking the treeview */
|
||||
static HTREEITEM BrsFolder_FindItemByPidl(browse_info *info, LPCITEMIDLIST pidl, HTREEITEM hItem)
|
||||
{
|
||||
TV_ITEMW item;
|
||||
TV_ITEMDATA *item_data;
|
||||
HRESULT hr;
|
||||
|
||||
item.mask = TVIF_HANDLE | TVIF_PARAM;
|
||||
item.hItem = hItem;
|
||||
SendMessageW(info->hwndTreeView, TVM_GETITEMW, 0, (LPARAM)&item);
|
||||
item_data = (TV_ITEMDATA *)item.lParam;
|
||||
|
||||
hr = IShellFolder_CompareIDs(item_data->lpsfParent, 0, item_data->lpifq, pidl);
|
||||
if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
|
||||
return hItem;
|
||||
|
||||
hItem = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
|
||||
|
||||
while (hItem)
|
||||
{
|
||||
HTREEITEM newItem = BrsFolder_FindItemByPidl(info, pidl, hItem);
|
||||
if (newItem)
|
||||
return newItem;
|
||||
hItem = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static LRESULT BrsFolder_OnChange(browse_info *info, const LPCITEMIDLIST *pidls, LONG event)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p)->(%p, %p, 0x%08x)\n", info, pidls[0], pidls[1], event);
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case SHCNE_RMDIR:
|
||||
case SHCNE_DELETE:
|
||||
{
|
||||
HTREEITEM handle_root = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_ROOT, 0);
|
||||
HTREEITEM handle_item = BrsFolder_FindItemByPidl(info, pidls[0], handle_root);
|
||||
|
||||
if (handle_item)
|
||||
SendMessageW(info->hwndTreeView, TVM_DELETEITEM, 0, (LPARAM)handle_item);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* BrsFolderDlgProc32 (not an exported API function)
|
||||
*/
|
||||
|
@ -1087,6 +1210,9 @@ static INT_PTR CALLBACK BrsFolderDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
|
|||
case BFFM_SETEXPANDED: /* unicode only */
|
||||
return BrsFolder_OnSetExpanded(info, (LPVOID)lParam, (BOOL)wParam, NULL);
|
||||
|
||||
case SHV_CHANGE_NOTIFY:
|
||||
return BrsFolder_OnChange(info, (const LPCITEMIDLIST*)wParam, (LONG)lParam);
|
||||
|
||||
case WM_DESTROY:
|
||||
return BrsFolder_OnDestroy(info);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue