[0.4.11][COMDLG32][SHELL32] Support accelerator keys F2/del, Ignore unused flag, de-DE update

by porting back:

[SHELL32] Ignore unused flag SEE_MASK_UNICODE (#5033)

0.4.15-dev-5676-g 5c22ce3742
to mute logspam of the kind
fixme:(dll/win32/shell32/shlexec.cpp:1934) flags ignored: 0x00004000
e.g. when starting Rapps.
-------------------------------------------------------------
[SHELL32] brsfolder.c Delete unused #ifndef __REACTOS__ block

It is a partial pick of:
0.4.15-dev-3642-g 83be315abf
and strip all EOL-whitespace in that file.
This part is done as the file is part of a backport into even older branches.
brsfolder.c will be 100% in sync between releases/0.4.7 - releases/0.4.14 afterwards.
-------------------------------------------------------------
[SHELL32] de-DE.rc Update regarding IDC_BROWSE_FOR_FOLDER_NEW_FOLDER

0.4.15-dev-2957-g c30b1fe893
and pick other small tweaks in that file from master
-------------------------------------------------------------
[COMDLG32] Support shortcut keys on Open/Save Dialog (#3238)

Enable key accelerators on File Open/Save Dialog. CORE-14332
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.
0.4.15-dev-39-g 771457f37f
--------------------------------------------------------------
[SHELL32] Sync brsfolder.c with keyboard shortcut code from wine (#2290)

0.4.14-dev-1187-g fc4c4d4911
This commit is contained in:
Joachim Henze 2023-02-14 21:05:27 +01:00
parent 8f1e2880e1
commit 5d463d517b
6 changed files with 291 additions and 40 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

@ -107,6 +107,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
@ -1417,6 +1489,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:
@ -1454,6 +1537,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

@ -105,9 +105,9 @@ BEGIN
LTEXT "", IDC_BROWSE_FOR_FOLDER_TITLE, 10, 8, 198, 24
LTEXT "", IDC_BROWSE_FOR_FOLDER_STATUS, 10, 25, 198, 12
LTEXT "Ordner:", IDC_BROWSE_FOR_FOLDER_FOLDER, 10, 152, 40, 12
CONTROL "", IDC_BROWSE_FOR_FOLDER_TREEVIEW, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | WS_BORDER | WS_TABSTOP, 12, 38, 194, 105
CONTROL "", IDC_BROWSE_FOR_FOLDER_TREEVIEW, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | WS_BORDER | WS_TABSTOP, 12, 38, 194, 105
EDITTEXT IDC_BROWSE_FOR_FOLDER_FOLDER_TEXT, 46, 150, 160, 14, WS_BORDER | WS_GROUP | WS_TABSTOP
PUSHBUTTON "&Neuen Ordner erstellen", IDC_BROWSE_FOR_FOLDER_NEW_FOLDER, 12, 174, 77, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "Neuen &Ordner erstellen", IDC_BROWSE_FOR_FOLDER_NEW_FOLDER, 12, 174, 85, 14, WS_GROUP | WS_TABSTOP
DEFPUSHBUTTON "OK", IDOK, 102, 174, 50, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
PUSHBUTTON "Abbrechen", IDCANCEL, 156, 174, 50, 14, WS_GROUP | WS_TABSTOP
END
@ -397,7 +397,7 @@ BEGIN
LTEXT "Datei: ", 14001, 44, 30, 188, 10
GROUPBOX "&Programme", -1, 7, 42, 249, 187
CONTROL "Programs", 14002, WC_TREEVIEW, WS_BORDER | WS_TABSTOP | TVS_SHOWSELALWAYS, 16 ,57, 230, 130
AUTOCHECKBOX "&Dateityp &immer mit dem ausgewählten Programm öffnen", 14003, 20, 193, 225, 10
AUTOCHECKBOX "Dateityp &immer mit diesem Programm öffnen", 14003, 16, 193, 232, 10
PUSHBUTTON "&Durchsuchen...", 14004, 188, 207, 60, 14
DEFPUSHBUTTON "OK", IDOK, 150, 236, 50, 14
PUSHBUTTON "Abbrechen", IDCANCEL, 206, 236, 50, 14

View file

@ -558,7 +558,6 @@ static LPWSTR SHELL_BuildEnvW( const WCHAR *path )
return new_env;
}
/***********************************************************************
* SHELL_TryAppPathW [Internal]
*
@ -579,13 +578,13 @@ static BOOL SHELL_TryAppPathW( LPCWSTR szName, LPWSTR lpResult, WCHAR **env)
wcscpy(buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
wcscat(buffer, szName);
res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, buffer, 0, KEY_READ, &hkApp);
if (res)
if (res)
{
// Add ".exe" extension, if extension does not exists
if (PathAddExtensionW(buffer, wszExe))
{
res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, buffer, 0, KEY_READ, &hkApp);
}
}
if (res) goto end;
}
@ -1731,7 +1730,7 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
static const DWORD unsupportedFlags =
SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
SEE_MASK_UNICODE | SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR;
SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR;
WCHAR parametersBuffer[1024], dirBuffer[MAX_PATH], wcmdBuffer[1024];
WCHAR *wszApplicationName, *wszParameters, *wszDir, *wcmd;

View file

@ -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
@ -63,7 +66,7 @@ typedef struct tagTV_ITEMDATA
LPSHELLFOLDER lpsfParent; /* IShellFolder of the parent */
LPITEMIDLIST lpi; /* PIDL relative to parent */
LPITEMIDLIST lpifq; /* Fully qualified PIDL */
IEnumIDList* pEnumIL; /* Children iterator */
IEnumIDList* pEnumIL; /* Children iterator */
} TV_ITEMDATA, *LPTV_ITEMDATA;
typedef struct tagLAYOUT_INFO
@ -185,7 +188,7 @@ static void LayoutUpdate(HWND hwnd, LAYOUT_DATA *data, const LAYOUT_INFO *layout
* InitializeTreeView [Internal]
*
* Called from WM_INITDIALOG handler.
*
*
* PARAMS
* hwndParent [I] The BrowseForFolder dialog
* root [I] ITEMIDLIST of the root shell folder
@ -202,18 +205,18 @@ static void InitializeTreeView( browse_info *info )
LPCITEMIDLIST root = info->lpBrowseInfo->pidlRoot;
TRACE("%p\n", info );
Shell_GetImageLists(NULL, &hImageList);
if (hImageList)
SendMessageW( info->hwndTreeView, TVM_SETIMAGELIST, 0, (LPARAM)hImageList );
/* We want to call InsertTreeViewItem down the code, in order to insert
* the root item of the treeview. Due to InsertTreeViewItem's signature,
* the root item of the treeview. Due to InsertTreeViewItem's signature,
* we need the following to do this:
*
* + An ITEMIDLIST corresponding to _the parent_ of root.
* + An ITEMIDLIST, which is a relative path from root's parent to root
* + An ITEMIDLIST corresponding to _the parent_ of root.
* + An ITEMIDLIST, which is a relative path from root's parent to root
* (containing a single SHITEMID).
* + An IShellFolder interface pointer of root's parent folder.
*
@ -223,7 +226,7 @@ static void InitializeTreeView( browse_info *info )
pidlParent = ILClone(root);
ILRemoveLastID(pidlParent);
pidlChild = ILClone(ILFindLastID(root));
if (_ILIsDesktop(pidlParent)) {
hr = SHGetDesktopFolder(&lpsfParent);
} else {
@ -348,7 +351,7 @@ static BOOL GetName(LPSHELLFOLDER lpsf, LPCITEMIDLIST lpi, DWORD dwFlags, LPWSTR
*
* PARAMS
* info [I] data for the dialog
* lpsf [I] IShellFolder interface of the item's parent shell folder
* lpsf [I] IShellFolder interface of the item's parent shell folder
* pidl [I] ITEMIDLIST of the child to insert, relative to parent
* pidlParent [I] ITEMIDLIST of the parent shell folder
* pEnumIL [I] Iterator for the children of the item to be inserted
@ -400,7 +403,7 @@ static HTREEITEM InsertTreeViewItem( browse_info *info, IShellFolder * lpsf,
/******************************************************************************
* FillTreeView [Internal]
*
* For each child (given by lpe) of the parent shell folder, which is given by
* For each child (given by lpe) of the parent shell folder, which is given by
* lpsf and whose PIDL is pidl, insert a treeview-item right under hParent
*
* PARAMS
@ -422,7 +425,7 @@ static void FillTreeView( browse_info *info, IShellFolder * lpsf,
/* No IEnumIDList -> No children */
if (!lpe) return;
SetCapture( hwnd );
SetCursor( LoadCursorA( 0, (LPSTR)IDC_WAIT ) );
@ -615,6 +618,94 @@ 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;
}
#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;
/* 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__
BrsFolder_Delete(info, selected_item);
#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;
@ -642,6 +733,9 @@ static LRESULT BrsFolder_OnNotify( browse_info *info, UINT CtlID, LPNMHDR lpnmh
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);
break;
@ -653,6 +747,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 +814,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);
@ -891,7 +988,7 @@ static BOOL BrsFolder_OnCommand( browse_info *info, UINT id )
return FALSE;
}
static BOOL BrsFolder_OnSetExpanded(browse_info *info, LPVOID selection,
static BOOL BrsFolder_OnSetExpanded(browse_info *info, LPVOID selection,
BOOL is_str, HTREEITEM *pItem)
{
LPITEMIDLIST pidlSelection = selection;
@ -901,7 +998,7 @@ static BOOL BrsFolder_OnSetExpanded(browse_info *info, LPVOID selection,
memset(&item, 0, sizeof(item));
/* If 'selection' is a string, convert to a Shell ID List. */
/* If 'selection' is a string, convert to a Shell ID List. */
if (is_str) {
IShellFolder *psfDesktop;
HRESULT hr;
@ -910,10 +1007,10 @@ static BOOL BrsFolder_OnSetExpanded(browse_info *info, LPVOID selection,
if (FAILED(hr))
goto done;
hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL,
hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL,
selection, NULL, &pidlSelection, NULL);
IShellFolder_Release(psfDesktop);
if (FAILED(hr))
if (FAILED(hr))
goto done;
}
@ -960,16 +1057,16 @@ static BOOL BrsFolder_OnSetExpanded(browse_info *info, LPVOID selection,
}
}
if (_ILIsEmpty(pidlCurrent) && item.hItem)
if (_ILIsEmpty(pidlCurrent) && item.hItem)
bResult = TRUE;
done:
if (pidlSelection && pidlSelection != selection)
ILFree(pidlSelection);
if (pItem)
if (pItem)
*pItem = item.hItem;
return bResult;
}
@ -989,7 +1086,7 @@ static BOOL BrsFolder_OnSetSelectionA(browse_info *info, LPVOID selection, BOOL
LPWSTR selectionW = NULL;
BOOL result = FALSE;
int length;
if (!is_str)
return BrsFolder_OnSetSelectionW(info, selection, is_str);
@ -1024,9 +1121,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,19 +1237,15 @@ 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);
}
return FALSE;
}
#ifndef __REACTOS__
static const WCHAR swBrowseTemplateName[] = {
'S','H','B','R','S','F','O','R','F','O','L','D','E','R','_','M','S','G','B','O','X',0};
static const WCHAR swNewBrowseTemplateName[] = {
'S','H','N','E','W','B','R','S','F','O','R','F','O','L','D','E','R','_','M','S','G','B','O','X',0};
#endif
/*************************************************************************
* SHBrowseForFolderA [SHELL32.@]
* SHBrowseForFolder [SHELL32.@]
@ -1184,7 +1330,7 @@ LPITEMIDLIST WINAPI SHBrowseForFolderW (LPBROWSEINFOW lpbi)
wDlgId = IDD_BROWSE_FOR_FOLDER;
r = DialogBoxParamW( shell32_hInstance, MAKEINTRESOURCEW(wDlgId), lpbi->hwndOwner,
BrsFolderDlgProc, (LPARAM)&info );
if (SUCCEEDED(hr))
if (SUCCEEDED(hr))
OleUninitialize();
if (!r)
{