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

Last change on this file since 3831 was 3243, checked in by cbratschi, 25 years ago

merged with Corel WINE 20000324

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