SHELL32: remove static variables in SHBrowseForFolder implementation
Mike McCormack
mike at codeweavers.com
Thu Apr 28 11:16:12 CDT 2005
ChangeLog:
* remove static variables in SHBrowseForFolder implementation
-------------- next part --------------
--- dlls/shell32/brsfolder.c.1 2005-04-28 22:55:59.000000000 +0900
+++ dlls/shell32/brsfolder.c 2005-04-29 01:13:15.000000000 +0900
@@ -37,11 +37,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
-static HWND hwndTreeView;
-static LPBROWSEINFOW lpBrowseInfo;
-static LPITEMIDLIST pidlRet;
+typedef struct tagbrowse_info
+{
+ HWND hWnd;
+ HWND hwndTreeView;
+ LPBROWSEINFOW lpBrowseInfo;
+ LPITEMIDLIST pidlRet;
+} browse_info;
-typedef struct tagID
+typedef struct tagTV_ITEMDATA
{
LPSHELLFOLDER lpsfParent; /* IShellFolder of the parent */
LPITEMIDLIST lpi; /* PIDL relativ to parent */
@@ -49,20 +53,36 @@ typedef struct tagID
IEnumIDList* pEnumIL; /* Children iterator */
} TV_ITEMDATA, *LPTV_ITEMDATA;
-static void FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq, HTREEITEM hParent, IEnumIDList* lpe);
-static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent);
-
#define SUPPORTEDFLAGS (BIF_STATUSTEXT | \
BIF_BROWSEFORCOMPUTER | \
BIF_RETURNFSANCESTORS | \
BIF_RETURNONLYFSDIRS | \
BIF_BROWSEINCLUDEFILES)
+static void FillTreeView(browse_info*, LPSHELLFOLDER,
+ LPITEMIDLIST, HTREEITEM, IEnumIDList*);
+static HTREEITEM InsertTreeViewItem( browse_info*, IShellFolder *,
+ LPCITEMIDLIST, LPCITEMIDLIST, IEnumIDList*, HTREEITEM);
+
+const WCHAR szBrowseFolderInfo[] = {
+ '_','_','W','I','N','E','_',
+ 'B','R','S','F','O','L','D','E','R','D','L','G','_',
+ 'I','N','F','O',0
+};
+
static inline DWORD BrowseFlagsToSHCONTF(UINT ulFlags)
{
return SHCONTF_FOLDERS | (ulFlags & BIF_BROWSEINCLUDEFILES ? SHCONTF_NONFOLDERS : 0);
}
+static void browsefolder_callback( LPBROWSEINFOW lpBrowseInfo, HWND hWnd,
+ UINT msg, LPARAM param )
+{
+ if (!lpBrowseInfo->lpfn)
+ return;
+ lpBrowseInfo->lpfn( hWnd, BFFM_INITIALIZED, param, lpBrowseInfo->lParam );
+}
+
/******************************************************************************
* InitializeTreeView [Internal]
*
@@ -72,25 +92,23 @@ static inline DWORD BrowseFlagsToSHCONTF
* hwndParent [I] The BrowseForFolder dialog
* root [I] ITEMIDLIST of the root shell folder
*/
-static void InitializeTreeView(HWND hwndParent, LPCITEMIDLIST root)
+static void InitializeTreeView( browse_info *info )
{
LPITEMIDLIST pidlParent, pidlChild;
HIMAGELIST hImageList;
HRESULT hr;
IShellFolder *lpsfParent, *lpsfRoot;
IEnumIDList * pEnumChildren = NULL;
+ HTREEITEM item;
+ DWORD flags;
+ LPCITEMIDLIST root = info->lpBrowseInfo->pidlRoot;
- TRACE("dlg=%p tree=%p\n", hwndParent, hwndTreeView );
+ TRACE("%p\n", info );
- hwndTreeView = GetDlgItem (hwndParent, IDD_TREEVIEW);
- if (!hwndTreeView) {
- FIXME("Could not get handle to treeview control! Error: %08lx\n", GetLastError());
- return;
- }
Shell_GetImageList(NULL, &hImageList);
if (hImageList)
- TreeView_SetImageList(hwndTreeView, hImageList, 0);
+ 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,
@@ -139,7 +157,8 @@ static void InitializeTreeView(HWND hwnd
return;
}
- hr = IShellFolder_EnumObjects(lpsfRoot, hwndParent, BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags), &pEnumChildren);
+ flags = BrowseFlagsToSHCONTF( info->lpBrowseInfo->ulFlags );
+ hr = IShellFolder_EnumObjects( lpsfRoot, info->hWnd, flags, &pEnumChildren );
if (!SUCCEEDED(hr)) {
WARN("Could not get child iterator! hr = %08lx\n", hr);
IShellFolder_Release(lpsfParent);
@@ -147,8 +166,10 @@ static void InitializeTreeView(HWND hwnd
return;
}
- TreeView_DeleteAllItems(hwndTreeView);
- TreeView_Expand(hwndTreeView, InsertTreeViewItem(lpsfParent, pidlChild, pidlParent, pEnumChildren, TVI_ROOT), TVE_EXPAND);
+ TreeView_DeleteAllItems( info->hwndTreeView );
+ item = InsertTreeViewItem( info, lpsfParent, pidlChild,
+ pidlParent, pEnumChildren, TVI_ROOT );
+ TreeView_Expand( info->hwndTreeView, item, TVE_EXPAND );
IShellFolder_Release(lpsfRoot);
IShellFolder_Release(lpsfParent);
@@ -156,30 +177,32 @@ static void InitializeTreeView(HWND hwnd
static int GetIcon(LPITEMIDLIST lpi, UINT uFlags)
{
- SHFILEINFOW sfi;
- SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW), uFlags);
- return sfi.iIcon;
+ SHFILEINFOW sfi;
+ SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW), uFlags);
+ return sfi.iIcon;
}
static void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTVITEMW lpTV_ITEM)
{
- LPITEMIDLIST pidlDesktop = NULL;
+ LPITEMIDLIST pidlDesktop = NULL;
+ DWORD flags;
- TRACE("%p %p\n",lpifq, lpTV_ITEM);
+ TRACE("%p %p\n",lpifq, lpTV_ITEM);
- if (!lpifq)
- {
- pidlDesktop = _ILCreateDesktop();
- lpifq = pidlDesktop;
- }
+ if (!lpifq)
+ {
+ pidlDesktop = _ILCreateDesktop();
+ lpifq = pidlDesktop;
+ }
- lpTV_ITEM->iImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
- lpTV_ITEM->iSelectedImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON);
+ flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON;
+ lpTV_ITEM->iImage = GetIcon( lpifq, flags );
- if (pidlDesktop)
- ILFree(pidlDesktop);
+ flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON;
+ lpTV_ITEM->iSelectedImage = GetIcon( lpifq, flags );
- return;
+ if (pidlDesktop)
+ ILFree( pidlDesktop );
}
/******************************************************************************
@@ -221,6 +244,7 @@ static BOOL GetName(LPSHELLFOLDER lpsf,
* InsertTreeViewItem [Internal]
*
* PARAMS
+ * info [I] data for the dialog
* lpsf [I] IShellFolder interface of the item's parent shell folder
* pidl [I] ITEMIDLIST of the child to insert, relativ to parent
* pidlParent [I] ITEMIDLIST of the parent shell folder
@@ -231,8 +255,9 @@ static BOOL GetName(LPSHELLFOLDER lpsf,
* Success: Handle to the created and inserted treeview-item
* Failure: NULL
*/
-static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl,
- LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent)
+static HTREEITEM InsertTreeViewItem( browse_info *info, IShellFolder * lpsf,
+ LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL,
+ HTREEITEM hParent)
{
TVITEMW tvi;
TVINSERTSTRUCTW tvins;
@@ -244,7 +269,8 @@ static HTREEITEM InsertTreeViewItem(IShe
tvi.cChildren= pEnumIL ? 1 : 0;
tvi.mask |= TVIF_CHILDREN;
- if (!(lptvid = (LPTV_ITEMDATA)SHAlloc(sizeof(TV_ITEMDATA))))
+ lptvid = SHAlloc( sizeof(TV_ITEMDATA) );
+ if (!lptvid)
return NULL;
if (!GetName(lpsf, pidl, SHGDN_NORMAL, szBuff))
@@ -265,7 +291,7 @@ static HTREEITEM InsertTreeViewItem(IShe
tvins.hInsertAfter = NULL;
tvins.hParent = hParent;
- return (HTREEITEM)TreeView_InsertItemW(hwndTreeView, &tvins);
+ return (HTREEITEM)TreeView_InsertItemW( info->hwndTreeView, &tvins );
}
/******************************************************************************
@@ -275,26 +301,28 @@ static HTREEITEM InsertTreeViewItem(IShe
* lpsf and whose PIDL is pidl, insert a treeview-item right under hParent
*
* PARAMS
+ * info [I] data for the dialog
* lpsf [I] IShellFolder interface of the parent shell folder
* pidl [I] ITEMIDLIST of the parent shell folder
* hParent [I] The treeview item that represents the parent shell folder
* lpe [I] An iterator for the children of the parent shell folder
*/
-static void FillTreeView(IShellFolder * lpsf, LPITEMIDLIST pidl, HTREEITEM hParent, IEnumIDList* lpe)
+static void FillTreeView( browse_info *info, IShellFolder * lpsf,
+ LPITEMIDLIST pidl, HTREEITEM hParent, IEnumIDList* lpe)
{
HTREEITEM hPrev = 0;
LPITEMIDLIST pidlTemp = 0;
ULONG ulFetched;
HRESULT hr;
- HWND hwnd=GetParent(hwndTreeView);
+ HWND hwnd = GetParent( info->hwndTreeView );
TRACE("%p %p %x %p\n",lpsf, pidl, (INT)hParent, lpe);
/* No IEnumIDList -> No children */
if (!lpe) return;
- SetCapture(GetParent(hwndTreeView));
- SetCursor(LoadCursorA(0, (LPSTR)IDC_WAIT));
+ SetCapture( hwnd );
+ SetCursor( LoadCursorA( 0, (LPSTR)IDC_WAIT ) );
while (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched))
{
@@ -307,10 +335,12 @@ static void FillTreeView(IShellFolder *
hr = IShellFolder_BindToObject(lpsf,pidlTemp,NULL,&IID_IShellFolder,(LPVOID*)&pSFChild);
if (SUCCEEDED(hr))
{
- hr = IShellFolder_EnumObjects(pSFChild, hwnd, BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags), &pEnumIL);
+ DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags);
+ hr = IShellFolder_EnumObjects(pSFChild, hwnd, flags, &pEnumIL);
if (hr == S_OK)
{
- if ((IEnumIDList_Skip(pEnumIL, 1) != S_OK) || FAILED(IEnumIDList_Reset(pEnumIL)))
+ if ((IEnumIDList_Skip(pEnumIL, 1) != S_OK) ||
+ FAILED(IEnumIDList_Reset(pEnumIL)))
{
IEnumIDList_Release(pEnumIL);
pEnumIL = NULL;
@@ -320,13 +350,13 @@ static void FillTreeView(IShellFolder *
}
}
- if (!(hPrev = InsertTreeViewItem(lpsf, pidlTemp, pidl, pEnumIL, hParent)))
- goto Done;
+ if (!(hPrev = InsertTreeViewItem(info, lpsf, pidlTemp, pidl, pEnumIL, hParent)))
+ goto done;
SHFree(pidlTemp); /* Finally, free the pidl that the shell gave us... */
pidlTemp=NULL;
}
-Done:
+done:
ReleaseCapture();
SetCursor(LoadCursorW(0, (LPWSTR)IDC_ARROW));
@@ -342,8 +372,9 @@ static inline BOOL PIDLIsType(LPCITEMIDL
return (data->type == type);
}
-static void BrsFolder_CheckValidSelection(HWND hWndTree, LPTV_ITEMDATA lptvid)
+static void BrsFolder_CheckValidSelection( browse_info *info, LPTV_ITEMDATA lptvid )
{
+ LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
LPCITEMIDLIST pidl = lptvid->lpi;
BOOL bEnabled = TRUE;
DWORD dwAttributes;
@@ -368,10 +399,10 @@ static void BrsFolder_CheckValidSelectio
if (FAILED(r) || (dwAttributes != (SFGAO_FOLDER | SFGAO_FILESYSTEM)))
bEnabled = FALSE;
}
- SendMessageW(hWndTree, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
+ SendMessageW(info->hWnd, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
}
-static LRESULT BrsFolder_Treeview_Delete( NMTREEVIEWW *pnmtv )
+static LRESULT BrsFolder_Treeview_Delete( browse_info *info, NMTREEVIEWW *pnmtv )
{
LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA)pnmtv->itemOld.lParam;
@@ -386,7 +417,7 @@ static LRESULT BrsFolder_Treeview_Delete
return 0;
}
-static LRESULT BrsFolder_Treeview_Expand( NMTREEVIEWW *pnmtv )
+static LRESULT BrsFolder_Treeview_Expand( browse_info *info, NMTREEVIEWW *pnmtv )
{
IShellFolder *lpsf2 = NULL;
LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
@@ -400,33 +431,33 @@ static LRESULT BrsFolder_Treeview_Expand
r = IShellFolder_BindToObject( lptvid->lpsfParent, lptvid->lpi, 0,
(REFIID)&IID_IShellFolder, (LPVOID *)&lpsf2 );
if (SUCCEEDED(r))
- FillTreeView( lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL);
+ FillTreeView( info, lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL);
/* My Computer is already sorted and trying to do a simple text
* sort will only mess things up */
if (!_ILIsMyComputer(lptvid->lpi))
- TreeView_SortChildren(hwndTreeView, pnmtv->itemNew.hItem, FALSE);
+ TreeView_SortChildren(info->hwndTreeView, pnmtv->itemNew.hItem, FALSE);
return 0;
}
-static HRESULT BrsFolder_Treeview_Changed( HWND hWnd, NMTREEVIEWW *pnmtv )
+static HRESULT BrsFolder_Treeview_Changed( browse_info *info, NMTREEVIEWW *pnmtv )
{
LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
- pidlRet = lptvid->lpifq;
- if (lpBrowseInfo->lpfn)
- (lpBrowseInfo->lpfn)(hWnd, BFFM_SELCHANGED, (LPARAM)pidlRet, lpBrowseInfo->lParam);
- BrsFolder_CheckValidSelection(hWnd, lptvid);
+ info->pidlRet = lptvid->lpifq;
+ browsefolder_callback( info->lpBrowseInfo, info->hWnd, BFFM_SELCHANGED,
+ (LPARAM)info->pidlRet );
+ BrsFolder_CheckValidSelection( info, lptvid );
return 0;
}
-static LRESULT BrsFolder_OnNotify( HWND hWnd, UINT CtlID, LPNMHDR lpnmh )
+static LRESULT BrsFolder_OnNotify( browse_info *info, UINT CtlID, LPNMHDR lpnmh )
{
NMTREEVIEWW *pnmtv = (NMTREEVIEWW *)lpnmh;
- TRACE("%p %x %p msg=%x\n", hWnd, CtlID, lpnmh, pnmtv->hdr.code);
+ TRACE("%p %x %p msg=%x\n", info, CtlID, lpnmh, pnmtv->hdr.code);
if (pnmtv->hdr.idFrom != IDD_TREEVIEW)
return 0;
@@ -435,15 +466,15 @@ static LRESULT BrsFolder_OnNotify( HWND
{
case TVN_DELETEITEMA:
case TVN_DELETEITEMW:
- return BrsFolder_Treeview_Delete( pnmtv );
+ return BrsFolder_Treeview_Delete( info, pnmtv );
case TVN_ITEMEXPANDINGA:
case TVN_ITEMEXPANDINGW:
- return BrsFolder_Treeview_Expand( pnmtv );
+ return BrsFolder_Treeview_Expand( info, pnmtv );
case TVN_SELCHANGEDA:
case TVN_SELCHANGEDW:
- return BrsFolder_Treeview_Changed( hWnd, pnmtv );
+ return BrsFolder_Treeview_Changed( info, pnmtv );
default:
WARN("unhandled (%d)\n", pnmtv->hdr.code);
@@ -454,10 +485,12 @@ static LRESULT BrsFolder_OnNotify( HWND
}
-static BOOL BrsFolder_OnCreate( HWND hWnd, LPBROWSEINFOW lpbi )
+static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
{
- pidlRet = NULL;
- lpBrowseInfo = lpbi;
+ LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
+
+ info->hWnd = hWnd;
+ SetPropW( hWnd, szBrowseFolderInfo, info );
if (lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS)
FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS);
@@ -470,27 +503,32 @@ static BOOL BrsFolder_OnCreate( HWND hWn
if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT))
ShowWindow( GetDlgItem(hWnd, IDD_STATUS), SW_HIDE );
- InitializeTreeView( hWnd, lpBrowseInfo->pidlRoot );
+ info->hwndTreeView = GetDlgItem( hWnd, IDD_TREEVIEW );
+ if (info->hwndTreeView)
+ InitializeTreeView( info );
+ else
+ ERR("treeview control missing!\n");
- if (lpBrowseInfo->lpfn)
- (lpBrowseInfo->lpfn)( hWnd, BFFM_INITIALIZED, 0, lpBrowseInfo->lParam );
+ browsefolder_callback( info->lpBrowseInfo, hWnd, BFFM_INITIALIZED, 0 );
return TRUE;
}
-static BOOL BrsFolder_OnCommand( HWND hWnd, UINT id )
+static BOOL BrsFolder_OnCommand( browse_info *info, UINT id )
{
+ LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
+
switch (id)
{
case IDOK:
- pdump( pidlRet );
+ pdump( info->pidlRet );
if (lpBrowseInfo->pszDisplayName)
- SHGetPathFromIDListW( pidlRet, lpBrowseInfo->pszDisplayName );
- EndDialog(hWnd, (DWORD) ILClone(pidlRet));
+ SHGetPathFromIDListW( info->pidlRet, lpBrowseInfo->pszDisplayName );
+ EndDialog( info->hWnd, 1 );
return TRUE;
case IDCANCEL:
- EndDialog(hWnd, 0);
+ EndDialog( info->hWnd, 0 );
return TRUE;
}
return FALSE;
@@ -502,18 +540,22 @@ static BOOL BrsFolder_OnCommand( HWND hW
static INT_PTR CALLBACK BrsFolderDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam )
{
+ browse_info *info;
+
TRACE("hwnd=%p msg=%04x 0x%08x 0x%08lx\n", hWnd, msg, wParam, lParam );
if (msg == WM_INITDIALOG)
- return BrsFolder_OnCreate( hWnd, (LPBROWSEINFOW) lParam );
+ return BrsFolder_OnCreate( hWnd, (browse_info*) lParam );
+
+ info = (browse_info*) GetPropW( hWnd, szBrowseFolderInfo );
switch (msg)
{
case WM_NOTIFY:
- return BrsFolder_OnNotify( hWnd, (UINT)wParam, (LPNMHDR)lParam);
+ return BrsFolder_OnNotify( info, (UINT)wParam, (LPNMHDR)lParam);
case WM_COMMAND:
- return BrsFolder_OnCommand( hWnd, wParam );
+ return BrsFolder_OnCommand( info, wParam );
case BFFM_SETSTATUSTEXTA:
TRACE("Set status %s\n", debugstr_a((LPSTR)lParam));
@@ -559,7 +601,7 @@ static INT_PTR CALLBACK BrsFolderDlgProc
return FALSE;
}
-static const WCHAR swBrowseTempName[] = {
+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};
/*************************************************************************
@@ -568,66 +610,71 @@ static const WCHAR swBrowseTempName[] =
*/
LPITEMIDLIST WINAPI SHBrowseForFolderA (LPBROWSEINFOA lpbi)
{
- BROWSEINFOW bi;
- LPITEMIDLIST lpid;
- INT len;
-
- TRACE("(%p{lpszTitle=%s,owner=%p})\n", lpbi,
- lpbi ? debugstr_a(lpbi->lpszTitle) : NULL, lpbi ? lpbi->hwndOwner : NULL);
-
- if (!lpbi)
- return NULL;
+ BROWSEINFOW bi;
+ LPITEMIDLIST lpid;
+ INT len;
+
+ TRACE("%p\n", lpbi);
- bi.hwndOwner = lpbi->hwndOwner;
- bi.pidlRoot = lpbi->pidlRoot;
- if (lpbi->pszDisplayName)
- {
- /*lpbi->pszDisplayName is assumed to be MAX_PATH (MSDN) */
- bi.pszDisplayName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
- MultiByteToWideChar(CP_ACP, 0, lpbi->pszDisplayName, -1, bi.pszDisplayName, MAX_PATH);
- }
- else
- bi.pszDisplayName = NULL;
+ bi.hwndOwner = lpbi->hwndOwner;
+ bi.pidlRoot = lpbi->pidlRoot;
+ if (lpbi->pszDisplayName)
+ {
+ len = MultiByteToWideChar( CP_ACP, 0, lpbi->pszDisplayName, -1, NULL, 0 );
+ bi.pszDisplayName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, lpbi->pszDisplayName, -1, bi.pszDisplayName, len );
+ }
+ else
+ bi.pszDisplayName = NULL;
- if (lpbi->lpszTitle)
- {
- len = MultiByteToWideChar(CP_ACP, 0, lpbi->lpszTitle, -1, NULL, 0);
- bi.lpszTitle = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
- MultiByteToWideChar(CP_ACP, 0, lpbi->lpszTitle, -1, (LPWSTR)bi.lpszTitle, len);
- }
- else
- bi.lpszTitle = NULL;
+ if (lpbi->lpszTitle)
+ {
+ len = MultiByteToWideChar( CP_ACP, 0, lpbi->lpszTitle, -1, NULL, 0 );
+ bi.lpszTitle = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, lpbi->lpszTitle, -1, (LPWSTR)bi.lpszTitle, len );
+ }
+ else
+ bi.lpszTitle = NULL;
- bi.ulFlags = lpbi->ulFlags;
- bi.lpfn = lpbi->lpfn;
- bi.lParam = lpbi->lParam;
- bi.iImage = lpbi->iImage;
- lpid = (LPITEMIDLIST) DialogBoxParamW(shell32_hInstance,
- swBrowseTempName, lpbi->hwndOwner,
- BrsFolderDlgProc, (INT)&bi);
- if (bi.pszDisplayName)
- {
- WideCharToMultiByte(CP_ACP, 0, bi.pszDisplayName, -1, lpbi->pszDisplayName, MAX_PATH, 0, NULL);
- HeapFree(GetProcessHeap(), 0, bi.pszDisplayName);
- }
- HeapFree(GetProcessHeap(), 0, (LPVOID)bi.lpszTitle);
- lpbi->iImage = bi.iImage;
- return lpid;
+ bi.ulFlags = lpbi->ulFlags;
+ bi.lpfn = lpbi->lpfn;
+ bi.lParam = lpbi->lParam;
+ bi.iImage = lpbi->iImage;
+ lpid = SHBrowseForFolderW( &bi );
+ if (bi.pszDisplayName)
+ {
+ WideCharToMultiByte( CP_ACP, 0, bi.pszDisplayName, -1,
+ lpbi->pszDisplayName, MAX_PATH, 0, NULL);
+ HeapFree( GetProcessHeap(), 0, bi.pszDisplayName );
+ }
+ HeapFree(GetProcessHeap(), 0, (LPVOID)bi.lpszTitle);
+ lpbi->iImage = bi.iImage;
+ return lpid;
}
/*************************************************************************
* SHBrowseForFolderW [SHELL32.@]
+ *
+ * NOTES:
+ * crashes when passed a null pointer
*/
LPITEMIDLIST WINAPI SHBrowseForFolderW (LPBROWSEINFOW lpbi)
{
- TRACE("((%p->{lpszTitle=%s,owner=%p})\n", lpbi,
- lpbi ? debugstr_w(lpbi->lpszTitle) : NULL, lpbi ? lpbi->hwndOwner : 0);
+ browse_info info;
+ DWORD r;
+
+ ERR("%p\n", lpbi);
- if (!lpbi)
- return NULL;
+ info.hWnd = 0;
+ info.pidlRet = NULL;
+ info.lpBrowseInfo = lpbi;
+ info.hwndTreeView = NULL;
+
+ r = DialogBoxParamW( shell32_hInstance, swBrowseTemplateName, lpbi->hwndOwner,
+ BrsFolderDlgProc, (LPARAM)&info );
+ if (!r)
+ return NULL;
- return (LPITEMIDLIST) DialogBoxParamW(shell32_hInstance,
- swBrowseTempName, lpbi->hwndOwner,
- BrsFolderDlgProc, (INT)lpbi);
+ return info.pidlRet;
}
More information about the wine-patches
mailing list