mirror of
https://github.com/reactos/reactos.git
synced 2024-09-27 21:16:34 +00:00
[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-g5c22ce3742
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-g83be315abf
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-gc30b1fe893
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-gc8e1460ac5
-------------------------------------------------------------- [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-g771457f37f
-------------------------------------------------------------- [SHELL32] Sync brsfolder.c with keyboard shortcut code from wine (#2290) 0.4.14-dev-1187-gfc4c4d4911
This commit is contained in:
parent
8f1e2880e1
commit
5d463d517b
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue