[prev in list] [next in list] [prev in thread] [next in thread]
List: wine-devel
Subject: <<PATCH>> Added shell32.dll functions to browse for unix directory;
From: Robert van Herk <robert () robertvanherk ! nl>
Date: 2004-11-30 16:20:29
Message-ID: 41AC9DCD.9070404 () robertvanherk ! nl
[Download RAW message or body]
Changes:
Added functionality to browse for a UNIX folder.
This is done by making two new funtions in dlls/shell32/brsfolder.c, namely
wine_shell_browse_for_UNIX_directoryA
wine_shell_browse_for_UNIX_directoryW
These functions are exported in shlobj.h.
The original code that allowed just for picking a Windows folder, was
split up.
It was to be found in brsfolder.c, but I split this in:
brsfolder.c
brsfolder.h
brsfolder_windows.c
brsfolder_windows.h
brsfolder_unix.c
brsfolder_unix.h
unixTools.c
unixTools.h,
Otherwise I found the code to be incomprehendible.
Furthermore, winecfg now uses the wine_shell_browse_for_UNIX_directoryA
to let the user pick a UNIX directory as root for his virtual drive
mappings.
Regards,
Robert van Herk
["patch.diff" (text/x-patch)]
? dlls/shell32/brsfolder.h
? dlls/shell32/brsfolder_unix.c
? dlls/shell32/brsfolder_unix.h
? dlls/shell32/brsfolder_windows.c
? dlls/shell32/brsfolder_windows.h
? dlls/shell32/unixTools.c
? dlls/shell32/unixTools.h
Index: dlls/shell32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/shell32/Makefile.in,v
retrieving revision 1.86
diff -u -r1.86 Makefile.in
--- dlls/shell32/Makefile.in 27 Oct 2004 00:47:53 -0000 1.86
+++ dlls/shell32/Makefile.in 30 Nov 2004 14:57:03 -0000
@@ -12,6 +12,8 @@
authors.c \
autocomplete.c \
brsfolder.c \
+ brsfolder_windows.c \
+ brsfolder_unix.c \
changenotify.c \
classes.c \
clipboard.c \
@@ -46,7 +48,8 @@
shpolicy.c \
shv_bg_cmenu.c \
shv_item_cmenu.c \
- systray.c
+ systray.c \
+ unixTools.c
RC_SRCS = shres.rc
RC_BINSRC = shres.rc
Index: dlls/shell32/brsfolder.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/brsfolder.c,v
retrieving revision 1.53
diff -u -r1.53 brsfolder.c
--- dlls/shell32/brsfolder.c 7 Oct 2004 03:06:48 -0000 1.53
+++ dlls/shell32/brsfolder.c 30 Nov 2004 14:57:03 -0000
@@ -1,5 +1,6 @@
/*
* Copyright 1999 Juergen Schmied
+ * Copyright 2004 Robert van Herk
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -35,14 +36,20 @@
#include "shellapi.h"
#include "shresdef.h"
+#include "brsfolder_windows.h"
+#include "brsfolder_unix.h"
+
+#include "brsfolder.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(shell);
-static HWND hwndTreeView;
-static LPBROWSEINFOW lpBrowseInfo;
-static LPITEMIDLIST pidlRet;
-static void FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq, HTREEITEM hParent, \
IEnumIDList* lpe);
-static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl, \
LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent); +enum browsemode \
{ + WINDOWS,
+ UNIX
+};
+
+static enum browsemode browseMode;
#define SUPPORTEDFLAGS (BIF_STATUSTEXT | \
BIF_BROWSEFORCOMPUTER | \
@@ -50,256 +57,31 @@
BIF_RETURNONLYFSDIRS | \
BIF_BROWSEINCLUDEFILES)
-static inline DWORD BrowseFlagsToSHCONTF(UINT ulFlags)
-{
- return SHCONTF_FOLDERS | (ulFlags & BIF_BROWSEINCLUDEFILES ? SHCONTF_NONFOLDERS \
: 0);
-}
-
-static void InitializeTreeView(HWND hwndParent, LPCITEMIDLIST root)
+static void InitializeTreeView(HWND hwndParent, LPBROWSEINFOW lpbi, INSERTROOT_PROC \
insertroot_proc) {
HIMAGELIST hImageList;
- IShellFolder * lpsf;
- HRESULT hr;
- IEnumIDList * pEnumIL = NULL;
- LPITEMIDLIST parentofroot;
- parentofroot = ILClone(root);
- ILRemoveLastID(parentofroot);
hwndTreeView = GetDlgItem (hwndParent, IDD_TREEVIEW);
Shell_GetImageList(NULL, &hImageList);
- TRACE("dlg=%p tree=%p\n", hwndParent, hwndTreeView );
+ TRACE("dlg=%p tree=%p\n", hwndParent, hwndTreeView);
if (hImageList && hwndTreeView)
TreeView_SetImageList(hwndTreeView, hImageList, 0);
- if (_ILIsDesktop (root)) {
- hr = SHGetDesktopFolder(&lpsf);
- } else {
- IShellFolder * lpsfdesktop;
-
- hr = SHGetDesktopFolder(&lpsfdesktop);
- if (SUCCEEDED(hr)) {
- hr = IShellFolder_BindToObject(lpsfdesktop, parentofroot, \
0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf);
- IShellFolder_Release(lpsfdesktop);
- }
- }
- if (SUCCEEDED(hr))
- {
- IShellFolder * pSFRoot;
- if (_ILIsPidlSimple(root))
- {
- pSFRoot = lpsf;
- IShellFolder_AddRef(pSFRoot);
- }
- else
- hr = IShellFolder_BindToObject(lpsf,ILFindLastID(root),0,&IID_IShellFolder,(LPVOID \
*)&pSFRoot);
- if (SUCCEEDED(hr))
- {
- hr = IShellFolder_EnumObjects(
- pSFRoot,
- hwndParent,
- BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags),
- &pEnumIL);
- IShellFolder_Release(pSFRoot);
- }
- }
-
- if (SUCCEEDED(hr) && hwndTreeView)
+ if (hwndTreeView)
{
TreeView_DeleteAllItems(hwndTreeView);
TreeView_Expand(hwndTreeView,
- InsertTreeViewItem(lpsf, _ILIsPidlSimple(root) ? root : \
ILFindLastID(root), parentofroot, pEnumIL, TVI_ROOT), + \
insertroot_proc(hwndParent, hwndTreeView, lpbi), TVE_EXPAND);
}
-
- if (SUCCEEDED(hr))
- IShellFolder_Release(lpsf);
-
TRACE("done\n");
}
-static int GetIcon(LPITEMIDLIST lpi, UINT uFlags)
-{
- SHFILEINFOW sfi;
- SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW), uFlags);
- return sfi.iIcon;
-}
-
-static void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTVITEMW lpTV_ITEM)
-{
- LPITEMIDLIST pidlDesktop = NULL;
-
- TRACE("%p %p\n",lpifq, lpTV_ITEM);
-
- 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);
-
- if (pidlDesktop)
- ILFree(pidlDesktop);
-
- return;
-}
-
-typedef struct tagID
-{
- LPSHELLFOLDER lpsfParent;
- LPITEMIDLIST lpi;
- LPITEMIDLIST lpifq;
- IEnumIDList* pEnumIL;
-} TV_ITEMDATA, *LPTV_ITEMDATA;
-
-static BOOL GetName(LPSHELLFOLDER lpsf, LPCITEMIDLIST lpi, DWORD dwFlags, LPWSTR \
lpFriendlyName)
-{
- BOOL bSuccess=TRUE;
- STRRET str;
-
- TRACE("%p %p %lx %p\n", lpsf, lpi, dwFlags, lpFriendlyName);
- if (SUCCEEDED(IShellFolder_GetDisplayNameOf(lpsf, lpi, dwFlags, &str)))
- {
- if (FAILED(StrRetToStrNW(lpFriendlyName, MAX_PATH, &str, lpi)))
- {
- bSuccess = FALSE;
- }
- }
- else
- bSuccess = FALSE;
-
- TRACE("-- %s\n", debugstr_w(lpFriendlyName));
- return bSuccess;
-}
-
-static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl, \
LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent)
-{
- TVITEMW tvi;
- TVINSERTSTRUCTW tvins;
- WCHAR szBuff[MAX_PATH];
- LPTV_ITEMDATA lptvid=0;
-
- tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
-
- tvi.cChildren= pEnumIL ? 1 : 0;
- tvi.mask |= TVIF_CHILDREN;
-
- if (!(lptvid = (LPTV_ITEMDATA)SHAlloc(sizeof(TV_ITEMDATA))))
- return NULL;
-
- if (!GetName(lpsf, pidl, SHGDN_NORMAL, szBuff))
- return NULL;
-
- tvi.pszText = szBuff;
- tvi.cchTextMax = MAX_PATH;
- tvi.lParam = (LPARAM)lptvid;
-
- IShellFolder_AddRef(lpsf);
- lptvid->lpsfParent = lpsf;
- lptvid->lpi = ILClone(pidl);
- lptvid->lpifq = pidlParent ? ILCombine(pidlParent, pidl) : ILClone(pidl);
- lptvid->pEnumIL = pEnumIL;
- GetNormalAndSelectedIcons(lptvid->lpifq, &tvi);
-
- tvins.u.item = tvi;
- tvins.hInsertAfter = NULL;
- tvins.hParent = hParent;
-
- return (HTREEITEM)TreeView_InsertItemW(hwndTreeView, &tvins);
-}
-
-static void FillTreeView(IShellFolder * lpsf, LPITEMIDLIST pidl, HTREEITEM hParent, \
IEnumIDList* lpe)
-{
- HTREEITEM hPrev = 0;
- LPITEMIDLIST pidlTemp = 0;
- ULONG ulFetched;
- HRESULT hr;
- HWND hwnd=GetParent(hwndTreeView);
-
- TRACE("%p %p %x\n",lpsf, pidl, (INT)hParent);
- SetCapture(GetParent(hwndTreeView));
- SetCursor(LoadCursorA(0, (LPSTR)IDC_WAIT));
-
- while (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched))
- {
- ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER;
- IEnumIDList* pEnumIL = NULL;
- IShellFolder* pSFChild = NULL;
- IShellFolder_GetAttributesOf(lpsf, 1, (LPCITEMIDLIST*)&pidlTemp, &ulAttrs);
- if (ulAttrs & SFGAO_FOLDER)
- {
- hr = IShellFolder_BindToObject(lpsf,pidlTemp,NULL,&IID_IShellFolder,(LPVOID*)&pSFChild);
- if (SUCCEEDED(hr))
- {
- hr = IShellFolder_EnumObjects(pSFChild, hwnd, \
BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags), &pEnumIL);
- if (SUCCEEDED(hr))
- {
- if ((IEnumIDList_Skip(pEnumIL, 1) != S_OK) || \
FAILED(IEnumIDList_Reset(pEnumIL)))
- {
- IEnumIDList_Release(pEnumIL);
- pEnumIL = NULL;
- }
- }
- IShellFolder_Release(pSFChild);
- }
- }
-
- if (!(hPrev = InsertTreeViewItem(lpsf, pidlTemp, pidl, pEnumIL, hParent)))
- goto Done;
- SHFree(pidlTemp); /* Finally, free the pidl that the shell gave us... */
- pidlTemp=NULL;
- }
-
-Done:
- ReleaseCapture();
- SetCursor(LoadCursorW(0, (LPWSTR)IDC_ARROW));
-
- if (pidlTemp)
- SHFree(pidlTemp);
-}
-
-static inline BOOL PIDLIsType(LPCITEMIDLIST pidl, PIDLTYPE type)
-{
- LPPIDLDATA data = _ILGetDataPointer(pidl);
- if (!data)
- return FALSE;
- return (data->type == type);
-}
-
-static void BrsFolder_CheckValidSelection(HWND hWndTree, LPTV_ITEMDATA lptvid)
-{
- LPCITEMIDLIST pidl = lptvid->lpi;
- BOOL bEnabled = TRUE;
- DWORD dwAttributes;
- if ((lpBrowseInfo->ulFlags & BIF_BROWSEFORCOMPUTER) &&
- !PIDLIsType(pidl, PT_COMP))
- bEnabled = FALSE;
- if (lpBrowseInfo->ulFlags & BIF_RETURNFSANCESTORS)
- {
- dwAttributes = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM;
- if (FAILED(IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1, \
(LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes)) ||
- !dwAttributes)
- bEnabled = FALSE;
- }
- if (lpBrowseInfo->ulFlags & BIF_RETURNONLYFSDIRS)
- {
- dwAttributes = SFGAO_FOLDER | SFGAO_FILESYSTEM;
- if (FAILED(IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1, \
(LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes)) ||
- (dwAttributes != (SFGAO_FOLDER | SFGAO_FILESYSTEM)))
- bEnabled = FALSE;
- }
- SendMessageW(hWndTree, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
-}
-
static LRESULT MsgNotify(HWND hWnd, UINT CtlID, LPNMHDR lpnmh)
{
NMTREEVIEWW *pnmtv = (NMTREEVIEWW *)lpnmh;
- LPTV_ITEMDATA lptvid; /* Long pointer to TreeView item data */
- IShellFolder * lpsf2=0;
-
TRACE("%p %x %p msg=%x\n", hWnd, CtlID, lpnmh, pnmtv->hdr.code);
@@ -310,14 +92,13 @@
case TVN_DELETEITEMA:
case TVN_DELETEITEMW:
TRACE("TVN_DELETEITEMA/W\n");
- lptvid=(LPTV_ITEMDATA)pnmtv->itemOld.lParam;
- IShellFolder_Release(lptvid->lpsfParent);
- if (lptvid->pEnumIL)
- IEnumIDList_Release(lptvid->pEnumIL);
- SHFree(lptvid->lpi);
- SHFree(lptvid->lpifq);
- SHFree(lptvid);
- break;
+ if (browseMode == WINDOWS) {
+ OnDeleteItem_Windows(pnmtv);
+ }
+ else {
+ OnDeleteItem_UNIX(pnmtv);
+ }
+ break;
case TVN_ITEMEXPANDINGA:
case TVN_ITEMEXPANDINGW:
@@ -325,21 +106,25 @@
TRACE("TVN_ITEMEXPANDINGA/W\n");
if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
break;
-
- lptvid=(LPTV_ITEMDATA)pnmtv->itemNew.lParam;
- if (SUCCEEDED(IShellFolder_BindToObject(lptvid->lpsfParent, \
lptvid->lpi,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
- { FillTreeView( lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, \
lptvid->pEnumIL);
- }
+ if (browseMode == WINDOWS) {
+ OnItemExpanding_Windows(hwndTreeView, lpBrowseInfo, pnmtv);
+ } else {
+ OnItemExpanding_UNIX(hwndTreeView, lpBrowseInfo, pnmtv);
+ }
TreeView_SortChildren(hwndTreeView, pnmtv->itemNew.hItem, FALSE);
}
break;
case TVN_SELCHANGEDA:
case TVN_SELCHANGEDW:
- 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);
+ if (browseMode == WINDOWS) {
+ LPITEMIDLIST pidlRet = OnSelChanged_Windows(hWnd, lpBrowseInfo, \
pnmtv); + if (lpBrowseInfo->lpfn)
+ (lpBrowseInfo->lpfn)(hWnd, BFFM_SELCHANGED, (LPARAM)pidlRet, \
lpBrowseInfo->lParam); +
+ } else {
+ OnSelChanged_UNIX(hWnd, lpBrowseInfo, pnmtv);
+ /*TODO: Call lpBrowseInfo->lpfn?? What to use for a pidl?*/
+ }
break;
default:
@@ -355,55 +140,21 @@
return 0;
}
-
/*************************************************************************
- * BrsFolderDlgProc32 (not an exported API function)
+ * DefBrsDlgProc
+ * Dialog procedure for both the browse for folder and browse for UNIX
+ * directory dialog. General cases get forwarded to this procedure.
*/
-static INT_PTR CALLBACK BrsFolderDlgProc(HWND hWnd, UINT msg, WPARAM wParam,
+INT_PTR DefBrsDlgProc(HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam )
{
- TRACE("hwnd=%p msg=%04x 0x%08x 0x%08lx\n", hWnd, msg, wParam, lParam );
-
switch(msg)
- { case WM_INITDIALOG:
- pidlRet = NULL;
- lpBrowseInfo = (LPBROWSEINFOW) lParam;
- if (lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS)
- FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS);
- if (lpBrowseInfo->lpszTitle) {
- SetWindowTextW(GetDlgItem(hWnd, IDD_TITLE), lpBrowseInfo->lpszTitle);
- } else {
- ShowWindow(GetDlgItem(hWnd, IDD_TITLE), SW_HIDE);
- }
- if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT))
- ShowWindow(GetDlgItem(hWnd, IDD_STATUS), SW_HIDE);
-
- InitializeTreeView(hWnd, lpBrowseInfo->pidlRoot);
-
- if (lpBrowseInfo->lpfn)
- (lpBrowseInfo->lpfn)(hWnd, BFFM_INITIALIZED, 0, lpBrowseInfo->lParam);
-
- return TRUE;
-
- case WM_NOTIFY:
+ {
+ case WM_NOTIFY:
MsgNotify( hWnd, (UINT)wParam, (LPNMHDR)lParam);
break;
-
- case WM_COMMAND:
- switch (wParam)
- { case IDOK:
- pdump ( pidlRet );
- if (lpBrowseInfo->pszDisplayName)
- SHGetPathFromIDListW(pidlRet, lpBrowseInfo->pszDisplayName);
- EndDialog(hWnd, (DWORD) ILClone(pidlRet));
- return TRUE;
-
- case IDCANCEL:
- EndDialog(hWnd, 0);
- return TRUE;
- }
- break;
- case BFFM_SETSTATUSTEXTA:
+
+ case BFFM_SETSTATUSTEXTA:
TRACE("Set status %s\n", debugstr_a((LPSTR)lParam));
SetWindowTextA(GetDlgItem(hWnd, IDD_STATUS), (LPSTR)lParam);
break;
@@ -439,26 +190,58 @@
break;
}
return FALSE;
-}
+}
+BOOL OnInitDialog(HWND hWnd, LPARAM lParam, INSERTROOT_PROC insertroot_proc)
+{
+ lpBrowseInfo = (LPBROWSEINFOW) lParam;
+ if (lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS)
+ FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags & \
~SUPPORTEDFLAGS); + if (lpBrowseInfo->lpszTitle) {
+ SetWindowTextW(GetDlgItem(hWnd, IDD_TITLE), lpBrowseInfo->lpszTitle);
+ } else {
+ ShowWindow(GetDlgItem(hWnd, IDD_TITLE), SW_HIDE);
+ }
+ if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT))
+ ShowWindow(GetDlgItem(hWnd, IDD_STATUS), SW_HIDE);
+
+ InitializeTreeView(hWnd, lpBrowseInfo, insertroot_proc);
+
+ if (lpBrowseInfo->lpfn)
+ (lpBrowseInfo->lpfn)(hWnd, BFFM_INITIALIZED, 0, lpBrowseInfo->lParam);
+ return TRUE;
+}
+
static const WCHAR swBrowseTempName[] = \
{'S','H','B','R','S','F','O','R','F','O','L','D','E','R','_','M','S','G','B','O','X',0};
-/*************************************************************************
- * SHBrowseForFolderA [SHELL32.@]
- * SHBrowseForFolder [SHELL32.@]
+/*
+ * This function is both used for Windows browsing and UNIX browsing
*/
-LPITEMIDLIST WINAPI SHBrowseForFolderA (LPBROWSEINFOA lpbi)
+static INT_PTR BrowseW (LPBROWSEINFOW lpbi, DLGPROC dlgproc, enum browsemode \
aBrowseMode) +{
+ INT_PTR ret;
+
+ browseMode = aBrowseMode;
+
+ ret = DialogBoxParamW(shell32_hInstance,
+ swBrowseTempName, lpbi->hwndOwner,
+ dlgproc, (INT)lpbi);
+ return ret;
+}
+
+/*
+ * This function is both used for Windows browsing and UNIX browsing
+ */
+static INT_PTR BrowseA (LPBROWSEINFOA lpbi, DLGPROC dlgproc, enum browsemode \
aBrowseMode) {
BROWSEINFOW bi;
- LPITEMIDLIST lpid;
+ INT_PTR ret;
INT len;
-
+
+ browseMode = aBrowseMode;
+
TRACE("(%p{lpszTitle=%s,owner=%p})\n", lpbi,
lpbi ? debugstr_a(lpbi->lpszTitle) : NULL, lpbi ? lpbi->hwndOwner : NULL);
-
- if (!lpbi)
- return NULL;
-
bi.hwndOwner = lpbi->hwndOwner;
bi.pidlRoot = lpbi->pidlRoot;
if (lpbi->pszDisplayName)
@@ -483,9 +266,9 @@
bi.lpfn = lpbi->lpfn;
bi.lParam = lpbi->lParam;
bi.iImage = lpbi->iImage;
- lpid = (LPITEMIDLIST) DialogBoxParamW(shell32_hInstance,
- swBrowseTempName, lpbi->hwndOwner,
- BrsFolderDlgProc, (INT)&bi);
+ ret = DialogBoxParamW(shell32_hInstance,
+ swBrowseTempName, lpbi->hwndOwner,
+ dlgproc, (INT)&bi);
if (bi.pszDisplayName)
{
WideCharToMultiByte(CP_ACP, 0, bi.pszDisplayName, -1, lpbi->pszDisplayName, \
MAX_PATH, 0, NULL); @@ -496,7 +279,19 @@
HeapFree(GetProcessHeap(), 0, (LPVOID)bi.lpszTitle);
}
lpbi->iImage = bi.iImage;
- return lpid;
+ return ret;
+}
+
+/*************************************************************************
+ * SHBrowseForFolderA [SHELL32.@]
+ * SHBrowseForFolder [SHELL32.@]
+ */
+LPITEMIDLIST WINAPI SHBrowseForFolderA (LPBROWSEINFOA lpbi)
+{
+ if (!lpbi)
+ return NULL;
+
+ return (LPITEMIDLIST) BrowseA (lpbi, BrsFolderDlgProc_Windows, WINDOWS);
}
@@ -508,10 +303,64 @@
TRACE("((%p->{lpszTitle=%s,owner=%p})\n", lpbi,
lpbi ? debugstr_w(lpbi->lpszTitle) : NULL, lpbi ? lpbi->hwndOwner : 0);
- if (!lpbi)
+ if (!lpbi)
return NULL;
+
+ return (LPITEMIDLIST) BrowseW (lpbi, BrsFolderDlgProc_Windows, WINDOWS);
+}
+
+/*************************************************************************
+ * wine_shell_browse_for_UNIX_directory [SHELL32.@]
+ */
+BOOL WINAPI wine_shell_browse_for_UNIX_directoryA (LPBROWSEINFOA lpbi)
+{
+ if (!lpbi)
+ return FALSE;
+
+ /*For UNIX browsing, pidls are not used. Hence, if the
+ user passes a pidl that should be root for this browse
+ anyway, we refuse to show the dialog:*/
+ if (lpbi->pidlRoot)
+ {
+ ERR("pildRoot must be set to NULL for UNIX browsing.\n");
+ return FALSE;
+ }
+
+ /*For UNIX browsing, we always use the pszDiplayName to RETURN
+ the chosen path in, thus:*/
+ if (!lpbi->pszDisplayName)
+ {
+ ERR("pszDisplayName must be set for UNIX browsing.\n");
+ return FALSE;
+ }
+
+ return (BOOL) BrowseA (lpbi, BrsDirectoryDlgProc_UNIX, UNIX);
+}
+
+/*************************************************************************
+ * wine_shell_browse_for_UNIX_directoryW [SHELL32.@]
+ */
+BOOL WINAPI wine_shell_browse_for_UNIX_directoryW (LPBROWSEINFOW lpbi)
+{
+ if (!lpbi)
+ return FALSE;
+
+ /*For UNIX browsing, pidls are not used. Hence, if the
+ user passes a pidl that should be root for this browse
+ anyway, we refuse to show the dialog:*/
+ if (lpbi->pidlRoot)
+ {
+ ERR("pildRoot must be set to NULL for UNIX browsing.\n");
+ return FALSE;
+ }
+
+ /*For UNIX browsing, we always use the pszDiplayName to RETURN
+ the chosen path in, thus:*/
+ if (!lpbi->pszDisplayName)
+ {
+ ERR("pszDisplayName must be set for UNIX browsing.\n");
+ return FALSE;
+ }
- return (LPITEMIDLIST) DialogBoxParamW(shell32_hInstance,
- swBrowseTempName, lpbi->hwndOwner,
- BrsFolderDlgProc, (INT)lpbi);
+ return (BOOL) BrowseW (lpbi, BrsDirectoryDlgProc_UNIX, UNIX);
}
Index: dlls/shell32/shell32.spec
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shell32.spec,v
retrieving revision 1.89
diff -u -r1.89 shell32.spec
--- dlls/shell32/shell32.spec 4 Nov 2004 04:54:08 -0000 1.89
+++ dlls/shell32/shell32.spec 30 Nov 2004 14:57:03 -0000
@@ -405,6 +405,13 @@
@ stub WOWShellExecute
#
+# Some Wine specific functions
+#
+@ stdcall wine_shell_browse_for_UNIX_directory(ptr) \
wine_shell_browse_for_UNIX_directoryA +@ stdcall \
wine_shell_browse_for_UNIX_directoryA(ptr) +@ stdcall \
wine_shell_browse_for_UNIX_directoryW(ptr) +
+#
# version 4.70 (IE3.0)
# _WIN32_IE >= 0x0300
#
Index: include/shlobj.h
===================================================================
RCS file: /home/wine/wine/include/shlobj.h,v
retrieving revision 1.96
diff -u -r1.96 shlobj.h
--- include/shlobj.h 4 Nov 2004 04:54:08 -0000 1.96
+++ include/shlobj.h 30 Nov 2004 14:57:05 -0000
@@ -294,6 +294,13 @@
#define BFFM_VALIDATEFAILED WINELIB_NAME_AW(BFFM_VALIDATEFAILED)
/**********************************************************************
+ * wine_shell_browse_for_UNIX_directory API
+ */
+BOOL WINAPI wine_shell_browse_for_UNIX_directoryA(LPBROWSEINFOA lpbi);
+BOOL WINAPI wine_shell_browse_for_UNIX_directoryW(LPBROWSEINFOW lpbi);
+#define wine_shell_browse_for_UNIX_directory \
WINELIB_NAME_AW(wine_shell_browse_for_UNIX_directory) +
+/**********************************************************************
* SHCreateShellFolderViewEx API
*/
Index: programs/winecfg/Makefile.in
===================================================================
RCS file: /home/wine/wine/programs/winecfg/Makefile.in,v
retrieving revision 1.12
diff -u -r1.12 Makefile.in
--- programs/winecfg/Makefile.in 23 Nov 2004 13:50:23 -0000 1.12
+++ programs/winecfg/Makefile.in 30 Nov 2004 14:57:06 -0000
@@ -4,7 +4,7 @@
VPATH = @srcdir@
MODULE = winecfg.exe
APPMODE = -mwindows
-IMPORTS = comdlg32 comctl32 user32 advapi32 kernel32
+IMPORTS = comdlg32 comctl32 user32 advapi32 kernel32 shell32
C_SRCS = \
appdefaults.c \
@@ -16,7 +16,7 @@
main.c \
properties.c \
winecfg.c \
- x11drvdlg.c
+ x11drvdlg.c \
RC_SRCS = winecfg.rc
RC_BINSRC = winecfg.rc
Index: programs/winecfg/driveui.c
===================================================================
RCS file: /home/wine/wine/programs/winecfg/driveui.c,v
retrieving revision 1.1
diff -u -r1.1 driveui.c
--- programs/winecfg/driveui.c 23 Nov 2004 13:50:23 -0000 1.1
+++ programs/winecfg/driveui.c 30 Nov 2004 14:57:07 -0000
@@ -34,6 +34,8 @@
#include <shlobj.h>
#include <winuser.h>
+#include <dlgs.h>
+
#include <wine/debug.h>
#include "winecfg.h"
@@ -580,9 +582,20 @@
break;
case IDC_BUTTON_BROWSE_PATH:
- MessageBox(dialog, "", "Write me!", MB_OK);
- break;
+ {
+ LPBROWSEINFO bi;
+ bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, \
sizeof(BROWSEINFO)); + bi->hwndOwner = dialog;
+ bi->pszDisplayName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
+ bi->lpszTitle = "Please choose a directory"; /*FIXME: Get this \
multilingual*/ + if (wine_shell_browse_for_UNIX_directory(bi))
+ set_text(dialog, IDC_EDIT_PATH, bi->pszDisplayName);
+
+ HeapFree(GetProcessHeap(), 0, bi->pszDisplayName);
+ HeapFree(GetProcessHeap(), 0, bi);
+ break;
+ }
case IDC_RADIO_ASSIGN:
{
char *str;
--- /dev/null 2004-04-06 15:27:52.000000000 +0200
+++ dlls/shell32/brsfolder_unix.h 2004-11-30 00:27:23.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2004 Robert van Herk
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __BRSFOLDER_UNIX_H__
+#define __BRSFOLDER_UNIX_H__
+
+#include "shlobj.h"
+
+inline HTREEITEM InsertRootItem_UNIX(HWND hwndParent, HWND hwndTreeView, \
LPBROWSEINFOW lpbi); +inline void OnDeleteItem_UNIX (NMTREEVIEWW *pnmtv);
+inline void OnItemExpanding_UNIX (HWND hwndTreeView, LPBROWSEINFOW lpBrowseInfo, \
NMTREEVIEWW *pnmtv); +inline void OnSelChanged_UNIX (HWND hwndTreeView, LPBROWSEINFOW \
lpBrowseInfo, NMTREEVIEWW *pnmtv); +
+INT_PTR CALLBACK BrsDirectoryDlgProc_UNIX(HWND hWnd, UINT msg, WPARAM wParam,
+ LPARAM lParam );
+
+
+#endif
--- /dev/null 2004-04-06 15:27:52.000000000 +0200
+++ dlls/shell32/brsfolder_unix.c 2004-11-30 15:57:18.000000000 +0100
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2004 Robert van Herk
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#define COBJMACROS
+
+#include "wine/debug.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "undocshell.h"
+#include "winnls.h"
+
+#include "brsfolder.h"
+#include "unixTools.h"
+
+/* Some UNIX includes*/
+#include <sys/stat.h> /*For IF_DIR*/
+#include <sys/param.h> /*For MAXPATHLEN*/
+
+#include "brsfolder_windows.h"
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
+#define MAXPATHLEN_UNIX MAXPATHLEN
+typedef struct tagID_UNIX
+{
+ char* path;
+} TV_ITEMDATA_UNIX, *LPTV_ITEMDATA_UNIX;
+
+static LPTV_ITEMDATA_UNIX currLPID = 0;
+
+static HTREEITEM InsertTreeViewItem(HWND hwndTreeView, char* path, HTREEITEM \
hParent) +{
+ TRACE("Path: %s\n", path);
+ TVITEMW tvi;
+ TVINSERTSTRUCTW tvins;
+ WCHAR szBuff[MAXPATHLEN_UNIX];
+ LPTV_ITEMDATA_UNIX lptvid = 0;
+
+ TVITEMEXW tviParent;
+ tviParent.hItem = hParent;
+ LPTV_ITEMDATA_UNIX lptvidParent = 0;
+ if (hParent != TVI_ROOT) {
+ if (TreeView_GetItemW(hwndTreeView, &tviParent)) {
+ lptvidParent = (LPTV_ITEMDATA_UNIX) (tviParent.lParam);
+ } else
+ ERR("hParent passed, but was not found as an item in hwndTreeView\n");
+ }
+
+ MultiByteToWideChar(CP_ACP, 0, path, MAXPATHLEN_UNIX, szBuff, \
MAXPATHLEN_UNIX); +
+ tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
+
+ tvi.cChildren= 1;
+ tvi.mask |= TVIF_CHILDREN;
+
+ if (!(lptvid = (LPTV_ITEMDATA_UNIX)SHAlloc(sizeof(TV_ITEMDATA_UNIX))))
+ return NULL;
+
+ tvi.pszText = szBuff;
+ tvi.cchTextMax = MAX_PATH;
+ tvi.lParam = (LPARAM)lptvid;
+
+ lptvid->path = SHAlloc(MAXPATHLEN_UNIX);
+ if (lptvidParent) {
+ /*Concatenate path of parent to path of inserted node*/
+ strncpy(lptvid->path, lptvidParent->path, MAXPATHLEN_UNIX);
+ strncpy(lptvid->path + strlen(lptvidParent->path), path, MAXPATHLEN_UNIX - \
strlen(lptvidParent->path)); + }
+ else
+ strncpy(lptvid->path, path, MAXPATHLEN_UNIX);
+
+ /*Include trailing slash:*/
+ if ((strncmp(lptvid->path + (strlen(lptvid->path) - 1), "/", 1)) != 0)
+ strncpy(lptvid->path + strlen(lptvid->path), "/", MAXPATHLEN_UNIX - \
strlen(lptvid->path)); +
+ /*GetNormalAndSelectedIcons(lptvid->lpifq, &tvi); TODO: fetch icons*/
+
+ tvins.item = tvi;
+ tvins.hInsertAfter = NULL;
+ tvins.hParent = hParent;
+
+ return (HTREEITEM)TreeView_InsertItemW(hwndTreeView, &tvins);
+}
+
+inline HTREEITEM InsertRootItem_UNIX(HWND hwndParent, HWND hwndTreeView, \
LPBROWSEINFOW lpbi) +{
+ return InsertTreeViewItem(hwndTreeView, "/", TVI_ROOT);
+}
+
+inline void OnItemExpanding_UNIX (HWND hwndTreeView, LPBROWSEINFOW lpBrowseInfo, \
NMTREEVIEWW *pnmtv) { + LPTV_ITEMDATA_UNIX lptvid = \
(LPTV_ITEMDATA_UNIX)pnmtv->itemNew.lParam; + UNIXTOOLS_DIRDATA dirdata;
+ char filename [MAXPATHLEN_UNIX];
+ openDirectory(lptvid->path, S_IFDIR, &dirdata);
+ TRACE ("Directory is: \"%s\"\n", lptvid->path);
+ while (hasNextFile(&dirdata)) {
+ getNextFile(&dirdata, filename, MAXPATHLEN_UNIX);
+ TRACE ("alive %s\n", filename);
+ InsertTreeViewItem (hwndTreeView, filename, pnmtv->itemNew.hItem);
+ TRACE ("File read: %s\n", filename);
+ }
+ closeDirectory(&dirdata);
+}
+
+inline void OnDeleteItem_UNIX (NMTREEVIEWW *pnmtv) {
+ LPTV_ITEMDATA_UNIX lptvid = (LPTV_ITEMDATA_UNIX)pnmtv->itemOld.lParam;
+ SHFree(lptvid->path);
+ SHFree(lptvid);
+}
+
+inline void OnSelChanged_UNIX (HWND hwndTreeView, LPBROWSEINFOW lpBrowseInfo, \
NMTREEVIEWW *pnmtv) { + LPTV_ITEMDATA_UNIX \
lptvid=(LPTV_ITEMDATA_UNIX)pnmtv->itemNew.lParam; + \
/*BrsFolder_CheckValidSelection(hwndTreeView, lpBrowseInfo, lptvid); TODO: check for \
valid selection*/ + currLPID = lptvid;
+}
+
+
+INT_PTR CALLBACK BrsDirectoryDlgProc_UNIX(HWND hWnd, UINT msg, WPARAM wParam,
+ LPARAM lParam )
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ currLPID = NULL;
+ return OnInitDialog(hWnd, lParam, InsertRootItem_UNIX);
+ case WM_COMMAND:
+ switch (wParam)
+ { case IDOK:
+ if (lpBrowseInfo->pszDisplayName)
+ if (currLPID) {
+ TRACE("Selected UNIX dir: %s\n", currLPID->path);
+ MultiByteToWideChar(CP_ACP, 0, currLPID->path, MAXPATHLEN_UNIX, \
lpBrowseInfo->pszDisplayName, MAX_PATH); + }
+ EndDialog(hWnd, (DWORD) TRUE);
+ return TRUE;
+ case IDCANCEL:
+ EndDialog(hWnd, (DWORD) FALSE);
+ return TRUE;
+ }
+ break;
+ default:
+ return DefBrsDlgProc(hWnd, msg, wParam, lParam);
+ }
+ return FALSE;
+}
--- /dev/null 2004-04-06 15:27:52.000000000 +0200
+++ dlls/shell32/brsfolder.h 2004-11-30 15:56:40.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2004 Robert van Herk
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __BRSFOLDER_H__
+#define __BRSFOLDER_H__
+
+#include "shlobj.h"
+
+LPBROWSEINFOW lpBrowseInfo;
+HWND hwndTreeView;
+
+typedef HTREEITEM (*INSERTROOT_PROC)(HWND hwndParent, HWND hwndTreeView, \
LPBROWSEINFOW lpbi); +
+INT_PTR DefBrsDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
+BOOL OnInitDialog(HWND hWnd, LPARAM lParam, INSERTROOT_PROC insertroot_proc);
+#endif
--- /dev/null 2004-04-06 15:27:52.000000000 +0200
+++ dlls/shell32/brsfolder_windows.h 2004-11-30 15:57:28.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2004 Robert van Herk
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __BRSFOLDER_WINDOWS_H__
+#define __BRSFOLDER_WINDOWS_H__
+
+#include "shlobj.h"
+
+HTREEITEM InsertRootItem_Windows(HWND hwndParent, HWND hwndTreeView, LPBROWSEINFOW \
lpbi); +inline void OnDeleteItem_Windows (NMTREEVIEWW *pnmtv);
+inline void OnItemExpanding_Windows (HWND hwndTreeView, LPBROWSEINFOW lpBrowseInfo, \
NMTREEVIEWW *pnmtv); +inline LPITEMIDLIST OnSelChanged_Windows (HWND hwndTreeView, \
LPBROWSEINFOW lpBrowseInfo, NMTREEVIEWW *pnmtv); +INT_PTR CALLBACK \
BrsFolderDlgProc_Windows(HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam \
); +
+typedef struct tagID_Windows
+{
+ LPSHELLFOLDER lpsfParent;
+ LPITEMIDLIST lpi;
+ LPITEMIDLIST lpifq;
+ IEnumIDList* pEnumIL;
+} TV_ITEMDATA_WINDOWS, *LPTV_ITEMDATA_WINDOWS;
+
+
+#endif
--- /dev/null 2004-04-06 15:27:52.000000000 +0200
+++ dlls/shell32/brsfolder_windows.c 2004-11-30 15:56:25.000000000 +0100
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2004 Robert van Herk
+ * Copyright 1999 Juergen Schmied
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * FIXME:
+ * - many memory leaks
+ */
+
+#define COBJMACROS
+
+#include "wine/debug.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "undocshell.h"
+
+#include "shlguid.h"
+#include "pidl.h"
+#include "shell32_main.h"
+#include "shellapi.h"
+#include "shresdef.h"
+
+#include "brsfolder.h"
+
+#include "brsfolder_windows.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
+LPITEMIDLIST pidlRet;
+
+static inline DWORD BrowseFlagsToSHCONTF(UINT ulFlags)
+{
+ return SHCONTF_FOLDERS | (ulFlags & BIF_BROWSEINCLUDEFILES ? SHCONTF_NONFOLDERS \
: 0); +}
+
+static BOOL GetName(LPSHELLFOLDER lpsf, LPCITEMIDLIST lpi, DWORD dwFlags, LPWSTR \
lpFriendlyName) +{
+ BOOL bSuccess=TRUE;
+ STRRET str;
+
+ TRACE("%p %p %lx %p\n", lpsf, lpi, dwFlags, lpFriendlyName);
+ if (SUCCEEDED(IShellFolder_GetDisplayNameOf(lpsf, lpi, dwFlags, &str)))
+ {
+ if (FAILED(StrRetToStrNW(lpFriendlyName, MAX_PATH, &str, lpi)))
+ {
+ bSuccess = FALSE;
+ }
+ }
+ else
+ bSuccess = FALSE;
+
+ TRACE("-- %s\n", debugstr_w(lpFriendlyName));
+ return bSuccess;
+}
+
+static int GetIcon(LPITEMIDLIST lpi, UINT uFlags)
+{
+ SHFILEINFOW sfi;
+ SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW), uFlags);
+ return sfi.iIcon;
+}
+
+static void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTVITEMW lpTV_ITEM)
+{
+ LPITEMIDLIST pidlDesktop = NULL;
+
+ TRACE("%p %p\n",lpifq, lpTV_ITEM);
+
+ 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); +
+ if (pidlDesktop)
+ ILFree(pidlDesktop);
+
+ return;
+}
+
+static HTREEITEM InsertTreeViewItem(HWND hwndTreeView, IShellFolder * lpsf, \
LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM \
hParent) +{
+ TVITEMW tvi;
+ TVINSERTSTRUCTW tvins;
+ WCHAR szBuff[MAX_PATH];
+ LPTV_ITEMDATA_WINDOWS lptvid=0;
+
+ tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
+
+ tvi.cChildren= pEnumIL ? 1 : 0;
+ tvi.mask |= TVIF_CHILDREN;
+
+ if (!(lptvid = (LPTV_ITEMDATA_WINDOWS)SHAlloc(sizeof(TV_ITEMDATA_WINDOWS))))
+ return NULL;
+
+ if (!GetName(lpsf, pidl, SHGDN_NORMAL, szBuff))
+ return NULL;
+
+ tvi.pszText = szBuff;
+ tvi.cchTextMax = MAX_PATH;
+ tvi.lParam = (LPARAM)lptvid;
+
+ IShellFolder_AddRef(lpsf);
+ lptvid->lpsfParent = lpsf;
+ lptvid->lpi = ILClone(pidl);
+ lptvid->lpifq = pidlParent ? ILCombine(pidlParent, pidl) : ILClone(pidl);
+ lptvid->pEnumIL = pEnumIL;
+ GetNormalAndSelectedIcons(lptvid->lpifq, &tvi);
+
+ tvins.item = tvi;
+ tvins.hInsertAfter = NULL;
+ tvins.hParent = hParent;
+
+ return (HTREEITEM)TreeView_InsertItemW(hwndTreeView, &tvins);
+}
+
+static inline BOOL PIDLIsType(LPCITEMIDLIST pidl, PIDLTYPE type)
+{
+ LPPIDLDATA data = _ILGetDataPointer(pidl);
+ if (!data)
+ return FALSE;
+ return (data->type == type);
+}
+
+static void BrsFolder_CheckValidSelection(HWND hWndTree, LPBROWSEINFOW lpBrowseInfo, \
LPTV_ITEMDATA_WINDOWS lptvid) +{
+ LPCITEMIDLIST pidl = lptvid->lpi;
+ BOOL bEnabled = TRUE;
+ DWORD dwAttributes;
+ if ((lpBrowseInfo->ulFlags & BIF_BROWSEFORCOMPUTER) &&
+ !PIDLIsType(pidl, PT_COMP))
+ bEnabled = FALSE;
+ if (lpBrowseInfo->ulFlags & BIF_RETURNFSANCESTORS)
+ {
+ dwAttributes = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM;
+ if (FAILED(IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1, \
(LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes)) || + !dwAttributes)
+ bEnabled = FALSE;
+ }
+ if (lpBrowseInfo->ulFlags & BIF_RETURNONLYFSDIRS)
+ {
+ dwAttributes = SFGAO_FOLDER | SFGAO_FILESYSTEM;
+ if (FAILED(IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1, \
(LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes)) || + (dwAttributes != \
(SFGAO_FOLDER | SFGAO_FILESYSTEM))) + bEnabled = FALSE;
+ }
+ SendMessageW(hWndTree, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
+}
+
+HTREEITEM InsertRootItem_Windows(HWND hwndParent, HWND hwndTreeView, LPBROWSEINFOW \
lpbi) +{
+ HTREEITEM out = 0;
+ IShellFolder * lpsf;
+ HRESULT hr;
+ IEnumIDList * pEnumIL = NULL;
+ LPCITEMIDLIST root = lpbi->pidlRoot;
+ LPITEMIDLIST parentofroot;
+
+ TRACE("dlg=%p tree=%p lpbi=%p\n", hwndParent, hwndTreeView, lpbi);
+
+ parentofroot = ILClone(root);
+ ILRemoveLastID(parentofroot);
+
+ if (_ILIsDesktop (root)) {
+ hr = SHGetDesktopFolder(&lpsf);
+ } else {
+ IShellFolder * lpsfdesktop;
+
+ hr = SHGetDesktopFolder(&lpsfdesktop);
+ if (SUCCEEDED(hr)) {
+ hr = IShellFolder_BindToObject(lpsfdesktop, parentofroot, \
0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf); + \
IShellFolder_Release(lpsfdesktop); + }
+ }
+ if (SUCCEEDED(hr))
+ {
+ IShellFolder * pSFRoot;
+ if (_ILIsPidlSimple(root))
+ {
+ pSFRoot = lpsf;
+ IShellFolder_AddRef(pSFRoot);
+ }
+ else
+ hr = IShellFolder_BindToObject(lpsf,ILFindLastID(root),0,&IID_IShellFolder,(LPVOID \
*)&pSFRoot); + if (SUCCEEDED(hr))
+ {
+ hr = IShellFolder_EnumObjects(
+ pSFRoot,
+ hwndParent,
+ BrowseFlagsToSHCONTF(lpbi->ulFlags),
+ &pEnumIL);
+ IShellFolder_Release(pSFRoot);
+ }
+ }
+
+ if (SUCCEEDED(hr) && hwndTreeView)
+ {
+ out = InsertTreeViewItem(hwndTreeView, lpsf, _ILIsPidlSimple(root) ? root : \
ILFindLastID(root), parentofroot, pEnumIL, TVI_ROOT); + }
+
+ if (SUCCEEDED(hr))
+ IShellFolder_Release(lpsf);
+
+ TRACE("done\n");
+ return out;
+}
+
+static void FillTreeView(HWND hwndTreeView, LPBROWSEINFOW lpbi, IShellFolder * lpsf, \
LPITEMIDLIST pidl, HTREEITEM hParent, IEnumIDList* lpe) +{
+ HTREEITEM hPrev = 0;
+ LPITEMIDLIST pidlTemp = 0;
+ ULONG ulFetched;
+ HRESULT hr;
+ HWND hwnd=GetParent(hwndTreeView);
+
+ TRACE("%p %p %x\n",lpsf, pidl, (INT)hParent);
+ SetCapture(GetParent(hwndTreeView));
+ SetCursor(LoadCursorA(0, (LPSTR)IDC_WAIT));
+
+ while (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched))
+ {
+ ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER;
+ IEnumIDList* pEnumIL = NULL;
+ IShellFolder* pSFChild = NULL;
+ IShellFolder_GetAttributesOf(lpsf, 1, (LPCITEMIDLIST*)&pidlTemp, &ulAttrs);
+ if (ulAttrs & SFGAO_FOLDER)
+ {
+ hr = IShellFolder_BindToObject(lpsf,pidlTemp,NULL,&IID_IShellFolder,(LPVOID*)&pSFChild);
+ if (SUCCEEDED(hr))
+ {
+ hr = IShellFolder_EnumObjects(pSFChild, hwnd, \
BrowseFlagsToSHCONTF(lpbi->ulFlags), &pEnumIL); + if \
(SUCCEEDED(hr)) + {
+ if ((IEnumIDList_Skip(pEnumIL, 1) != S_OK) || \
FAILED(IEnumIDList_Reset(pEnumIL))) + {
+ IEnumIDList_Release(pEnumIL);
+ pEnumIL = NULL;
+ }
+ }
+ IShellFolder_Release(pSFChild);
+ }
+ }
+
+ if (!(hPrev = InsertTreeViewItem(hwndTreeView, lpsf, pidlTemp, pidl, pEnumIL, \
hParent))) + goto Done;
+ SHFree(pidlTemp); /* Finally, free the pidl that the shell gave us... */
+ pidlTemp=NULL;
+ }
+
+Done:
+ ReleaseCapture();
+ SetCursor(LoadCursorW(0, (LPWSTR)IDC_ARROW));
+
+ if (pidlTemp)
+ SHFree(pidlTemp);
+}
+
+inline void OnDeleteItem_Windows (NMTREEVIEWW *pnmtv) {
+ LPTV_ITEMDATA_WINDOWS lptvid = \
(LPTV_ITEMDATA_WINDOWS)pnmtv->itemOld.lParam; + \
IShellFolder_Release(lptvid->lpsfParent); + if (lptvid->pEnumIL)
+ IEnumIDList_Release(lptvid->pEnumIL);
+ SHFree(lptvid->lpi);
+ SHFree(lptvid->lpifq);
+ SHFree(lptvid);
+}
+
+inline void OnItemExpanding_Windows (HWND hwndTreeView, LPBROWSEINFOW lpBrowseInfo, \
NMTREEVIEWW *pnmtv) { + IShellFolder * lpsf2=0;
+ LPTV_ITEMDATA_WINDOWS lptvid=(LPTV_ITEMDATA_WINDOWS)pnmtv->itemNew.lParam;
+ if (SUCCEEDED(IShellFolder_BindToObject(lptvid->lpsfParent, \
lptvid->lpi,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2))) + { \
FillTreeView(hwndTreeView, lpBrowseInfo,lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, \
lptvid->pEnumIL); + }
+}
+
+inline LPITEMIDLIST OnSelChanged_Windows (HWND hwndTreeView, LPBROWSEINFOW \
lpBrowseInfo, NMTREEVIEWW *pnmtv) { + LPTV_ITEMDATA_WINDOWS \
lptvid=(LPTV_ITEMDATA_WINDOWS)pnmtv->itemNew.lParam; + LPITEMIDLIST out = \
lptvid->lpifq; + BrsFolder_CheckValidSelection(hwndTreeView, lpBrowseInfo, lptvid);
+ pidlRet = out;
+ return out;
+}
+
+INT_PTR CALLBACK BrsFolderDlgProc_Windows(HWND hWnd, UINT msg, WPARAM wParam,
+ LPARAM lParam )
+{
+ TRACE("hwnd=%p msg=%04x 0x%08x 0x%08lx\n", hWnd, msg, wParam, lParam );
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ pidlRet = NULL;
+ return OnInitDialog(hWnd, lParam, InsertRootItem_Windows);
+ case WM_COMMAND:
+ switch (wParam)
+ { case IDOK:
+ pdump ( pidlRet );
+ if (lpBrowseInfo->pszDisplayName)
+ SHGetPathFromIDListW(pidlRet, lpBrowseInfo->pszDisplayName);
+ EndDialog(hWnd, (DWORD) ILClone(pidlRet));
+ return TRUE;
+
+ case IDCANCEL:
+ EndDialog(hWnd, 0);
+ return TRUE;
+ }
+ break;
+ default:
+ return DefBrsDlgProc(hWnd, msg, wParam, lParam);
+ }
+ return FALSE;
+}
--- /dev/null 2004-04-06 15:27:52.000000000 +0200
+++ dlls/shell32/unixTools.h 2004-11-30 12:19:08.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2004 Robert van Herk
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __UNIXTOOLS_H__
+#define __UNIXTOOLS_H__
+
+#include <dirent.h>
+
+typedef struct tagDIR
+{
+ char* currentFile;
+ char* dirname;
+ DIR* dp;
+ int open;
+ int fileTypeMask;
+} UNIXTOOLS_DIRDATA, *LP_UNIXTOOLS_DIRDATA;
+
+void openDirectory(char* dirname, int fileTypeMask, LP_UNIXTOOLS_DIRDATA dirdata);
+void closeDirectory(LP_UNIXTOOLS_DIRDATA dirdata);
+inline int hasNextFile(LP_UNIXTOOLS_DIRDATA dirdata);
+inline void getNextFile(LP_UNIXTOOLS_DIRDATA dirdata, char* buff, int maxSize);
+
+#endif
--- /dev/null 2004-04-06 15:27:52.000000000 +0200
+++ dlls/shell32/unixTools.c 2004-11-30 15:55:34.000000000 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2004 Robert van Herk
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include "wine/debug.h"
+
+#include "unixTools.h"
+
+/*
+ * Helper functions to read out UNIX directory listings.
+ * Hence: no Win32 code here, except for some wine traces
+ */
+
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
+static void prepNextFile(LP_UNIXTOOLS_DIRDATA dirdata)
+{
+ TRACE("hallo\n");
+
+ struct dirent *dirp;
+ struct stat sbuf;
+ char fullName[MAXPATHLEN];
+ int len;
+ strncpy(fullName, dirdata->dirname, MAXPATHLEN); /*The part of the path from \
the root*/ + /*Include trailing slash:*/
+ if ((strncmp(fullName + (strlen(fullName) - 1), "/", 1)) != 0)
+ strncpy(fullName + strlen(fullName), "/", MAXPATHLEN - strlen(fullName));
+ len = strlen(fullName);
+
+ int done = 0;
+ while (!done) {
+ if ((dirp=readdir(dirdata->dp))!=NULL) {
+ /* We are done, if we found an entry of the correct type: */
+ if (strcmp(dirp->d_name, ".") == 0) continue; /*Ignore "." */
+ if (strcmp(dirp->d_name, "..") == 0) continue; /*Ignore ".." */
+ strncpy(fullName + len, dirp->d_name, MAXPATHLEN - len);
+ if (stat(fullName, &sbuf) != 0) continue; /*Couldn't get stats of \
the file.*/ + done = ((sbuf.st_mode & S_IFMT) & dirdata->fileTypeMask);
+ if (done) {
+ strncpy(dirdata->currentFile, dirp->d_name, MAXPATHLEN);
+ dirdata->open = 1;
+ }
+ } else {
+ dirdata->open = 0;
+ done = 1;
+ }
+ }
+}
+
+void openDirectory(char* dirname, int fileTypeMask, LP_UNIXTOOLS_DIRDATA dirdata)
+{
+ dirdata->currentFile = malloc(MAXPATHLEN);
+ dirdata->dirname = malloc(MAXPATHLEN);
+ if ((dirdata->dp = opendir(dirname)) != NULL)
+ {
+ dirdata->fileTypeMask = fileTypeMask;
+ strncpy(dirdata->dirname, dirname, MAXPATHLEN);
+ prepNextFile(dirdata);
+ } else
+ dirdata->open = 0;
+}
+
+void closeDirectory(LP_UNIXTOOLS_DIRDATA dirdata) {
+ closedir(dirdata->dp);
+ free(dirdata->currentFile);
+ free(dirdata->dirname);
+}
+
+inline int hasNextFile(LP_UNIXTOOLS_DIRDATA dirdata)
+{
+ return (dirdata->open == 1);
+}
+
+inline void getNextFile(LP_UNIXTOOLS_DIRDATA dirdata, char* buff, int maxSize) {
+ strncpy(buff, dirdata->currentFile, maxSize);
+ prepNextFile(dirdata);
+}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic