[0.4.14][COMDLG32][SHELL32] Support accelerator keys F2/del CORE-14332

For FileOpenDlgProc95() & SHBrowseForFolder().
I decided to port those 2 commits back to have CORE-14332
fixed as a whole and not only a part of it.
*If* I would ever decide to port that back even further I should
remember that I will have to pick additionally 0.4.14-dev-1187-g
fc4c4d4911

-------------------------------------------------------------
[COMDLG32] Support shortcut keys on Open/Save Dialog (#3238)

Enable key accelerators on File Open/Save Dialog. CORE-14332
cherry picked from commit 0.4.15-dev-1050-g
c8e1460ac5
--------------------------------------------------------------
[SHELL32] Implement VK_DELETE on SHBrowseForFolder (#2661)

Enable Del/Delete key to delete the selected folder in "Browse for Folder" dialog.
You can use https://jira.reactos.org/secure/attachment/40118/getfolder.zip as a test program.
CORE-7592
cherry picked from commit 0.4.15-dev-39-g
771457f37f
This commit is contained in:
Katayama Hirofumi MZ 2020-04-26 22:06:19 +09:00 committed by Joachim Henze
parent 0ea7582101
commit 23283deaf3
4 changed files with 141 additions and 8 deletions

View file

@ -27,6 +27,9 @@
#define COMDLG32_Atom MAKEINTATOM(0xa000) /* MS uses this one to identify props */
extern HINSTANCE COMDLG32_hInstance DECLSPEC_HIDDEN;
#ifdef __REACTOS__
extern CRITICAL_SECTION COMDLG32_OpenFileLock DECLSPEC_HIDDEN;
#endif
void COMDLG32_SetCommDlgExtendedError(DWORD err) DECLSPEC_HIDDEN;
LPVOID COMDLG32_AllocMem(int size) __WINE_ALLOC_SIZE(1) DECLSPEC_HIDDEN;

View file

@ -40,6 +40,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
DECLSPEC_HIDDEN HINSTANCE COMDLG32_hInstance = 0;
#ifdef __REACTOS__
CRITICAL_SECTION COMDLG32_OpenFileLock DECLSPEC_HIDDEN;
#endif
static DWORD COMDLG32_TlsIndex = TLS_OUT_OF_INDEXES;
@ -76,6 +79,9 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
DisableThreadLibraryCalls(hInstance);
SHELL32_hInstance = GetModuleHandleA("SHELL32.DLL");
#ifdef __REACTOS__
InitializeCriticalSection(&COMDLG32_OpenFileLock);
#endif
/* SHELL */
GPA(COMDLG32_SHSimpleIDListFromPathAW, SHELL32_hInstance, (LPCSTR)162);
@ -84,6 +90,9 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
case DLL_PROCESS_DETACH:
if (Reserved) break;
if (COMDLG32_TlsIndex != TLS_OUT_OF_INDEXES) TlsFree(COMDLG32_TlsIndex);
#ifdef __REACTOS__
DeleteCriticalSection(&COMDLG32_OpenFileLock);
#endif
break;
}
return TRUE;

View file

@ -106,6 +106,78 @@ typedef struct tagLookInInfo
UINT uSelectedItem;
} LookInInfos;
#ifdef __REACTOS__
/* We have to call IShellView::TranslateAccelerator to handle the standard
key bindings of File Open Dialog. We use hook to realize them. */
static HHOOK s_hFileDialogHook = NULL;
static LONG s_nFileDialogHookCount = 0;
#define MAX_TRANSLATE 8
static HWND s_ahwndTranslate[MAX_TRANSLATE] = { NULL };
static void FILEDLG95_AddRemoveTranslate(HWND hwndOld, HWND hwndNew)
{
LONG i;
for (i = 0; i < MAX_TRANSLATE; ++i)
{
if (s_ahwndTranslate[i] == hwndOld)
{
s_ahwndTranslate[i] = hwndNew;
break;
}
}
}
static __inline BOOL
FILEDLG95_DoTranslate(LONG i, HWND hwndFocus, LPMSG pMsg)
{
FileOpenDlgInfos *fodInfos;
HWND hwndView;
if (s_ahwndTranslate[i] == NULL)
return FALSE;
fodInfos = get_filedlg_infoptr(s_ahwndTranslate[i]);
if (fodInfos == NULL)
return FALSE;
hwndView = fodInfos->ShellInfos.hwndView;
if (hwndView == hwndFocus || IsChild(hwndView, hwndFocus))
{
IShellView_TranslateAccelerator(fodInfos->Shell.FOIShellView, pMsg);
return TRUE;
}
return FALSE;
}
/* WH_MSGFILTER hook procedure */
static LRESULT CALLBACK
FILEDLG95_TranslateMsgProc(INT nCode, WPARAM wParam, LPARAM lParam)
{
LPMSG pMsg;
if (nCode < 0)
return CallNextHookEx(s_hFileDialogHook, nCode, wParam, lParam);
if (nCode != MSGF_DIALOGBOX)
return 0;
pMsg = (LPMSG)lParam;
if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST)
{
LONG i;
HWND hwndFocus = GetFocus();
EnterCriticalSection(&COMDLG32_OpenFileLock);
for (i = 0; i < MAX_TRANSLATE; ++i)
{
if (FILEDLG95_DoTranslate(i, hwndFocus, pMsg))
break;
}
LeaveCriticalSection(&COMDLG32_OpenFileLock);
}
return 0;
}
#endif
/***********************************************************************
* Defines and global variables
@ -1420,6 +1492,17 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
SendCustomDlgNotificationMessage(hwnd,CDN_SELCHANGE);
#ifdef __REACTOS__
/* Enable hook and translate */
EnterCriticalSection(&COMDLG32_OpenFileLock);
if (++s_nFileDialogHookCount == 1)
{
s_hFileDialogHook = SetWindowsHookEx(WH_MSGFILTER, FILEDLG95_TranslateMsgProc,
0, GetCurrentThreadId());
}
FILEDLG95_AddRemoveTranslate(NULL, hwnd);
LeaveCriticalSection(&COMDLG32_OpenFileLock);
#endif
return 0;
}
case WM_SIZE:
@ -1457,6 +1540,17 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETIMAGELIST, 0, 0);
ImageList_Destroy(himl);
}
#ifdef __REACTOS__
/* Disable hook and translate */
EnterCriticalSection(&COMDLG32_OpenFileLock);
FILEDLG95_AddRemoveTranslate(hwnd, NULL);
if (--s_nFileDialogHookCount == 0)
{
UnhookWindowsHookEx(s_hFileDialogHook);
s_hFileDialogHook = NULL;
}
LeaveCriticalSection(&COMDLG32_OpenFileLock);
#endif
return FALSE;
}

View file

@ -625,6 +625,40 @@ static HRESULT BrsFolder_Rename(browse_info *info, HTREEITEM rename)
return S_OK;
}
#ifdef __REACTOS__
static void
BrsFolder_Delete(browse_info *info, HTREEITEM selected_item)
{
TV_ITEMW item;
TV_ITEMDATA *item_data;
SHFILEOPSTRUCTW fileop = { info->hwndTreeView };
WCHAR szzFrom[MAX_PATH + 1];
/* get item_data */
item.mask = TVIF_HANDLE | TVIF_PARAM;
item.hItem = selected_item;
if (!SendMessageW(info->hwndTreeView, TVM_GETITEMW, 0, (LPARAM)&item))
{
ERR("TVM_GETITEMW failed\n");
return;
}
item_data = (TV_ITEMDATA *)item.lParam;
/* get the path */
if (!SHGetPathFromIDListW(item_data->lpifq, szzFrom))
{
ERR("SHGetPathFromIDListW failed\n");
return;
}
szzFrom[lstrlenW(szzFrom) + 1] = 0; /* double NULL-terminated */
fileop.pFrom = szzFrom;
/* delete folder */
fileop.fFlags = FOF_ALLOWUNDO;
fileop.wFunc = FO_DELETE;
SHFileOperationW(&fileop);
}
#endif
static LRESULT BrsFolder_Treeview_Keydown(browse_info *info, LPNMTVKEYDOWN keydown)
{
HTREEITEM selected_item;
@ -643,14 +677,7 @@ static LRESULT BrsFolder_Treeview_Keydown(browse_info *info, LPNMTVKEYDOWN keydo
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.
*********************************************************/
BrsFolder_Delete(info, selected_item);
#else
const ITEMIDLIST *item_id;
ISFHelper *psfhlp;