source: trunk/src/shell32/brsfolder.c@ 8706

Last change on this file since 8706 was 8613, checked in by sandervl, 23 years ago

compile fix

File size: 9.7 KB
Line 
1/* $Id: brsfolder.c,v 1.9 2002-06-09 12:38:17 sandervl Exp $ */
2
3/*
4 * Win32 compatibility SHELL32 BRSFOLDER for OS/2
5 *
6 * Project Odin Software License can be found in LICENSE.TXT
7 *
8 */
9
10
11/****************************************************************************
12 * includes
13 ****************************************************************************/
14
15#include <odin.h>
16#include <os2sel.h>
17#include <odinwrap.h>
18
19ODINDEBUGCHANNEL(SHELL32-BRSFOLDER)
20
21#include <stdlib.h>
22#include <string.h>
23
24#include "debugtools.h"
25#include "undocshell.h"
26#include "shlguid.h"
27#include "pidl.h"
28#include "shell32_main.h"
29#include "shellapi.h"
30#include "shresdef.h"
31
32DEFAULT_DEBUG_CHANNEL(shell);
33
34static HWND hwndTreeView;
35static LPBROWSEINFOA lpBrowseInfo;
36static LPITEMIDLIST pidlRet;
37
38static void FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq, HTREEITEM hParent);
39
40static void InitializeTreeView(HWND hwndParent, LPCITEMIDLIST root)
41{
42 HIMAGELIST hImageList;
43 IShellFolder * lpsf;
44 HRESULT hr;
45
46 hwndTreeView = GetDlgItem (hwndParent, IDD_TREEVIEW);
47 Shell_GetImageList(NULL, &hImageList);
48
49 TRACE("dlg=%x tree=%x\n", hwndParent, hwndTreeView );
50
51 if (hImageList && hwndTreeView)
52 { TreeView_SetImageList(hwndTreeView, hImageList, 0);
53 }
54
55 /* so far, this method doesn't work (still missing the upper level), keep the old way */
56#if 0
57 if (root == NULL) {
58 hr = SHGetDesktopFolder(&lpsf);
59 } else {
60 IShellFolder * lpsfdesktop;
61
62 hr = SHGetDesktopFolder(&lpsfdesktop);
63 if (SUCCEEDED(hr)) {
64 hr = IShellFolder_BindToObject(lpsfdesktop, root, 0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf);
65 IShellFolder_Release(lpsfdesktop);
66 }
67 }
68#else
69 hr = SHGetDesktopFolder(&lpsf);
70#endif
71
72 if (SUCCEEDED(hr) && hwndTreeView)
73 { TreeView_DeleteAllItems(hwndTreeView);
74 FillTreeView(lpsf, NULL, TVI_ROOT);
75#ifdef __WIN32OS2__
76 //@@PF Windows always expands root here. Period.
77 TreeView_Expand(hwndTreeView,TreeView_GetRoot(hwndTreeView),TVE_EXPAND);
78#endif
79 }
80
81 if (SUCCEEDED(hr))
82 { IShellFolder_Release(lpsf);
83 }
84 TRACE("done\n");
85}
86
87static int GetIcon(LPITEMIDLIST lpi, UINT uFlags)
88{ SHFILEINFOA sfi;
89 SHGetFileInfoA((LPCSTR)lpi,0,&sfi, sizeof(SHFILEINFOA), uFlags);
90 return sfi.iIcon;
91}
92
93static void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq,LPTVITEMA lpTV_ITEM)
94{ TRACE("%p %p\n",lpifq, lpTV_ITEM);
95
96 lpTV_ITEM->iImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
97 lpTV_ITEM->iSelectedImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON);
98
99 return;
100}
101
102typedef struct tagID
103{
104 LPSHELLFOLDER lpsfParent;
105 LPITEMIDLIST lpi;
106 LPITEMIDLIST lpifq;
107} TV_ITEMDATA, *LPTV_ITEMDATA;
108
109static BOOL GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPSTR lpFriendlyName)
110{
111 BOOL bSuccess=TRUE;
112 STRRET str;
113
114 TRACE("%p %p %lx %p\n", lpsf, lpi, dwFlags, lpFriendlyName);
115 if (SUCCEEDED(IShellFolder_GetDisplayNameOf(lpsf, lpi, dwFlags, &str)))
116 {
117 if(FAILED(StrRetToStrNA (lpFriendlyName, MAX_PATH, &str, lpi)))
118 {
119 bSuccess = FALSE;
120 }
121 }
122 else
123 bSuccess = FALSE;
124
125 TRACE("-- %s\n",lpFriendlyName);
126 return bSuccess;
127}
128
129static void FillTreeView(IShellFolder * lpsf, LPITEMIDLIST pidl, HTREEITEM hParent)
130{
131 TVITEMA tvi;
132 TVINSERTSTRUCTA tvins;
133 HTREEITEM hPrev = 0;
134 LPENUMIDLIST lpe=0;
135 LPITEMIDLIST pidlTemp=0;
136 LPTV_ITEMDATA lptvid=0;
137 ULONG ulFetched;
138 HRESULT hr;
139 char szBuff[256];
140 HWND hwnd=GetParent(hwndTreeView);
141
142 TRACE("%p %p %x\n",lpsf, pidl, (INT)hParent);
143 SetCapture(GetParent(hwndTreeView));
144 SetCursor(LoadCursorA(0, IDC_WAITA));
145
146 hr=IShellFolder_EnumObjects(lpsf,hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,&lpe);
147
148 if (SUCCEEDED(hr))
149 { while (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched))
150 { ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER;
151 IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulAttrs);
152 if (ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER))
153 { if (ulAttrs & SFGAO_FOLDER)
154 { tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
155
156 if (ulAttrs & SFGAO_HASSUBFOLDER)
157 { tvi.cChildren=1;
158 tvi.mask |= TVIF_CHILDREN;
159 }
160
161 if (!( lptvid = (LPTV_ITEMDATA)SHAlloc(sizeof(TV_ITEMDATA))))
162 goto Done;
163
164 if (!GetName(lpsf, pidlTemp, SHGDN_NORMAL, szBuff))
165 goto Done;
166
167 tvi.pszText = szBuff;
168 tvi.cchTextMax = MAX_PATH;
169 tvi.lParam = (LPARAM)lptvid;
170
171 IShellFolder_AddRef(lpsf);
172 lptvid->lpsfParent = lpsf;
173 lptvid->lpi = ILClone(pidlTemp);
174 lptvid->lpifq = ILCombine(pidl, pidlTemp);
175 GetNormalAndSelectedIcons(lptvid->lpifq, &tvi);
176
177 tvins.DUMMYUNIONNAME.item = tvi;
178 tvins.hInsertAfter = hPrev;
179 tvins.hParent = hParent;
180
181 hPrev = (HTREEITEM)TreeView_InsertItemA (hwndTreeView, &tvins);
182
183 }
184 }
185 SHFree(pidlTemp); /* Finally, free the pidl that the shell gave us... */
186 pidlTemp=0;
187 }
188 }
189
190Done:
191 ReleaseCapture();
192 SetCursor(LoadCursorA(0, IDC_ARROWA));
193
194 if (lpe)
195 IEnumIDList_Release(lpe);
196 if (pidlTemp )
197 SHFree(pidlTemp);
198}
199
200static LRESULT MsgNotify(HWND hWnd, UINT CtlID, LPNMHDR lpnmh)
201{
202 NMTREEVIEWA *pnmtv = (NMTREEVIEWA *)lpnmh;
203 LPTV_ITEMDATA lptvid; /* Long pointer to TreeView item data */
204 IShellFolder * lpsf2=0;
205
206
207 TRACE("%x %x %p msg=%x\n", hWnd, CtlID, lpnmh, pnmtv->hdr.code);
208
209 switch (pnmtv->hdr.idFrom)
210 { case IDD_TREEVIEW:
211 switch (pnmtv->hdr.code)
212 { case TVN_DELETEITEMA:
213 { FIXME("TVN_DELETEITEMA\n");
214 lptvid=(LPTV_ITEMDATA)pnmtv->itemOld.lParam;
215 IShellFolder_Release(lptvid->lpsfParent);
216 SHFree(lptvid->lpi);
217 SHFree(lptvid->lpifq);
218 SHFree(lptvid);
219 }
220 break;
221
222 case TVN_ITEMEXPANDINGA:
223 { FIXME("TVN_ITEMEXPANDINGA\n");
224 if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
225 break;
226
227 lptvid=(LPTV_ITEMDATA)pnmtv->itemNew.lParam;
228 if (SUCCEEDED(IShellFolder_BindToObject(lptvid->lpsfParent, lptvid->lpi,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
229 { FillTreeView( lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem );
230 }
231#ifndef __WIN32OS2__
232 //@PF This is absolutely wrong from all points. First tree we have is
233 //already sorted the way it should. Second we should supply a sort procedure
234 //if needed because otherwise we get sort by name!
235 TreeView_SortChildren(hwndTreeView, pnmtv->itemNew.hItem, FALSE);
236#endif
237 }
238 break;
239 case TVN_SELCHANGEDA:
240 lptvid=(LPTV_ITEMDATA)pnmtv->itemNew.lParam;
241 pidlRet = lptvid->lpifq;
242 if (lpBrowseInfo->lpfn)
243 (lpBrowseInfo->lpfn)(hWnd, BFFM_SELCHANGED, (LPARAM)pidlRet, lpBrowseInfo->lParam);
244 break;
245
246 default:
247 FIXME("unhandled (%d)\n", pnmtv->hdr.code);
248 break;
249 }
250 break;
251
252 default:
253 break;
254 }
255
256 return 0;
257}
258
259
260/*************************************************************************
261 * BrsFolderDlgProc32 (not an exported API function)
262 */
263static BOOL WINAPI BrsFolderDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
264 LPARAM lParam )
265{ TRACE("hwnd=%i msg=%i 0x%08x 0x%08lx\n", hWnd, msg, wParam, lParam );
266
267 switch(msg)
268 { case WM_INITDIALOG:
269 pidlRet = NULL;
270 lpBrowseInfo = (LPBROWSEINFOA) lParam;
271 if (lpBrowseInfo->ulFlags & ~(BIF_STATUSTEXT))
272 FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags & ~(BIF_STATUSTEXT));
273 if (lpBrowseInfo->lpszTitle) {
274 SetWindowTextA(GetDlgItem(hWnd, IDD_TITLE), lpBrowseInfo->lpszTitle);
275 } else {
276 ShowWindow(GetDlgItem(hWnd, IDD_TITLE), SW_HIDE);
277 }
278 if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT))
279 ShowWindow(GetDlgItem(hWnd, IDD_STATUS), SW_HIDE);
280
281 if ( lpBrowseInfo->pidlRoot )
282 FIXME("root is desktop\n");
283
284 InitializeTreeView( hWnd, lpBrowseInfo->pidlRoot );
285
286 if (lpBrowseInfo->lpfn) {
287 (lpBrowseInfo->lpfn)(hWnd, BFFM_INITIALIZED, 0, lpBrowseInfo->lParam);
288#ifndef __WIN32OS2__
289 (lpBrowseInfo->lpfn)(hWnd, BFFM_SELCHANGED, 0/*FIXME*/, lpBrowseInfo->lParam);
290#endif
291 }
292
293 return TRUE;
294
295 case WM_NOTIFY:
296 MsgNotify( hWnd, (UINT)wParam, (LPNMHDR)lParam);
297 break;
298
299 case WM_COMMAND:
300 switch (wParam)
301 { case IDOK:
302 pdump ( pidlRet );
303 SHGetPathFromIDListA(pidlRet, lpBrowseInfo->pszDisplayName);
304 EndDialog(hWnd, (DWORD) ILClone(pidlRet));
305 return TRUE;
306
307 case IDCANCEL:
308 EndDialog(hWnd, 0);
309 return TRUE;
310 break;
311 }
312 break;
313 case BFFM_SETSTATUSTEXTA:
314 TRACE("Set status %s\n", debugstr_a((LPSTR)lParam));
315 SetWindowTextA(GetDlgItem(hWnd, IDD_STATUS), (LPSTR)lParam);
316 break;
317 case BFFM_SETSTATUSTEXTW:
318 TRACE("Set status %s\n", debugstr_w((LPWSTR)lParam));
319 SetWindowTextW(GetDlgItem(hWnd, IDD_STATUS), (LPWSTR)lParam);
320 break;
321 case BFFM_ENABLEOK:
322 TRACE("Enable %ld\n", lParam);
323 EnableWindow(GetDlgItem(hWnd, 1), (lParam)?TRUE:FALSE);
324 break;
325 case BFFM_SETSELECTIONA:
326 if (wParam) {
327 TRACE("Set selection %s\n", debugstr_a((LPSTR)lParam));
328 }
329 else {
330 TRACE("Set selection %p\n", (void*)lParam);
331 }
332 break;
333 case BFFM_SETSELECTIONW:
334 if (wParam) {
335 TRACE("Set selection %s\n", debugstr_w((LPWSTR)lParam));
336 }
337 else {
338 TRACE("Set selection %p\n", (void*)lParam);
339 }
340 break;
341 }
342 return FALSE;
343}
344
345/*************************************************************************
346 * SHBrowseForFolderA [SHELL32.209]
347 *
348 */
349LPITEMIDLIST WIN32API SHBrowseForFolderA(LPBROWSEINFOA lpbi)
350{
351 TRACE("(%p{lpszTitle=%s,owner=%i})\n",
352 lpbi, debugstr_a(lpbi->lpszTitle), lpbi->hwndOwner);
353
354 return (LPITEMIDLIST) DialogBoxParamA( shell32_hInstance,
355 "SHBRSFORFOLDER_MSGBOX",
356 lpbi->hwndOwner,
357 BrsFolderDlgProc, (INT)lpbi );
358}
Note: See TracBrowser for help on using the repository browser.