source: trunk/src/shell32/brsfolder.cpp@ 4032

Last change on this file since 4032 was 4032, checked in by phaller, 25 years ago

Synchronized shell32 with wine

File size: 11.4 KB
Line 
1/* $Id: brsfolder.cpp,v 1.5 2000-08-18 02:01:14 phaller Exp $ */
2
3/*
4 * Win32 SHELL32 for OS/2
5 *
6 * Copyright 1997 Marcus Meissner
7 * Copyright 1999 Patrick Haller (haller@zebra.fh-weingarten.de)
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 * Corel WINE 20000324 level
11 */
12
13
14/*****************************************************************************
15 * Includes *
16 *****************************************************************************/
17
18#include <stdlib.h>
19#include <string.h>
20#include <odin.h>
21#include <odinwrap.h>
22#include <os2sel.h>
23
24#define ICOM_CINTERFACE 1
25
26#include <winbase.h>
27#include "winerror.h"
28#include "heap.h"
29#include "resource.h"
30#include "dlgs.h"
31#include "win.h"
32#include "sysmetrics.h"
33#include "debugtools.h"
34#include "winreg.h"
35#include "authors.h"
36#include "winnls.h"
37#include "commctrl.h"
38#include "spy.h"
39
40#include "wine/obj_base.h"
41#include "wine/obj_enumidlist.h"
42#include "wine/obj_shellfolder.h"
43#include "wine/undocshell.h"
44
45#include "pidl.h"
46#include "shell32_main.h"
47#include "shellapi.h"
48#include "shlguid.h"
49
50#include <misc.h>
51
52
53/*****************************************************************************
54 * Local Variables *
55 *****************************************************************************/
56
57ODINDEBUGCHANNEL(shell32-brsfolder)
58
59#define BRS_SPACE 40
60#define BRS_MARGIN 6
61#define IDD_TREEVIEW 99
62
63static HWND hwndTreeView;
64static LPBROWSEINFOA lpBrowseInfo;
65static LPITEMIDLIST pidlRet;
66
67static void FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq, HTREEITEM hParent);
68
69
70/*****************************************************************************
71 * Implementation *
72 *****************************************************************************/
73
74static void InitializeTreeView(HWND hwndParent)
75{
76 HIMAGELIST hImageList;
77 IShellFolder * lpsf;
78 HRESULT hr;
79
80 dprintf(("SHELL32:brsfolder:InitializeTreeView(%08xh)\n",
81 hwndParent));
82
83 hwndTreeView = GetDlgItem (hwndParent, IDD_TREEVIEW);
84 Shell_GetImageList(NULL, &hImageList);
85
86 if (hImageList && hwndTreeView)
87 { TreeView_SetImageList(hwndTreeView, hImageList, 0);
88 }
89
90 hr = SHGetDesktopFolder(&lpsf);
91
92 if (SUCCEEDED(hr) && hwndTreeView)
93 { TreeView_DeleteAllItems(hwndTreeView);
94 FillTreeView(lpsf, NULL, TVI_ROOT);
95 }
96
97 if (SUCCEEDED(hr))
98 { IShellFolder_Release(lpsf);
99 }
100}
101
102static int GetIcon(LPITEMIDLIST lpi, UINT uFlags)
103{
104 SHFILEINFOA sfi;
105
106 dprintf(("SHELL32:brsfolder:GetIcon(%08xh,%08xh)\n",
107 lpi,
108 uFlags));
109
110 SHGetFileInfoA((LPCSTR)lpi,0,&sfi, sizeof(SHFILEINFOA), uFlags);
111 return sfi.iIcon;
112}
113
114static void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq,LPTVITEMA lpTV_ITEM)
115{
116 dprintf(("SHELL32:brsfolder:GetNormalAndSelectedIcons(%08xh,%08xh)\n",
117 lpifq,
118 lpTV_ITEM));
119
120 lpTV_ITEM->iImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
121 lpTV_ITEM->iSelectedImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON);
122
123 return;
124}
125
126typedef struct tagID
127{
128 LPSHELLFOLDER lpsfParent;
129 LPITEMIDLIST lpi;
130 LPITEMIDLIST lpifq;
131} TV_ITEMDATA, *LPTV_ITEMDATA;
132
133static BOOL GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPSTR lpFriendlyName)
134{
135 BOOL bSuccess=TRUE;
136 STRRET str;
137
138 dprintf(("SHELL32:brsfolder:GetName(%08xh,%08xh,%08xh,%08xh)\n",
139 lpsf,
140 lpi,
141 dwFlags,
142 lpFriendlyName));
143
144 if (SUCCEEDED(IShellFolder_GetDisplayNameOf(lpsf, lpi, dwFlags, &str)))
145 {
146 if(FAILED(StrRetToStrNA (lpFriendlyName, MAX_PATH, &str, lpi)))
147 {
148 bSuccess = FALSE;
149 }
150 }
151 else
152 bSuccess = FALSE;
153
154 TRACE("-- %s\n",lpFriendlyName);
155 return bSuccess;
156}
157
158static void FillTreeView(IShellFolder * lpsf, LPITEMIDLIST pidl, HTREEITEM hParent)
159{
160 TVITEMA tvi;
161 TVINSERTSTRUCTA tvins;
162 HTREEITEM hPrev = 0;
163 LPENUMIDLIST lpe=0;
164 LPITEMIDLIST pidlTemp=0;
165 LPTV_ITEMDATA lptvid=0;
166 ULONG ulFetched;
167 HRESULT hr;
168 char szBuff[256];
169 HWND hwnd=GetParent(hwndTreeView);
170
171 dprintf(("SHELL32:brsfolder:FillTreeView(%08xh,%08xh,%08xh)\n",
172 lpsf,
173 pidl,
174 hParent));
175
176 SetCapture(GetParent(hwndTreeView));
177 SetCursor(LoadCursorA(0, IDC_WAITA));
178
179 hr=IShellFolder_EnumObjects(lpsf,hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,&lpe);
180
181 if (SUCCEEDED(hr))
182 { while (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched))
183 { ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER;
184 IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulAttrs);
185 if (ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER))
186 { if (ulAttrs & SFGAO_FOLDER)
187 { tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
188
189 if (ulAttrs & SFGAO_HASSUBFOLDER)
190 { tvi.cChildren=1;
191 tvi.mask |= TVIF_CHILDREN;
192 }
193
194 if (! ( lptvid = (LPTV_ITEMDATA)SHAlloc(sizeof(TV_ITEMDATA)) ) )
195 goto Done;
196
197 if (!GetName(lpsf, pidlTemp, SHGDN_NORMAL, szBuff))
198 goto Done;
199
200 tvi.pszText = szBuff;
201 tvi.cchTextMax = MAX_PATH;
202 tvi.lParam = (LPARAM)lptvid;
203
204 IShellFolder_AddRef(lpsf);
205 lptvid->lpsfParent = lpsf;
206 lptvid->lpi = ILClone(pidlTemp);
207 lptvid->lpifq = ILCombine(pidl, pidlTemp);
208 GetNormalAndSelectedIcons(lptvid->lpifq, &tvi);
209
210 tvins.DUMMYUNIONNAME.item = tvi;
211 tvins.hInsertAfter = hPrev;
212 tvins.hParent = hParent;
213
214 hPrev = (HTREEITEM)TreeView_InsertItemA (hwndTreeView, &tvins);
215
216 }
217 }
218 SHFree(pidlTemp); /* Finally, free the pidl that the shell gave us... */
219 pidlTemp=0;
220 }
221 }
222
223Done:
224 ReleaseCapture();
225 SetCursor(LoadCursorA(0, IDC_ARROWA));
226
227 if (lpe)
228 IEnumIDList_Release(lpe);
229 if (pidlTemp )
230 SHFree(pidlTemp);
231}
232
233static LRESULT MsgNotify(HWND hWnd, UINT CtlID, LPNMHDR lpnmh)
234{
235 NMTREEVIEWA *pnmtv = (NMTREEVIEWA *)lpnmh;
236 LPTV_ITEMDATA lptvid; /* Long pointer to TreeView item data */
237 IShellFolder * lpsf2=0;
238
239
240 dprintf(("SHELL32:brsfolder:MsgNotify(%08xh,%08xh,%08xh)\n",
241 hWnd,
242 CtlID,
243 lpnmh));
244
245 switch (pnmtv->hdr.idFrom)
246 { case IDD_TREEVIEW:
247 switch (pnmtv->hdr.code)
248 { case TVN_DELETEITEMA:
249 { FIXME("TVN_DELETEITEMA\n");
250 lptvid=(LPTV_ITEMDATA)pnmtv->itemOld.lParam;
251 IShellFolder_Release(lptvid->lpsfParent);
252 SHFree(lptvid->lpi);
253 SHFree(lptvid->lpifq);
254 SHFree(lptvid);
255 }
256 break;
257
258 case TVN_ITEMEXPANDINGA:
259 { FIXME("TVN_ITEMEXPANDINGA\n");
260 if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
261 break;
262
263 lptvid=(LPTV_ITEMDATA)pnmtv->itemNew.lParam;
264 if (SUCCEEDED(IShellFolder_BindToObject(lptvid->lpsfParent, lptvid->lpi,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
265 { FillTreeView( lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem );
266 }
267 TreeView_SortChildren(hwndTreeView, pnmtv->itemNew.hItem, FALSE);
268 }
269 break;
270 case TVN_SELCHANGEDA:
271 lptvid=(LPTV_ITEMDATA)pnmtv->itemNew.lParam;
272 pidlRet = lptvid->lpifq;
273 break;
274
275 default:
276 FIXME("unhandled\n");
277 break;
278 }
279 break;
280
281 default:
282 break;
283 }
284
285 return 0;
286}
287
288/*************************************************************************
289 * ResizeControls (temporary solution and will be removed
290 * if a horizontal scroll bar added to a tree control)
291 */
292
293void ResizeConrols(HWND hWnd, int Cx, int Cy)
294{
295 POINT pt;
296 HWND hBtn;
297 RECT rcCtl;
298
299 // Move the treeView control
300 if(hwndTreeView)
301 {
302 GetWindowRect(hwndTreeView, &rcCtl);
303 pt.y = rcCtl.top;
304 pt.x = rcCtl.left;
305 ScreenToClient(hWnd, &pt);
306 MoveWindow(hwndTreeView, pt.x, pt.y, Cx - pt.x - BRS_MARGIN, Cy - BRS_SPACE, TRUE);
307 }
308
309 // Move the OK button
310 hBtn = GetDlgItem(hWnd, IDOK);
311 if(hBtn)
312 {
313 GetWindowRect(hBtn, &rcCtl);
314 pt.y = Cy - (BRS_MARGIN + (rcCtl.bottom - rcCtl.top));
315 pt.x = Cx - 2 * (2 * BRS_MARGIN + (rcCtl.right - rcCtl.left));
316 MoveWindow(hBtn, pt.x, pt.y, rcCtl.right - rcCtl.left, rcCtl.bottom - rcCtl.top, TRUE);
317 }
318
319 // MOve the cancel button
320 hBtn = GetDlgItem(hWnd, IDCANCEL);
321 if(hBtn)
322 {
323 pt.x = Cx - (2 * BRS_MARGIN + (rcCtl.right - rcCtl.left));
324 MoveWindow(hBtn, pt.x, pt.y, rcCtl.right - rcCtl.left, rcCtl.bottom - rcCtl.top, TRUE);
325 }
326}
327
328/*************************************************************************
329 * BrsFolderDlgProc32 (not an exported API function)
330 */
331ODINFUNCTION4(BOOL, BrsFolderDlgProc, HWND, hWnd,
332 UINT, msg,
333 WPARAM, wParam,
334 LPARAM, lParam)
335{
336 switch(msg)
337 { case WM_INITDIALOG:
338 pidlRet = NULL;
339 lpBrowseInfo = (LPBROWSEINFOA) lParam;
340 if (lpBrowseInfo->lpfn)
341 FIXME("Callbacks not implemented\n");
342 if (lpBrowseInfo->ulFlags)
343 FIXME("flag %x not implemented\n", lpBrowseInfo->ulFlags);
344 if (lpBrowseInfo->lpszTitle)
345 FIXME("title %s not displayed\n", lpBrowseInfo->lpszTitle);
346 if ( lpBrowseInfo->pidlRoot )
347 FIXME("root is desktop\n");
348
349 InitializeTreeView ( hWnd);
350 {
351 RECT rcDlg;
352
353 GetClientRect(hWnd, &rcDlg);
354 ResizeConrols(hWnd, rcDlg.right, rcDlg.bottom);
355 }
356 return 1;
357
358 case WM_SIZE:
359 ResizeConrols(hWnd, LOWORD(lParam), HIWORD(lParam));
360 break;
361
362 case WM_NOTIFY:
363 MsgNotify( hWnd, (UINT)wParam, (LPNMHDR)lParam);
364 break;
365
366 case WM_COMMAND:
367 switch (wParam)
368 { case IDOK:
369 pdump ( pidlRet );
370 SHGetPathFromIDListA(pidlRet, lpBrowseInfo->pszDisplayName);
371 EndDialog(hWnd, (DWORD) ILClone(pidlRet));
372 return TRUE;
373
374 case IDCANCEL:
375 EndDialog(hWnd, 0);
376 return TRUE;
377 }
378 break;
379 }
380 return 0;
381}
382
383/*************************************************************************
384 * SHBrowseForFolderA [SHELL32.209]
385 *
386 */
387ODINFUNCTION1(LPITEMIDLIST, SHBrowseForFolderA, LPBROWSEINFOA, lpbi)
388{
389 TRACE("(%lx,%s) empty stub!\n", (DWORD)lpbi, lpbi->lpszTitle);
390
391 return (LPITEMIDLIST) DialogBoxParamA( shell32_hInstance,
392 "SHBRSFORFOLDER_MSGBOX", 0,
393 BrsFolderDlgProc, (INT)lpbi );
394}
Note: See TracBrowser for help on using the repository browser.