[SHELL32] SHBrowseForFolder: Refactor brsfolder.c (#6903)

dll/win32/shell32/wine/brsfolder.c.
This file is too hard to read. Nobody reads.
And WineHQ doesn't show no progress
recently in this file. OUT OF DATE!
JIRA issue: CORE-17340
- Rewrite some SendMessageW code by
  using TreeView_... macros.
- Add BrsFolder_GetDataFromItem helper
  function and use it.
This commit is contained in:
Katayama Hirofumi MZ 2024-05-18 20:42:22 +09:00 committed by GitHub
parent a0eec982ce
commit ae02934445
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -18,7 +18,6 @@
* FIXME:
* - many memory leaks
* - many flags unimplemented
* - implement editbox
*/
#define WIN32_NO_STATUS
@ -39,24 +38,13 @@
#include "shell32_main.h"
#include "shresdef.h"
#ifdef __REACTOS__
#include <shlwapi.h>
#include "ui/layout.h" /* Resizable window */
#endif
#include <shlwapi.h>
#include "ui/layout.h" /* Resizable window */
WINE_DEFAULT_DEBUG_CHANNEL(shell);
#define SHV_CHANGE_NOTIFY (WM_USER + 0x1111)
#ifndef __REACTOS__ /* Defined in "layout.h" */
/* original margins and control size */
typedef struct tagLAYOUT_DATA
{
LONG left, width, right;
LONG top, height, bottom;
} LAYOUT_DATA;
#endif
typedef struct tagbrowse_info
{
HWND hWnd;
@ -76,28 +64,12 @@ typedef struct tagTV_ITEMDATA
IEnumIDList* pEnumIL; /* Children iterator */
} TV_ITEMDATA, *LPTV_ITEMDATA;
#ifndef __REACTOS__ /* Defined in "layout.h" */
typedef struct tagLAYOUT_INFO
{
int iItemId; /* control id */
DWORD dwAnchor; /* BF_* flags specifying which margins should remain constant */
} LAYOUT_INFO;
#endif
static const LAYOUT_INFO g_layout_info[] =
{
{IDC_BROWSE_FOR_FOLDER_TITLE, BF_TOP|BF_LEFT|BF_RIGHT},
{IDC_BROWSE_FOR_FOLDER_STATUS, BF_TOP|BF_LEFT|BF_RIGHT},
#ifndef __REACTOS__ /* Duplicated */
{IDC_BROWSE_FOR_FOLDER_FOLDER, BF_TOP|BF_LEFT|BF_RIGHT},
#endif
{IDC_BROWSE_FOR_FOLDER_TREEVIEW, BF_TOP|BF_BOTTOM|BF_LEFT|BF_RIGHT},
#ifdef __REACTOS__
{IDC_BROWSE_FOR_FOLDER_FOLDER_TEXT, BF_TOP|BF_LEFT|BF_RIGHT},
#else
{IDC_BROWSE_FOR_FOLDER_FOLDER, BF_BOTTOM|BF_LEFT},
{IDC_BROWSE_FOR_FOLDER_FOLDER_TEXT, BF_BOTTOM|BF_LEFT|BF_RIGHT},
#endif
{IDC_BROWSE_FOR_FOLDER_NEW_FOLDER, BF_BOTTOM|BF_LEFT},
{IDOK, BF_BOTTOM|BF_RIGHT},
{IDCANCEL, BF_BOTTOM|BF_RIGHT}
@ -131,70 +103,16 @@ static void browsefolder_callback( LPBROWSEINFOW lpBrowseInfo, HWND hWnd,
lpBrowseInfo->lpfn( hWnd, msg, param, lpBrowseInfo->lParam );
}
#ifndef __REACTOS__ /* Defined in "layout.h" */
static LAYOUT_DATA *LayoutInit(HWND hwnd, const LAYOUT_INFO *layout_info, int layout_count)
static LPTV_ITEMDATA
BrsFolder_GetDataFromItem(browse_info *info, HTREEITEM hItem)
{
LAYOUT_DATA *data;
RECT rcWnd;
int i;
GetClientRect(hwnd, &rcWnd);
data = SHAlloc(sizeof(LAYOUT_DATA)*layout_count);
for (i = 0; i < layout_count; i++)
{
RECT r;
HWND hItem = GetDlgItem(hwnd, layout_info[i].iItemId);
if (hItem == NULL)
ERR("Item %d not found\n", i);
GetWindowRect(hItem, &r);
MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&r, 2);
data[i].left = r.left;
data[i].right = rcWnd.right - r.right;
data[i].width = r.right - r.left;
data[i].top = r.top;
data[i].bottom = rcWnd.bottom - r.bottom;
data[i].height = r.bottom - r.top;
}
return data;
TVITEMW item = { TVIF_HANDLE | TVIF_PARAM };
item.hItem = hItem;
if (!TreeView_GetItem(info->hwndTreeView, &item))
ERR("TreeView_GetItem failed\n");
return (LPTV_ITEMDATA)item.lParam;
}
static void LayoutUpdate(HWND hwnd, LAYOUT_DATA *data, const LAYOUT_INFO *layout_info, int layout_count)
{
RECT rcWnd;
int i;
GetClientRect(hwnd, &rcWnd);
for (i = 0; i < layout_count; i++)
{
RECT r;
HWND hItem = GetDlgItem(hwnd, layout_info[i].iItemId);
GetWindowRect(hItem, &r);
MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&r, 2);
if (layout_info[i].dwAnchor & BF_RIGHT)
{
r.right = rcWnd.right - data[i].right;
if (!(layout_info[i].dwAnchor & BF_LEFT))
r.left = r.right - data[i].width;
}
if (layout_info[i].dwAnchor & BF_BOTTOM)
{
r.bottom = rcWnd.bottom - data[i].bottom;
if (!(layout_info[i].dwAnchor & BF_TOP))
r.top = r.bottom - data[i].height;
}
SetWindowPos(hItem, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER);
}
}
#endif
/******************************************************************************
* InitializeTreeView [Internal]
*
@ -220,7 +138,7 @@ static void InitializeTreeView( browse_info *info )
Shell_GetImageLists(NULL, &hImageList);
if (hImageList)
SendMessageW( info->hwndTreeView, TVM_SETIMAGELIST, 0, (LPARAM)hImageList );
TreeView_SetImageList(info->hwndTreeView, hImageList, 0);
/* We want to call InsertTreeViewItem down the code, in order to insert
* the root item of the treeview. Due to InsertTreeViewItem's signature,
@ -286,10 +204,10 @@ static void InitializeTreeView( browse_info *info )
return;
}
SendMessageW( info->hwndTreeView, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT );
TreeView_DeleteItem(info->hwndTreeView, TVI_ROOT);
item = InsertTreeViewItem( info, lpsfParent, pidlChild,
pidlParent, pEnumChildren, TVI_ROOT );
SendMessageW( info->hwndTreeView, TVM_EXPAND, TVE_EXPAND, (LPARAM)item );
TreeView_Expand(info->hwndTreeView, item, TVE_EXPAND);
ILFree(pidlChild);
ILFree(pidlParent);
@ -465,17 +383,11 @@ static void FillTreeView( browse_info *info, IShellFolder * lpsf,
IShellFolder_Release(pSFChild);
}
}
#ifdef __REACTOS__
if (ulAttrs != (ulAttrs & SFGAO_FOLDER))
{
if (!InsertTreeViewItem(info, lpsf, pidlTemp, pidl, pEnumIL, hParent))
goto done;
}
#else
if (!InsertTreeViewItem(info, lpsf, pidlTemp, pidl, pEnumIL, hParent))
goto done;
#endif
SHFree(pidlTemp); /* Finally, free the pidl that the shell gave us... */
pidlTemp=NULL;
}
@ -574,8 +486,7 @@ static LRESULT BrsFolder_Treeview_Expand( browse_info *info, NMTREEVIEWW *pnmtv
/* My Computer is already sorted and trying to do a simple text
* sort will only mess things up */
if (!_ILIsMyComputer(lptvid->lpi))
SendMessageW( info->hwndTreeView, TVM_SORTCHILDREN,
FALSE, (LPARAM)pnmtv->itemNew.hItem );
TreeView_SortChildren(info->hwndTreeView, pnmtv->itemNew.hItem, FALSE);
return 0;
}
@ -607,10 +518,8 @@ static LRESULT BrsFolder_Treeview_Rename(browse_info *info, NMTVDISPINFOW *pnmtv
if(!pnmtv->item.pszText)
return 0;
item.mask = TVIF_HANDLE|TVIF_PARAM;
item.hItem = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_CARET, 0);
SendMessageW(info->hwndTreeView, TVM_GETITEMW, 0, (LPARAM)&item);
item_data = (LPTV_ITEMDATA)item.lParam;
item.hItem = TreeView_GetSelection(info->hwndTreeView);
item_data = BrsFolder_GetDataFromItem(info, item.hItem);
SHGetPathFromIDListW(item_data->lpifq, old_path);
if(!(p = strrchrW(old_path, '\\')))
@ -628,40 +537,31 @@ static LRESULT BrsFolder_Treeview_Rename(browse_info *info, NMTVDISPINFOW *pnmtv
IShellFolder_ParseDisplayName(item_data->lpsfParent, NULL, NULL,
pnmtv->item.pszText, NULL, &item_data->lpi, NULL);
item.mask = TVIF_HANDLE|TVIF_TEXT;
item.mask = TVIF_HANDLE | TVIF_TEXT;
item.pszText = pnmtv->item.pszText;
SendMessageW(info->hwndTreeView, TVM_SETITEMW, 0, (LPARAM)&item);
TreeView_SetItem(info->hwndTreeView, &item);
nmtv.itemNew.lParam = item.lParam;
BrsFolder_Treeview_Changed(info, &nmtv);
return 0;
}
static HRESULT BrsFolder_Rename(browse_info *info, HTREEITEM rename)
static HRESULT BrsFolder_Rename(browse_info *info, HTREEITEM hItem)
{
SendMessageW(info->hwndTreeView, TVM_SELECTITEM, TVGN_CARET, (LPARAM)rename);
SendMessageW(info->hwndTreeView, TVM_EDITLABELW, 0, (LPARAM)rename);
TreeView_SelectItem(info->hwndTreeView, hItem);
TreeView_EditLabel(info->hwndTreeView, hItem);
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;
item_data = BrsFolder_GetDataFromItem(info, selected_item);
/* get the path */
if (!SHGetPathFromIDListW(item_data->lpifq, szzFrom))
@ -677,20 +577,16 @@ BrsFolder_Delete(browse_info *info, HTREEITEM selected_item)
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 */
#ifdef __REACTOS__
if (!(info->lpBrowseInfo->ulFlags & BIF_USENEWUI))
#else
if (!(info->lpBrowseInfo->ulFlags & BIF_NEWDIALOGSTYLE))
#endif
return 0;
selected_item = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_CARET, 0);
selected_item = TreeView_GetSelection(info->hwndTreeView);
switch (keydown->wVKey)
{
@ -698,32 +594,7 @@ static LRESULT BrsFolder_Treeview_Keydown(browse_info *info, LPNMTVKEYDOWN keydo
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
}
BrsFolder_Delete(info, selected_item);
break;
}
return 0;
@ -782,15 +653,10 @@ static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
if (lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS)
FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS);
#ifdef __REACTOS__
if (lpBrowseInfo->ulFlags & BIF_USENEWUI)
#else
if (lpBrowseInfo->ulFlags & BIF_NEWDIALOGSTYLE)
#endif
{
RECT rcWnd;
#ifdef __REACTOS__
/* Resize the treeview if there's not editbox */
if ((lpBrowseInfo->ulFlags & BIF_NEWDIALOGSTYLE)
&& !(lpBrowseInfo->ulFlags & BIF_EDITBOX))
@ -811,9 +677,6 @@ static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
info->layout = LayoutInit(hWnd, g_layout_info, LAYOUT_INFO_COUNT);
else
info->layout = NULL;
#else
info->layout = LayoutInit(hWnd, g_layout_info, LAYOUT_INFO_COUNT);
#endif
/* TODO: Windows allows shrinking the windows a bit */
GetWindowRect(hWnd, &rcWnd);
@ -831,11 +694,7 @@ static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
ShowWindow( GetDlgItem(hWnd, IDC_BROWSE_FOR_FOLDER_TITLE), SW_HIDE );
if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT)
#ifdef __REACTOS__
|| (lpBrowseInfo->ulFlags & BIF_USENEWUI))
#else
|| (lpBrowseInfo->ulFlags & BIF_NEWDIALOGSTYLE))
#endif
ShowWindow( GetDlgItem(hWnd, IDC_BROWSE_FOR_FOLDER_STATUS), SW_HIDE );
/* Hide "Make New Folder" Button? */
@ -854,18 +713,6 @@ static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
if (info->hwndTreeView)
{
InitializeTreeView( info );
#ifndef __REACTOS__
/* Resize the treeview if there's not editbox */
if ((lpBrowseInfo->ulFlags & BIF_NEWDIALOGSTYLE)
&& !(lpBrowseInfo->ulFlags & BIF_EDITBOX))
{
RECT rc;
GetClientRect(info->hwndTreeView, &rc);
SetWindowPos(info->hwndTreeView, HWND_TOP, 0, 0,
rc.right, rc.bottom + 40, SWP_NOMOVE);
}
#endif
}
else
ERR("treeview control missing!\n");
@ -878,39 +725,28 @@ static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
info->hNotify = SHChangeNotifyRegister(hWnd, SHCNRF_InterruptLevel, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
#ifdef __REACTOS__
SetFocus(info->hwndTreeView);
#endif
browsefolder_callback( info->lpBrowseInfo, hWnd, BFFM_INITIALIZED, 0 );
#ifdef __REACTOS__
SHAutoComplete(GetDlgItem(hWnd, IDC_BROWSE_FOR_FOLDER_FOLDER_TEXT),
(SHACF_FILESYS_ONLY | SHACF_URLHISTORY | SHACF_FILESYSTEM));
return TRUE;
#else
return TRUE;
#endif
}
static HRESULT BrsFolder_NewFolder(browse_info *info)
{
DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags);
IShellFolder *desktop, *cur;
#ifdef __REACTOS__
WCHAR wszNewFolder[25];
WCHAR path[MAX_PATH];
#else
ISFHelper *sfhelper;
#endif
WCHAR name[MAX_PATH];
HTREEITEM parent, added;
HTREEITEM hParent, hAdded;
LPTV_ITEMDATA item_data;
LPITEMIDLIST new_item;
TVITEMW item;
HRESULT hr;
int len;
#ifdef __REACTOS__
hr = SHGetDesktopFolder(&desktop);
if(FAILED(hr))
return hr;
@ -941,55 +777,22 @@ static HRESULT BrsFolder_NewFolder(browse_info *info)
len = strlenW(path);
if(len<MAX_PATH && name[len] == L'\\')
len++;
#else
if(!info->pidlRet) {
ERR("Make new folder button should be disabled\n");
return E_FAIL;
}
/* Create new directory */
hr = SHGetDesktopFolder(&desktop);
if(FAILED(hr))
return hr;
hr = IShellFolder_BindToObject(desktop, info->pidlRet, 0, &IID_IShellFolder, (void**)&cur);
IShellFolder_Release(desktop);
if(FAILED(hr))
return hr;
hr = IShellFolder_QueryInterface(cur, &IID_ISFHelper, (void**)&sfhelper);
if(FAILED(hr))
return hr;
if(!SHGetPathFromIDListW(info->pidlRet, name)) {
hr = E_FAIL;
goto cleanup;
}
len = strlenW(name);
if(len<MAX_PATH)
name[len++] = '\\';
hr = ISFHelper_GetUniqueName(sfhelper, &name[len], MAX_PATH-len);
ISFHelper_Release(sfhelper);
if(FAILED(hr))
goto cleanup;
#endif
hr = E_FAIL;
if(!CreateDirectoryW(name, NULL))
goto cleanup;
/* Update parent of newly created directory */
parent = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_CARET, 0);
if(!parent)
hParent = TreeView_GetSelection(info->hwndTreeView);
if(!hParent)
goto cleanup;
SendMessageW(info->hwndTreeView, TVM_EXPAND, TVE_EXPAND, (LPARAM)parent);
TreeView_Expand(info->hwndTreeView, hParent, TVE_EXPAND);
memset(&item, 0, sizeof(TVITEMW));
item.mask = TVIF_PARAM|TVIF_STATE;
item.hItem = parent;
SendMessageW(info->hwndTreeView, TVM_GETITEMW, 0, (LPARAM)&item);
item.hItem = hParent;
TreeView_GetItem(info->hwndTreeView, &item);
item_data = (LPTV_ITEMDATA)item.lParam;
if(!item_data)
goto cleanup;
@ -1005,19 +808,19 @@ static HRESULT BrsFolder_NewFolder(browse_info *info)
item.mask = TVIF_STATE;
item.state = TVIS_EXPANDEDONCE;
item.stateMask = TVIS_EXPANDEDONCE;
SendMessageW(info->hwndTreeView, TVM_SETITEMW, 0, (LPARAM)&item);
TreeView_SetItem(info->hwndTreeView, &item);
}
hr = IShellFolder_ParseDisplayName(cur, NULL, NULL, name+len, NULL, &new_item, NULL);
if(FAILED(hr))
goto cleanup;
added = InsertTreeViewItem(info, cur, new_item, item_data->lpifq, NULL, parent);
hAdded = InsertTreeViewItem(info, cur, new_item, item_data->lpifq, NULL, hParent);
IShellFolder_Release(cur);
SHFree(new_item);
SendMessageW(info->hwndTreeView, TVM_SORTCHILDREN, FALSE, (LPARAM)parent);
return BrsFolder_Rename(info, added);
TreeView_SortChildren(info->hwndTreeView, hParent, FALSE);
return BrsFolder_Rename(info, hAdded);
cleanup:
return hr;
@ -1026,14 +829,11 @@ cleanup:
static BOOL BrsFolder_OnCommand( browse_info *info, UINT id )
{
LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
#ifdef __REACTOS__
WCHAR szPath[MAX_PATH];
#endif
switch (id)
{
case IDOK:
#ifdef __REACTOS__
/* Get the text */
GetDlgItemTextW(info->hWnd, IDC_BROWSE_FOR_FOLDER_FOLDER_TEXT, szPath, _countof(szPath));
StrTrimW(szPath, L" \t");
@ -1048,12 +848,10 @@ static BOOL BrsFolder_OnCommand( browse_info *info, UINT id )
{
info->pidlRet = ILClone(info->pidlRet);
}
#endif
if (info->pidlRet == NULL) /* A null pidl would mean a cancel */
info->pidlRet = _ILCreateDesktop();
pdump( info->pidlRet );
if (lpBrowseInfo->pszDisplayName)
#ifdef __REACTOS__
{
SHFILEINFOW fileInfo = { NULL };
lpBrowseInfo->pszDisplayName[0] = UNICODE_NULL;
@ -1063,9 +861,6 @@ static BOOL BrsFolder_OnCommand( browse_info *info, UINT id )
lstrcpynW(lpBrowseInfo->pszDisplayName, fileInfo.szDisplayName, MAX_PATH);
}
}
#else
SHGetPathFromIDListW( info->pidlRet, lpBrowseInfo->pszDisplayName );
#endif
EndDialog( info->hWnd, 1 );
return TRUE;
@ -1105,14 +900,12 @@ static BOOL BrsFolder_OnSetExpanded(browse_info *info, LPVOID selection,
if (FAILED(hr))
goto done;
}
#ifdef __REACTOS__
if (_ILIsDesktop(pidlSelection))
{
item.hItem = TVI_ROOT;
bResult = TRUE;
goto done;
}
#endif
/* Move pidlCurrent behind the SHITEMIDs in pidlSelection, which are the root of
* the sub-tree currently displayed. */
@ -1129,17 +922,16 @@ static BOOL BrsFolder_OnSetExpanded(browse_info *info, LPVOID selection,
/* Initialize item to point to the first child of the root folder. */
item.mask = TVIF_PARAM;
item.hItem = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_ROOT, 0);
item.hItem = TreeView_GetRoot(info->hwndTreeView);
if (item.hItem)
item.hItem = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_CHILD,
(LPARAM)item.hItem);
item.hItem = TreeView_GetChild(info->hwndTreeView, item.hItem);
/* Walk the tree along the nodes corresponding to the remaining ITEMIDLIST */
while (item.hItem && !_ILIsEmpty(pidlCurrent)) {
LPTV_ITEMDATA pItemData;
SendMessageW(info->hwndTreeView, TVM_GETITEMW, 0, (LPARAM)&item);
TreeView_GetItem(info->hwndTreeView, &item);
pItemData = (LPTV_ITEMDATA)item.lParam;
if (_ILIsEqualSimple(pItemData->lpi, pidlCurrent)) {
@ -1147,13 +939,11 @@ static BOOL BrsFolder_OnSetExpanded(browse_info *info, LPVOID selection,
if (!_ILIsEmpty(pidlCurrent)) {
/* Only expand current node and move on to its first child,
* if we didn't already reach the last SHITEMID */
SendMessageW(info->hwndTreeView, TVM_EXPAND, TVE_EXPAND, (LPARAM)item.hItem);
item.hItem = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_CHILD,
(LPARAM)item.hItem);
TreeView_Expand(info->hwndTreeView, item.hItem, TVE_EXPAND);
item.hItem = TreeView_GetChild(info->hwndTreeView, item.hItem);
}
} else {
item.hItem = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_NEXT,
(LPARAM)item.hItem);
item.hItem = TreeView_GetNextSibling(info->hwndTreeView, item.hItem);
}
}
@ -1178,7 +968,7 @@ static BOOL BrsFolder_OnSetSelectionW(browse_info *info, LPVOID selection, BOOL
bResult = BrsFolder_OnSetExpanded(info, selection, is_str, &hItem);
if (bResult)
SendMessageW(info->hwndTreeView, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItem );
TreeView_SelectItem(info->hwndTreeView, hItem);
return bResult;
}
@ -1201,33 +991,11 @@ static BOOL BrsFolder_OnSetSelectionA(browse_info *info, LPVOID selection, BOOL
return result;
}
#ifndef __REACTOS__ /* This is a buggy way (resize on title bar) */
static LRESULT BrsFolder_OnWindowPosChanging(browse_info *info, WINDOWPOS *pos)
{
#ifdef __REACTOS__
if ((info->lpBrowseInfo->ulFlags & BIF_USENEWUI) && !(pos->flags & SWP_NOSIZE))
#else
if ((info->lpBrowseInfo->ulFlags & BIF_NEWDIALOGSTYLE) && !(pos->flags & SWP_NOSIZE))
#endif
{
if (pos->cx < info->szMin.cx)
pos->cx = info->szMin.cx;
if (pos->cy < info->szMin.cy)
pos->cy = info->szMin.cy;
}
return 0;
}
#endif
static INT BrsFolder_OnDestroy(browse_info *info)
{
if (info->layout)
{
#ifdef __REACTOS__
LayoutDestroy(info->layout);
#else
SHFree(info->layout);
#endif
info->layout = NULL;
}
@ -1239,27 +1007,23 @@ static INT BrsFolder_OnDestroy(browse_info *info)
/* 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;
item_data = BrsFolder_GetDataFromItem(info, hItem);
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);
hItem = TreeView_GetChild(info->hwndTreeView, 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);
hItem = TreeView_GetNextSibling(info->hwndTreeView, hItem);
}
return NULL;
}
@ -1275,12 +1039,10 @@ static LRESULT BrsFolder_OnChange(browse_info *info, const LPCITEMIDLIST *pidls,
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);
HTREEITEM hRoot = TreeView_GetRoot(info->hwndTreeView);
HTREEITEM hItem = BrsFolder_FindItemByPidl(info, pidls[0], hRoot);
if (hItem)
TreeView_DeleteItem(info->hwndTreeView, hItem);
break;
}
}
@ -1310,15 +1072,10 @@ static INT_PTR CALLBACK BrsFolderDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
case WM_COMMAND:
return BrsFolder_OnCommand( info, wParam );
#ifdef __REACTOS__
case WM_GETMINMAXINFO:
((LPMINMAXINFO)lParam)->ptMinTrackSize.x = info->szMin.cx;
((LPMINMAXINFO)lParam)->ptMinTrackSize.y = info->szMin.cy;
return 0;
#else /* This is a buggy way (resize on title bar) */
case WM_WINDOWPOSCHANGING:
return BrsFolder_OnWindowPosChanging( info, (WINDOWPOS *)lParam);
#endif
case WM_SIZE:
if (info->layout) /* new style dialogs */
@ -1409,7 +1166,6 @@ LPITEMIDLIST WINAPI SHBrowseForFolderA (LPBROWSEINFOA lpbi)
return lpid;
}
/*************************************************************************
* SHBrowseForFolderW [SHELL32.@]
*
@ -1419,42 +1175,26 @@ LPITEMIDLIST WINAPI SHBrowseForFolderA (LPBROWSEINFOA lpbi)
LPITEMIDLIST WINAPI SHBrowseForFolderW (LPBROWSEINFOW lpbi)
{
browse_info info;
DWORD r;
INT_PTR r;
HRESULT hr;
#ifdef __REACTOS__
WORD wDlgId;
#else
const WCHAR * templateName;
INITCOMMONCONTROLSEX icex;
#endif
info.hWnd = 0;
info.hWnd = NULL;
info.pidlRet = NULL;
info.lpBrowseInfo = lpbi;
info.hwndTreeView = NULL;
#ifdef __REACTOS__
info.layout = NULL;
#else
icex.dwSize = sizeof( icex );
icex.dwICC = ICC_TREEVIEW_CLASSES;
InitCommonControlsEx( &icex );
#endif
hr = OleInitialize(NULL);
#ifdef __REACTOS__
if (lpbi->ulFlags & BIF_USENEWUI)
#else
if (lpbi->ulFlags & BIF_NEWDIALOGSTYLE)
#endif
wDlgId = IDD_BROWSE_FOR_FOLDER_NEW;
else
wDlgId = IDD_BROWSE_FOR_FOLDER;
r = DialogBoxParamW( shell32_hInstance, MAKEINTRESOURCEW(wDlgId), lpbi->hwndOwner,
BrsFolderDlgProc, (LPARAM)&info );
if (SUCCEEDED(hr))
wDlgId = ((lpbi->ulFlags & BIF_USENEWUI) ? IDD_BROWSE_FOR_FOLDER_NEW : IDD_BROWSE_FOR_FOLDER);
r = DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(wDlgId), lpbi->hwndOwner,
BrsFolderDlgProc, (LPARAM)&info );
if (SUCCEEDED(hr))
OleUninitialize();
if (!r)
{
ILFree(info.pidlRet);