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

Last change on this file since 21447 was 21447, checked in by dmik, 15 years ago

Fixed ntdll build break by gcc4 by fixing DUMMYUNIONNAME/DUMMYSTRUCTNAME macros.

File size: 10.0 KB
Line 
1/* $Id: brsfolder.c,v 1.10 2002-06-27 12:00:23 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_DOT 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#ifdef __WIN32OS2__
244 {
245 //@PF: windows enables the ok button before sending it notifies the app
246 EnableWindow(GetDlgItem(hWnd, 1), TRUE);
247 (lpBrowseInfo->lpfn)(hWnd, BFFM_SELCHANGED, (LPARAM)pidlRet, lpBrowseInfo->lParam);
248 }
249#else
250 (lpBrowseInfo->lpfn)(hWnd, BFFM_SELCHANGED, (LPARAM)pidlRet, lpBrowseInfo->lParam);
251#endif
252 break;
253
254 default:
255 FIXME("unhandled (%d)\n", pnmtv->hdr.code);
256 break;
257 }
258 break;
259
260 default:
261 break;
262 }
263
264 return 0;
265}
266
267
268/*************************************************************************
269 * BrsFolderDlgProc32 (not an exported API function)
270 */
271static BOOL WINAPI BrsFolderDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
272 LPARAM lParam )
273{ TRACE("hwnd=%i msg=%i 0x%08x 0x%08lx\n", hWnd, msg, wParam, lParam );
274
275 switch(msg)
276 { case WM_INITDIALOG:
277 pidlRet = NULL;
278 lpBrowseInfo = (LPBROWSEINFOA) lParam;
279 if (lpBrowseInfo->ulFlags & ~(BIF_STATUSTEXT))
280 FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags & ~(BIF_STATUSTEXT));
281 if (lpBrowseInfo->lpszTitle) {
282 SetWindowTextA(GetDlgItem(hWnd, IDD_TITLE), lpBrowseInfo->lpszTitle);
283 } else {
284 ShowWindow(GetDlgItem(hWnd, IDD_TITLE), SW_HIDE);
285 }
286 if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT))
287 ShowWindow(GetDlgItem(hWnd, IDD_STATUS), SW_HIDE);
288
289 if ( lpBrowseInfo->pidlRoot )
290 FIXME("root is desktop\n");
291
292 InitializeTreeView( hWnd, lpBrowseInfo->pidlRoot );
293
294 if (lpBrowseInfo->lpfn) {
295 (lpBrowseInfo->lpfn)(hWnd, BFFM_INITIALIZED, 0, lpBrowseInfo->lParam);
296#ifndef __WIN32OS2__
297 (lpBrowseInfo->lpfn)(hWnd, BFFM_SELCHANGED, 0/*FIXME*/, lpBrowseInfo->lParam);
298#endif
299 }
300
301 return TRUE;
302
303 case WM_NOTIFY:
304 MsgNotify( hWnd, (UINT)wParam, (LPNMHDR)lParam);
305 break;
306
307 case WM_COMMAND:
308 switch (wParam)
309 { case IDOK:
310 pdump ( pidlRet );
311 SHGetPathFromIDListA(pidlRet, lpBrowseInfo->pszDisplayName);
312 EndDialog(hWnd, (DWORD) ILClone(pidlRet));
313 return TRUE;
314
315 case IDCANCEL:
316 EndDialog(hWnd, 0);
317 return TRUE;
318 break;
319 }
320 break;
321 case BFFM_SETSTATUSTEXTA:
322 TRACE("Set status %s\n", debugstr_a((LPSTR)lParam));
323 SetWindowTextA(GetDlgItem(hWnd, IDD_STATUS), (LPSTR)lParam);
324 break;
325 case BFFM_SETSTATUSTEXTW:
326 TRACE("Set status %s\n", debugstr_w((LPWSTR)lParam));
327 SetWindowTextW(GetDlgItem(hWnd, IDD_STATUS), (LPWSTR)lParam);
328 break;
329 case BFFM_ENABLEOK:
330 TRACE("Enable %ld\n", lParam);
331 EnableWindow(GetDlgItem(hWnd, 1), (lParam)?TRUE:FALSE);
332 break;
333 case BFFM_SETSELECTIONA:
334 if (wParam) {
335 TRACE("Set selection %s\n", debugstr_a((LPSTR)lParam));
336 }
337 else {
338 TRACE("Set selection %p\n", (void*)lParam);
339 }
340 break;
341 case BFFM_SETSELECTIONW:
342 if (wParam) {
343 TRACE("Set selection %s\n", debugstr_w((LPWSTR)lParam));
344 }
345 else {
346 TRACE("Set selection %p\n", (void*)lParam);
347 }
348 break;
349 }
350 return FALSE;
351}
352
353/*************************************************************************
354 * SHBrowseForFolderA [SHELL32.209]
355 *
356 */
357LPITEMIDLIST WIN32API SHBrowseForFolderA(LPBROWSEINFOA lpbi)
358{
359 TRACE("(%p{lpszTitle=%s,owner=%i})\n",
360 lpbi, debugstr_a(lpbi->lpszTitle), lpbi->hwndOwner);
361
362 return (LPITEMIDLIST) DialogBoxParamA( shell32_hInstance,
363 "SHBRSFORFOLDER_MSGBOX",
364 lpbi->hwndOwner,
365 BrsFolderDlgProc, (INT)lpbi );
366}
Note: See TracBrowser for help on using the repository browser.