4 #include "debugtools.h"
5 #include "wine/undocshell.h"
8 #include "shell32_main.h"
12 DEFAULT_DEBUG_CHANNEL(shell
);
14 static HWND hwndTreeView
;
15 static LPBROWSEINFOA lpBrowseInfo
;
16 static LPITEMIDLIST pidlRet
;
18 static void FillTreeView(LPSHELLFOLDER lpsf
, LPITEMIDLIST lpifq
, HTREEITEM hParent
);
20 static void InitializeTreeView(HWND hwndParent
, LPCITEMIDLIST root
)
22 HIMAGELIST hImageList
;
26 hwndTreeView
= GetDlgItem (hwndParent
, IDD_TREEVIEW
);
27 Shell_GetImageList(NULL
, &hImageList
);
29 TRACE("dlg=%x tree=%x\n", hwndParent
, hwndTreeView
);
31 if (hImageList
&& hwndTreeView
)
32 { TreeView_SetImageList(hwndTreeView
, hImageList
, 0);
35 /* so far, this method doesn't work (still missing the upper level), keep the old way */
38 hr
= SHGetDesktopFolder(&lpsf
);
40 IShellFolder
* lpsfdesktop
;
42 hr
= SHGetDesktopFolder(&lpsfdesktop
);
44 hr
= IShellFolder_BindToObject(lpsfdesktop
, root
, 0,(REFIID
)&IID_IShellFolder
,(LPVOID
*)&lpsf
);
45 IShellFolder_Release(lpsfdesktop
);
49 hr
= SHGetDesktopFolder(&lpsf
);
52 if (SUCCEEDED(hr
) && hwndTreeView
)
53 { TreeView_DeleteAllItems(hwndTreeView
);
54 FillTreeView(lpsf
, NULL
, TVI_ROOT
);
58 { IShellFolder_Release(lpsf
);
63 static int GetIcon(LPITEMIDLIST lpi
, UINT uFlags
)
65 SHGetFileInfoA((LPCSTR
)lpi
,0,&sfi
, sizeof(SHFILEINFOA
), uFlags
);
69 static void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq
,LPTVITEMA lpTV_ITEM
)
70 { TRACE("%p %p\n",lpifq
, lpTV_ITEM
);
72 lpTV_ITEM
->iImage
= GetIcon(lpifq
, SHGFI_PIDL
| SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
);
73 lpTV_ITEM
->iSelectedImage
= GetIcon(lpifq
, SHGFI_PIDL
| SHGFI_SYSICONINDEX
| SHGFI_SMALLICON
| SHGFI_OPENICON
);
80 LPSHELLFOLDER lpsfParent
;
83 } TV_ITEMDATA
, *LPTV_ITEMDATA
;
85 static BOOL
GetName(LPSHELLFOLDER lpsf
, LPITEMIDLIST lpi
, DWORD dwFlags
, LPSTR lpFriendlyName
)
90 TRACE("%p %p %lx %p\n", lpsf
, lpi
, dwFlags
, lpFriendlyName
);
91 if (SUCCEEDED(IShellFolder_GetDisplayNameOf(lpsf
, lpi
, dwFlags
, &str
)))
93 if(FAILED(StrRetToStrNA (lpFriendlyName
, MAX_PATH
, &str
, lpi
)))
101 TRACE("-- %s\n",lpFriendlyName
);
105 static void FillTreeView(IShellFolder
* lpsf
, LPITEMIDLIST pidl
, HTREEITEM hParent
)
108 TVINSERTSTRUCTA tvins
;
111 LPITEMIDLIST pidlTemp
=0;
112 LPTV_ITEMDATA lptvid
=0;
116 HWND hwnd
=GetParent(hwndTreeView
);
118 TRACE("%p %p %x\n",lpsf
, pidl
, (INT
)hParent
);
119 SetCapture(GetParent(hwndTreeView
));
120 SetCursor(LoadCursorA(0, IDC_WAITA
));
122 hr
=IShellFolder_EnumObjects(lpsf
,hwnd
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,&lpe
);
125 { while (NOERROR
== IEnumIDList_Next(lpe
,1,&pidlTemp
,&ulFetched
))
126 { ULONG ulAttrs
= SFGAO_HASSUBFOLDER
| SFGAO_FOLDER
;
127 IShellFolder_GetAttributesOf(lpsf
, 1, &pidlTemp
, &ulAttrs
);
128 if (ulAttrs
& (SFGAO_HASSUBFOLDER
| SFGAO_FOLDER
))
129 { if (ulAttrs
& SFGAO_FOLDER
)
130 { tvi
.mask
= TVIF_TEXT
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
| TVIF_PARAM
;
132 if (ulAttrs
& SFGAO_HASSUBFOLDER
)
134 tvi
.mask
|= TVIF_CHILDREN
;
137 if (!( lptvid
= (LPTV_ITEMDATA
)SHAlloc(sizeof(TV_ITEMDATA
))))
140 if (!GetName(lpsf
, pidlTemp
, SHGDN_NORMAL
, szBuff
))
143 tvi
.pszText
= szBuff
;
144 tvi
.cchTextMax
= MAX_PATH
;
145 tvi
.lParam
= (LPARAM
)lptvid
;
147 IShellFolder_AddRef(lpsf
);
148 lptvid
->lpsfParent
= lpsf
;
149 lptvid
->lpi
= ILClone(pidlTemp
);
150 lptvid
->lpifq
= ILCombine(pidl
, pidlTemp
);
151 GetNormalAndSelectedIcons(lptvid
->lpifq
, &tvi
);
153 tvins
.DUMMYUNIONNAME
.item
= tvi
;
154 tvins
.hInsertAfter
= hPrev
;
155 tvins
.hParent
= hParent
;
157 hPrev
= (HTREEITEM
)TreeView_InsertItemA (hwndTreeView
, &tvins
);
161 SHFree(pidlTemp
); /* Finally, free the pidl that the shell gave us... */
168 SetCursor(LoadCursorA(0, IDC_ARROWA
));
171 IEnumIDList_Release(lpe
);
176 static LRESULT
MsgNotify(HWND hWnd
, UINT CtlID
, LPNMHDR lpnmh
)
178 NMTREEVIEWA
*pnmtv
= (NMTREEVIEWA
*)lpnmh
;
179 LPTV_ITEMDATA lptvid
; /* Long pointer to TreeView item data */
180 IShellFolder
* lpsf2
=0;
183 TRACE("%x %x %p msg=%x\n", hWnd
, CtlID
, lpnmh
, pnmtv
->hdr
.code
);
185 switch (pnmtv
->hdr
.idFrom
)
187 switch (pnmtv
->hdr
.code
)
188 { case TVN_DELETEITEMA
:
189 { FIXME("TVN_DELETEITEMA\n");
190 lptvid
=(LPTV_ITEMDATA
)pnmtv
->itemOld
.lParam
;
191 IShellFolder_Release(lptvid
->lpsfParent
);
193 SHFree(lptvid
->lpifq
);
198 case TVN_ITEMEXPANDINGA
:
199 { FIXME("TVN_ITEMEXPANDINGA\n");
200 if ((pnmtv
->itemNew
.state
& TVIS_EXPANDEDONCE
))
203 lptvid
=(LPTV_ITEMDATA
)pnmtv
->itemNew
.lParam
;
204 if (SUCCEEDED(IShellFolder_BindToObject(lptvid
->lpsfParent
, lptvid
->lpi
,0,(REFIID
)&IID_IShellFolder
,(LPVOID
*)&lpsf2
)))
205 { FillTreeView( lpsf2
, lptvid
->lpifq
, pnmtv
->itemNew
.hItem
);
207 TreeView_SortChildren(hwndTreeView
, pnmtv
->itemNew
.hItem
, FALSE
);
210 case TVN_SELCHANGEDA
:
211 lptvid
=(LPTV_ITEMDATA
)pnmtv
->itemNew
.lParam
;
212 pidlRet
= lptvid
->lpifq
;
213 if (lpBrowseInfo
->lpfn
)
214 (lpBrowseInfo
->lpfn
)(hWnd
, BFFM_SELCHANGED
, (LPARAM
)pidlRet
, lpBrowseInfo
->lParam
);
218 FIXME("unhandled (%d)\n", pnmtv
->hdr
.code
);
231 /*************************************************************************
232 * BrsFolderDlgProc32 (not an exported API function)
234 static BOOL WINAPI
BrsFolderDlgProc( HWND hWnd
, UINT msg
, WPARAM wParam
,
236 { TRACE("hwnd=%i msg=%i 0x%08x 0x%08lx\n", hWnd
, msg
, wParam
, lParam
);
239 { case WM_INITDIALOG
:
241 lpBrowseInfo
= (LPBROWSEINFOA
) lParam
;
242 if (lpBrowseInfo
->ulFlags
& ~(BIF_STATUSTEXT
))
243 FIXME("flags %x not implemented\n", lpBrowseInfo
->ulFlags
& ~(BIF_STATUSTEXT
));
244 if (lpBrowseInfo
->lpszTitle
) {
245 SetWindowTextA(GetDlgItem(hWnd
, IDD_TITLE
), lpBrowseInfo
->lpszTitle
);
247 ShowWindow(GetDlgItem(hWnd
, IDD_TITLE
), SW_HIDE
);
249 if (!(lpBrowseInfo
->ulFlags
& BIF_STATUSTEXT
))
250 ShowWindow(GetDlgItem(hWnd
, IDD_STATUS
), SW_HIDE
);
252 if ( lpBrowseInfo
->pidlRoot
)
253 FIXME("root is desktop\n");
255 InitializeTreeView( hWnd
, lpBrowseInfo
->pidlRoot
);
257 if (lpBrowseInfo
->lpfn
) {
258 (lpBrowseInfo
->lpfn
)(hWnd
, BFFM_INITIALIZED
, 0, lpBrowseInfo
->lParam
);
259 (lpBrowseInfo
->lpfn
)(hWnd
, BFFM_SELCHANGED
, 0/*FIXME*/, lpBrowseInfo
->lParam
);
265 MsgNotify( hWnd
, (UINT
)wParam
, (LPNMHDR
)lParam
);
272 SHGetPathFromIDListA(pidlRet
, lpBrowseInfo
->pszDisplayName
);
273 EndDialog(hWnd
, (DWORD
) ILClone(pidlRet
));
282 case BFFM_SETSTATUSTEXTA
:
283 TRACE("Set status %s\n", debugstr_a((LPSTR
)lParam
));
284 SetWindowTextA(GetDlgItem(hWnd
, IDD_STATUS
), (LPSTR
)lParam
);
286 case BFFM_SETSTATUSTEXTW
:
287 TRACE("Set status %s\n", debugstr_w((LPWSTR
)lParam
));
288 SetWindowTextW(GetDlgItem(hWnd
, IDD_STATUS
), (LPWSTR
)lParam
);
291 TRACE("Enable %ld\n", lParam
);
292 EnableWindow(GetDlgItem(hWnd
, 1), (lParam
)?TRUE
:FALSE
);
294 case BFFM_SETSELECTIONA
:
296 TRACE("Set selection %s\n", debugstr_a((LPSTR
)lParam
));
298 TRACE("Set selection %p\n", (void*)lParam
);
300 case BFFM_SETSELECTIONW
:
302 TRACE("Set selection %s\n", debugstr_w((LPWSTR
)lParam
));
304 TRACE("Set selection %p\n", (void*)lParam
);
310 /*************************************************************************
311 * SHBrowseForFolderA [SHELL32.209]
314 LPITEMIDLIST WINAPI
SHBrowseForFolderA (LPBROWSEINFOA lpbi
)
316 TRACE("(%p{lpszTitle=%s,owner=%i})\n",
317 lpbi
, debugstr_a(lpbi
->lpszTitle
), lpbi
->hwndOwner
);
319 return (LPITEMIDLIST
) DialogBoxParamA( shell32_hInstance
,
320 "SHBRSFORFOLDER_MSGBOX",
322 BrsFolderDlgProc
, (INT
)lpbi
);