source: trunk/src/comdlg32/filedlgbrowser.c@ 3669

Last change on this file since 3669 was 3256, checked in by cbratschi, 25 years ago

* empty log message *

File size: 32.5 KB
Line 
1/* $Id: filedlgbrowser.c,v 1.5 2000-03-28 15:26:48 cbratschi Exp $ */
2/*
3 * Implementation of IShellBrowser for the File Open common dialog
4 *
5 * Copyright 2000 Christoph Bratschi (cbratschi@datacomm.ch)
6 * Project Odin Software License can be found in LICENSE.TXT
7 *
8 * Corel WINE 20000324 level
9 */
10
11#ifdef __WIN32OS2__
12#include <windef.h>
13#include <winbase.h>
14#include <wingdi.h>
15#include <winuser.h>
16#include <heapstring.h>
17#include <misc.h>
18
19#endif
20
21#include <stdio.h>
22#include "unknwn.h"
23#include "filedlgbrowser.h"
24#include "winuser.h"
25#include "heap.h"
26#include "wine/obj_dataobject.h"
27#include "debugtools.h"
28#include "cdlg.h"
29#include "wine/undocshell.h"
30
31DEFAULT_DEBUG_CHANNEL(commdlg)
32
33#define SETDefFormatEtc(fe,cf,med) \
34{ \
35 (fe).cfFormat = cf;\
36 (fe).dwAspect = DVASPECT_CONTENT; \
37 (fe).ptd =NULL;\
38 (fe).tymed = med;\
39 (fe).lindex = -1;\
40};
41
42
43/**************************************************************************
44* Structure
45*/
46static ICOM_VTABLE(IShellBrowser) IShellBrowserImpl_Vtbl =
47{
48 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
49 /* IUnknown */
50 IShellBrowserImpl_QueryInterface,
51 IShellBrowserImpl_AddRef,
52 IShellBrowserImpl_Release,
53 /* IOleWindow */
54 IShellBrowserImpl_GetWindow,
55 IShellBrowserImpl_ContextSensitiveHelp,
56 /* IShellBrowser */
57 IShellBrowserImpl_InsertMenusSB,
58 IShellBrowserImpl_SetMenuSB,
59 IShellBrowserImpl_RemoveMenusSB,
60 IShellBrowserImpl_SetStatusTextSB,
61 IShellBrowserImpl_EnableModelessSB,
62 IShellBrowserImpl_TranslateAcceleratorSB,
63 IShellBrowserImpl_BrowseObject,
64 IShellBrowserImpl_GetViewStateStream,
65 IShellBrowserImpl_GetControlWindow,
66 IShellBrowserImpl_SendControlMsg,
67 IShellBrowserImpl_QueryActiveShellView,
68 IShellBrowserImpl_OnViewWindowActive,
69 IShellBrowserImpl_SetToolbarItems
70};
71
72static ICOM_VTABLE(ICommDlgBrowser) IShellBrowserImpl_ICommDlgBrowser_Vtbl =
73{
74 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
75 /* IUnknown */
76 IShellBrowserImpl_ICommDlgBrowser_QueryInterface,
77 IShellBrowserImpl_ICommDlgBrowser_AddRef,
78 IShellBrowserImpl_ICommDlgBrowser_Release,
79 /* ICommDlgBrowser */
80 IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand,
81 IShellBrowserImpl_ICommDlgBrowser_OnStateChange,
82 IShellBrowserImpl_ICommDlgBrowser_IncludeObject
83};
84
85
86/**************************************************************************
87* Local Prototypes
88*/
89
90HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *iface, IShellView *ppshv);
91#if 0
92LPITEMIDLIST GetSelectedPidl(IShellView *ppshv);
93#endif
94
95/**************************************************************************
96* External Prototypes
97*/
98extern const char *FileOpenDlgInfosStr;
99
100extern HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPSTR lpstrFileName);
101extern HRESULT GetFileName(HWND hwnd, LPITEMIDLIST pidl, LPSTR lpstrFileName);
102extern IShellFolder* GetShellFolderFromPidl(LPITEMIDLIST pidlAbs);
103extern LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl);
104extern LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPCSTR lpcstrFileName);
105
106extern BOOL FILEDLG95_SHELL_FillIncludedItemList(HWND hwnd,
107 LPITEMIDLIST pidlCurrentFolder,
108 LPSTR lpstrMask);
109
110extern int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl);
111extern BOOL FILEDLG95_OnOpen(HWND hwnd);
112extern HRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode);
113
114
115/**************************************************************************
116* IShellBrowserImpl_Construct
117*/
118IShellBrowser * IShellBrowserImpl_Construct(HWND hwndOwner)
119{
120 IShellBrowserImpl *sb;
121 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwndOwner,FileOpenDlgInfosStr);
122
123 sb=(IShellBrowserImpl*)SHAlloc(sizeof(IShellBrowserImpl));
124
125 /* Initialisation of the member variables */
126 sb->ref=1;
127 sb->hwndOwner = hwndOwner;
128
129 /* Initialisation of the vTables */
130 sb->lpVtbl = &IShellBrowserImpl_Vtbl;
131 sb->lpVtbl2 = &IShellBrowserImpl_ICommDlgBrowser_Vtbl;
132
133 COMDLG32_SHGetSpecialFolderLocation(hwndOwner,
134 CSIDL_DESKTOP,
135 &fodInfos->ShellInfos.pidlAbsCurrent);
136
137 TRACE("%p\n", sb);
138
139 return (IShellBrowser *) sb;
140}
141
142/**************************************************************************
143*
144*
145* The INTERFACE of the IShellBrowser object
146*
147*/
148
149/*
150 * IUnknown
151 */
152
153/***************************************************************************
154* IShellBrowserImpl_QueryInterface
155*/
156HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
157 REFIID riid,
158 LPVOID *ppvObj)
159{
160 ICOM_THIS(IShellBrowserImpl, iface);
161
162 TRACE("(%p)\n", This);
163
164 *ppvObj = NULL;
165
166 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
167 { *ppvObj = This;
168 }
169 else if(IsEqualIID(riid, &IID_IOleWindow)) /*IOleWindow*/
170 { *ppvObj = (IOleWindow*)This;
171 }
172
173 else if(IsEqualIID(riid, &IID_IShellBrowser)) /*IShellBrowser*/
174 { *ppvObj = (IShellBrowser*)This;
175 }
176
177 else if(IsEqualIID(riid, &IID_ICommDlgBrowser)) /*ICommDlgBrowser*/
178 { *ppvObj = (ICommDlgBrowser*) &(This->lpVtbl2);
179 }
180
181 if(*ppvObj)
182 { IUnknown_AddRef( (IShellBrowser*) *ppvObj);
183 return S_OK;
184 }
185 return E_NOINTERFACE;
186}
187
188/**************************************************************************
189* IShellBrowser::AddRef
190*/
191ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
192{
193 ICOM_THIS(IShellBrowserImpl, iface);
194
195 TRACE("(%p)\n", This);
196
197 return ++(This->ref);
198}
199
200/**************************************************************************
201* IShellBrowserImpl_Release
202*/
203ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
204{
205 ICOM_THIS(IShellBrowserImpl, iface);
206
207 TRACE("(%p)\n", This);
208
209 if (!--(This->ref))
210 {
211 COMDLG32_SHFree(This);
212 return 0;
213 }
214 return This->ref;
215}
216
217/*
218 * IOleWindow
219 */
220
221/**************************************************************************
222* IShellBrowserImpl_GetWindow (IOleWindow)
223*
224* Inherited from IOleWindow::GetWindow
225*
226* See Windows documentation for more details
227*
228* Note : We will never be window less in the File Open dialog
229*
230*/
231HRESULT WINAPI IShellBrowserImpl_GetWindow(IShellBrowser * iface,
232 HWND * phwnd)
233{
234 ICOM_THIS(IShellBrowserImpl, iface);
235
236 TRACE("(%p)\n", This);
237
238 if(!This->hwndOwner)
239 return E_FAIL;
240
241 *phwnd = This->hwndOwner;
242
243 return (*phwnd) ? S_OK : E_UNEXPECTED;
244
245}
246
247/**************************************************************************
248* IShellBrowserImpl_ContextSensitiveHelp
249*/
250HRESULT WINAPI IShellBrowserImpl_ContextSensitiveHelp(IShellBrowser * iface,
251 BOOL fEnterMode)
252{
253 ICOM_THIS(IShellBrowserImpl, iface);
254
255 TRACE("(%p)\n", This);
256
257 /* Feature not implemented */
258 return E_NOTIMPL;
259}
260
261/*
262 * IShellBrowser
263 */
264
265/**************************************************************************
266* IShellBrowserImpl_BrowseObject
267*
268* See Windows documentation on IShellBrowser::BrowseObject for more details
269*
270* This function will override user specified flags and will always
271* use SBSP_DEFBROWSER and SBSP_DEFMODE.
272*/
273HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface,
274 LPCITEMIDLIST pidl,
275 UINT wFlags)
276{
277 HRESULT hRes;
278 IShellFolder *psfTmp;
279 IShellView *psvTmp;
280 FileOpenDlgInfos *fodInfos;
281 LPITEMIDLIST pidlTmp;
282
283 ICOM_THIS(IShellBrowserImpl, iface);
284
285 TRACE("(%p)\n", This);
286
287 fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
288
289 /* Format the pidl according to its parameter's category */
290 if(wFlags & SBSP_RELATIVE)
291 {
292
293 /* SBSP_RELATIVE A relative pidl (relative from the current folder) */
294 hRes = IShellFolder_BindToObject(fodInfos->Shell.FOIShellFolder,
295 pidl,
296 NULL,
297 &IID_IShellFolder,
298 (LPVOID *)&psfTmp);
299 if(FAILED(hRes))
300 {
301 return hRes;
302 }
303 /* create an absolute pidl */
304 pidlTmp = COMDLG32_PIDL_ILCombine(fodInfos->ShellInfos.pidlAbsCurrent,
305 (LPITEMIDLIST)pidl);
306
307 }
308 else if(wFlags & SBSP_PARENT)
309 {
310 /* Browse the parent folder (ignores the pidl) */
311
312 pidlTmp = GetParentPidl(fodInfos->ShellInfos.pidlAbsCurrent);
313 psfTmp = GetShellFolderFromPidl(pidlTmp);
314
315 }
316 else
317 {
318 /* An absolute pidl (relative from the desktop) */
319 pidlTmp = COMDLG32_PIDL_ILClone((LPITEMIDLIST)pidl);
320 psfTmp = GetShellFolderFromPidl(pidlTmp);
321 }
322
323
324 /* Retrieve the IShellFolder interface of the pidl specified folder */
325 if(!psfTmp)
326 return E_FAIL;
327
328 /* If the pidl to browse to is equal to the actual pidl ...
329 do nothing and pretend you did it*/
330 if(COMDLG32_PIDL_ILIsEqual(pidlTmp,fodInfos->ShellInfos.pidlAbsCurrent))
331 {
332 IShellFolder_Release(psfTmp);
333 COMDLG32_SHFree(pidlTmp);
334 return NOERROR;
335 }
336#ifdef SHELL_NO_DESKTOP
337
338 if(pidlTmp->mkid.cb == 0x00)
339 {
340 IShellFolder_Release(psfTmp);
341 COMDLG32_SHFree(pidlTmp);
342 return NOERROR;
343 }
344#endif
345
346 /* Release the current fodInfos->Shell.FOIShellFolder and update its value */
347 IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
348 fodInfos->Shell.FOIShellFolder = psfTmp;
349
350 /* Create the associated view */
351 if(SUCCEEDED(hRes = IShellFolder_CreateViewObject(psfTmp,
352 fodInfos->ShellInfos.hwndOwner,
353 &IID_IShellView,
354 (LPVOID *)&psvTmp)))
355 {
356 HWND hwndView;
357 HWND hDlgWnd;
358 BOOL bViewHasFocus;
359
360 /* Check if listview has focus */
361 bViewHasFocus = IsChild(fodInfos->ShellInfos.hwndView,GetFocus());
362
363 /* Get the foldersettings from the old view */
364 if(fodInfos->Shell.FOIShellView)
365 {
366 IShellView_GetCurrentInfo(fodInfos->Shell.FOIShellView,
367 &fodInfos->ShellInfos.folderSettings);
368 }
369
370 /* Create the window */
371 if(SUCCEEDED(hRes = IShellView_CreateViewWindow(psvTmp,
372 NULL,
373 &fodInfos->ShellInfos.folderSettings,
374 fodInfos->Shell.FOIShellBrowser,
375 &fodInfos->ShellInfos.rectView,
376 &hwndView)))
377 {
378 /* Fit the created view in the appropriate RECT */
379 MoveWindow(hwndView,
380 fodInfos->ShellInfos.rectView.left,
381 fodInfos->ShellInfos.rectView.top,
382 fodInfos->ShellInfos.rectView.right-fodInfos->ShellInfos.rectView.left,
383 fodInfos->ShellInfos.rectView.bottom-fodInfos->ShellInfos.rectView.top,
384 FALSE);
385
386 /* Select the new folder in the Look In combo box of the Open file dialog */
387
388 FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,pidlTmp);
389
390 /* Release old pidlAbsCurrent memory and update its value */
391 COMDLG32_SHFree((LPVOID)fodInfos->ShellInfos.pidlAbsCurrent);
392 fodInfos->ShellInfos.pidlAbsCurrent = pidlTmp;
393
394 /* Release the current fodInfos->Shell.FOIShellView and update its value */
395 if(fodInfos->Shell.FOIShellView)
396 {
397 IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
398 IShellView_Release(fodInfos->Shell.FOIShellView);
399 }
400#if 0
401 ShowWindow(fodInfos->ShellInfos.hwndView,SW_HIDE);
402#endif
403 fodInfos->Shell.FOIShellView = psvTmp;
404
405 fodInfos->ShellInfos.hwndView = hwndView;
406
407 /* changes the tab order of the ListView to reflect the window's File Dialog */
408 hDlgWnd = GetDlgItem(GetParent(hwndView), IDC_LOOKIN);
409 SetWindowPos(hwndView, hDlgWnd, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
410
411 /* Since we destroyed the old view if it had focus set focus
412 to the newly created view */
413 if (bViewHasFocus)
414 SetFocus(fodInfos->ShellInfos.hwndView);
415
416 return NOERROR;
417 }
418 }
419
420 FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,fodInfos->ShellInfos.pidlAbsCurrent);
421 return hRes;
422}
423
424/**************************************************************************
425* IShellBrowserImpl_EnableModelessSB
426*/
427HRESULT WINAPI IShellBrowserImpl_EnableModelessSB(IShellBrowser *iface,
428 BOOL fEnable)
429
430{
431 ICOM_THIS(IShellBrowserImpl, iface);
432
433 TRACE("(%p)\n", This);
434
435 /* Feature not implemented */
436 return E_NOTIMPL;
437}
438
439/**************************************************************************
440* IShellBrowserImpl_GetControlWindow
441*/
442HRESULT WINAPI IShellBrowserImpl_GetControlWindow(IShellBrowser *iface,
443 UINT id,
444 HWND *lphwnd)
445
446{
447 ICOM_THIS(IShellBrowserImpl, iface);
448
449 TRACE("(%p)\n", This);
450
451 /* Feature not implemented */
452 return E_NOTIMPL;
453}
454/**************************************************************************
455* IShellBrowserImpl_GetViewStateStream
456*/
457HRESULT WINAPI IShellBrowserImpl_GetViewStateStream(IShellBrowser *iface,
458 DWORD grfMode,
459 LPSTREAM *ppStrm)
460
461{
462 ICOM_THIS(IShellBrowserImpl, iface);
463
464 TRACE("(%p)\n", This);
465
466 /* Feature not implemented */
467 return E_NOTIMPL;
468}
469/**************************************************************************
470* IShellBrowserImpl_InsertMenusSB
471*/
472HRESULT WINAPI IShellBrowserImpl_InsertMenusSB(IShellBrowser *iface,
473 HMENU hmenuShared,
474 LPOLEMENUGROUPWIDTHS lpMenuWidths)
475
476{
477 ICOM_THIS(IShellBrowserImpl, iface);
478
479 TRACE("(%p)\n", This);
480
481 /* Feature not implemented */
482 return E_NOTIMPL;
483}
484/**************************************************************************
485* IShellBrowserImpl_OnViewWindowActive
486*/
487HRESULT WINAPI IShellBrowserImpl_OnViewWindowActive(IShellBrowser *iface,
488 IShellView *ppshv)
489
490{
491 ICOM_THIS(IShellBrowserImpl, iface);
492
493 TRACE("(%p)\n", This);
494
495 /* Feature not implemented */
496 return E_NOTIMPL;
497}
498/**************************************************************************
499* IShellBrowserImpl_QueryActiveShellView
500*/
501HRESULT WINAPI IShellBrowserImpl_QueryActiveShellView(IShellBrowser *iface,
502 IShellView **ppshv)
503
504{
505 ICOM_THIS(IShellBrowserImpl, iface);
506
507 FileOpenDlgInfos *fodInfos;
508
509 TRACE("(%p)\n", This);
510
511 fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
512
513 if(!(*ppshv = fodInfos->Shell.FOIShellView))
514 {
515 return E_FAIL;
516 }
517 IShellView_AddRef(fodInfos->Shell.FOIShellView);
518 return NOERROR;
519}
520/**************************************************************************
521* IShellBrowserImpl_RemoveMenusSB
522*/
523HRESULT WINAPI IShellBrowserImpl_RemoveMenusSB(IShellBrowser *iface,
524 HMENU hmenuShared)
525
526{
527 ICOM_THIS(IShellBrowserImpl, iface);
528
529 TRACE("(%p)\n", This);
530
531 /* Feature not implemented */
532 return E_NOTIMPL;
533}
534/**************************************************************************
535* IShellBrowserImpl_SendControlMsg
536*/
537HRESULT WINAPI IShellBrowserImpl_SendControlMsg(IShellBrowser *iface,
538 UINT id,
539 UINT uMsg,
540 WPARAM wParam,
541 LPARAM lParam,
542 LRESULT *pret)
543
544{
545 ICOM_THIS(IShellBrowserImpl, iface);
546 LRESULT lres;
547
548 TRACE("(%p)->(0x%08x 0x%08x 0x%08x 0x%08lx %p)\n", This, id, uMsg, wParam, lParam, pret);
549
550 switch (id)
551 {
552 case FCW_TOOLBAR:
553 lres = SendDlgItemMessageA( This->hwndOwner, IDC_TOOLBAR, uMsg, wParam, lParam);
554 break;
555 default:
556 FIXME("ctrl id: %x\n", id);
557 return E_NOTIMPL;
558 }
559 if (pret) *pret = lres;
560 return S_OK;
561}
562/**************************************************************************
563* IShellBrowserImpl_SetMenuSB
564*/
565HRESULT WINAPI IShellBrowserImpl_SetMenuSB(IShellBrowser *iface,
566 HMENU hmenuShared,
567 HOLEMENU holemenuReserved,
568 HWND hwndActiveObject)
569
570{
571 ICOM_THIS(IShellBrowserImpl, iface);
572
573 TRACE("(%p)\n", This);
574
575 /* Feature not implemented */
576 return E_NOTIMPL;
577}
578/**************************************************************************
579* IShellBrowserImpl_SetStatusTextSB
580*/
581HRESULT WINAPI IShellBrowserImpl_SetStatusTextSB(IShellBrowser *iface,
582 LPCOLESTR lpszStatusText)
583
584{
585 ICOM_THIS(IShellBrowserImpl, iface);
586
587 TRACE("(%p)\n", This);
588
589 /* Feature not implemented */
590 return E_NOTIMPL;
591}
592/**************************************************************************
593* IShellBrowserImpl_SetToolbarItems
594*/
595HRESULT WINAPI IShellBrowserImpl_SetToolbarItems(IShellBrowser *iface,
596 LPTBBUTTON lpButtons,
597 UINT nButtons,
598 UINT uFlags)
599
600{
601 ICOM_THIS(IShellBrowserImpl, iface);
602
603 TRACE("(%p)\n", This);
604
605 /* Feature not implemented */
606 return E_NOTIMPL;
607}
608/**************************************************************************
609* IShellBrowserImpl_TranslateAcceleratorSB
610*/
611HRESULT WINAPI IShellBrowserImpl_TranslateAcceleratorSB(IShellBrowser *iface,
612 LPMSG lpmsg,
613 WORD wID)
614
615{
616 ICOM_THIS(IShellBrowserImpl, iface);
617
618 TRACE("(%p)\n", This);
619
620 /* Feature not implemented */
621 return E_NOTIMPL;
622}
623
624/*
625 * ICommDlgBrowser
626 */
627
628/***************************************************************************
629* IShellBrowserImpl_ICommDlgBrowser_QueryInterface
630*/
631HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_QueryInterface(ICommDlgBrowser *iface,
632 REFIID riid,
633 LPVOID *ppvObj)
634{
635 _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
636
637 TRACE("(%p)\n", This);
638
639 return IShellBrowserImpl_QueryInterface(This,riid,ppvObj);
640}
641
642/**************************************************************************
643* IShellBrowserImpl_ICommDlgBrowser_AddRef
644*/
645ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_AddRef(ICommDlgBrowser * iface)
646{
647 _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
648
649 TRACE("(%p)\n", This);
650
651 return IShellBrowserImpl_AddRef(This);
652}
653
654/**************************************************************************
655* IShellBrowserImpl_ICommDlgBrowser_Release
656*/
657ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_Release(ICommDlgBrowser * iface)
658{
659 _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
660
661 TRACE("(%p)\n", This);
662
663 return IShellBrowserImpl_Release(This);
664}
665/**************************************************************************
666* IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand
667*
668* Called when a user double-clicks in the view or presses the ENTER key
669*/
670HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand(ICommDlgBrowser *iface,
671 IShellView *ppshv)
672{
673 LPITEMIDLIST pidl;
674 FileOpenDlgInfos *fodInfos;
675
676 _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
677
678 TRACE("(%p)\n", This);
679
680 fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
681
682 /* If the selected object is not a folder, send a IDOK command to parent window */
683 pidl = GetSelectedPidl(ppshv);
684 if (pidl)
685 {
686 HRESULT hRes;
687
688 ULONG ulAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
689 IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr);
690 if (ulAttr)
691 hRes = IShellBrowser_BrowseObject((IShellBrowser *)This,pidl,SBSP_RELATIVE);
692 /* Tell the dialog that the user selected a file */
693 else
694 {
695 hRes = PostMessageA(This->hwndOwner, WM_COMMAND, IDOK, 0L);
696 }
697
698 /* Free memory used by pidl */
699 COMDLG32_SHFree((LPVOID)pidl);
700
701 return hRes;
702 }
703
704 return E_FAIL;
705}
706
707/**************************************************************************
708* IShellBrowserImpl_ICommDlgBrowser_OnStateChange
709*/
710HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnStateChange(ICommDlgBrowser *iface,
711 IShellView *ppshv,
712 ULONG uChange)
713{
714
715 _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
716
717 TRACE("(%p)\n", This);
718
719 switch (uChange)
720 {
721 case CDBOSC_SETFOCUS:
722 /* FIXME: Reset the default button.
723 This should be taken care of by defdlg. If control
724 other than button receives focus the default button
725 should be restored. */
726 SendMessageA(This->hwndOwner, DM_SETDEFID, IDOK, 0);
727 break;
728 case CDBOSC_KILLFOCUS:
729 {
730 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
731 if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
732 SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Save");
733 }
734 break;
735 case CDBOSC_SELCHANGE:
736 return IShellBrowserImpl_ICommDlgBrowser_OnSelChange(iface,ppshv);
737 case CDBOSC_RENAME:
738 break;
739 }
740
741 return NOERROR;
742}
743/**************************************************************************
744* IShellBrowserImpl_ICommDlgBrowser_IncludeObject
745*/
746HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_IncludeObject(ICommDlgBrowser *iface,
747 IShellView * ppshv,
748 LPCITEMIDLIST pidl)
749{
750 FileOpenDlgInfos *fodInfos;
751 ULONG ulAttr;
752 STRRET str;
753 WCHAR szPathW[MAX_PATH];
754
755 _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
756
757 TRACE("(%p)\n", This);
758//CB: slow!!!
759 fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
760
761 ulAttr = SFGAO_HIDDEN | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_LINK;
762 IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr);
763
764 if( (ulAttr & SFGAO_HIDDEN) /* hidden */
765 | !(ulAttr & (SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR))) /* special folder */
766 return S_FALSE;
767 /* always include directorys and links */
768 if(ulAttr & (SFGAO_FOLDER | SFGAO_LINK))
769 return S_OK;
770 /* Check if there is a mask to apply if not */
771 if(!fodInfos->ShellInfos.lpstrCurrentFilter ||
772 !lstrlenW(fodInfos->ShellInfos.lpstrCurrentFilter))
773 return S_OK;
774
775 if (SUCCEEDED(IShellFolder_GetDisplayNameOf(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_FORPARSING, &str)))
776 {
777 if (SUCCEEDED(StrRetToBufW(&str, pidl,szPathW, MAX_PATH)))
778 {
779 if (COMDLG32_PathMatchSpecW(szPathW, fodInfos->ShellInfos.lpstrCurrentFilter))
780 return S_OK;
781 }
782 }
783 return S_FALSE;
784}
785
786/**************************************************************************
787* IShellBrowserImpl_ICommDlgBrowser_OnSelChange
788*/
789HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *iface, IShellView *ppshv)
790{
791 ULONG uAttr;
792 FileOpenDlgInfos *fodInfos;
793 UINT nFiles = 0; /* Intial to zero */
794 UINT nCurrLength;
795 UINT nFileToOpen;
796 UINT nAllLength = 2; /* Include intial '"' and final NULL */
797 UINT nSize = MAX_PATH;
798 UINT nFileSelected = 0;
799 LPITEMIDLIST pidlSelection;
800 LPSTR lpstrTemp = NULL;
801 LPSTR lpstrAllFile = NULL;
802 char lpstrCurrFile[MAX_PATH];
803
804 _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
805
806 fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
807 TRACE("(%p)\n", This);
808
809 /* Locate memory and Get selected item counter */
810 if((lpstrAllFile = (LPSTR)SHAlloc(nSize * sizeof(char))) != NULL)
811 {
812 ZeroMemory(lpstrAllFile, nSize * sizeof(char));
813 *lpstrAllFile = '\"';
814 lpstrTemp = lpstrAllFile + 1;
815 nFileSelected = GetNumSelected(fodInfos->Shell.FOIShellView); /* Get all selected counter */
816 }
817
818 /* Count all selected files we have */
819 for(nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++)
820 { /* get the file selected */
821 pidlSelection = NULL;
822 uAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
823 ZeroMemory(lpstrCurrFile, MAX_PATH * sizeof(char));
824 EnumSelectedPidls(fodInfos->Shell.FOIShellView, nFileToOpen, &pidlSelection);
825
826 /* get the file name and attrib of the selected files*/
827 GetName(fodInfos->Shell.FOIShellFolder, pidlSelection, SHGDN_NORMAL, lpstrCurrFile);
828 IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidlSelection, &uAttr);
829 COMDLG32_SHFree((LPVOID) pidlSelection);
830
831 if(!uAttr)
832 { /* Get the new file name */
833 nCurrLength = lstrlenA(lpstrCurrFile);
834 if(nAllLength + nCurrLength + 3 > nSize)
835 { /* increase the memory and transfer string to new location */
836 nSize += MAX_PATH;
837 if((lpstrTemp = (LPSTR)SHAlloc(nSize * sizeof(char))) != NULL)
838 { /* Transfer old file names */
839 ZeroMemory(lpstrTemp, nSize * sizeof(char));
840 lstrcpyA(lpstrTemp, lpstrAllFile);
841 SHFree(lpstrAllFile);
842 lpstrAllFile = lpstrTemp;
843 lpstrTemp = lpstrAllFile + nAllLength - 1;
844 }
845 else
846 { /* if failure, stop the loop to get filename */
847 nFileSelected = 0;
848 }
849 }
850
851 if(lpstrTemp != NULL)
852 { /* Add the new file name */
853 nFiles++;
854 lstrcpyA(lpstrTemp, lpstrCurrFile);
855 *(lpstrTemp + nCurrLength) = '\"';
856 *(lpstrTemp + nCurrLength + 1) = ' ';
857 *(lpstrTemp + nCurrLength + 2) = '\"';
858 nAllLength += nCurrLength + 3;
859 lpstrTemp = lpstrAllFile + nAllLength - 1;
860 }
861 }
862 }
863
864 if(lpstrAllFile)
865 {
866 if(nFiles > 1)
867 {
868 *(lpstrTemp - 2) = '\0';
869 SetWindowTextA(fodInfos->DlgInfos.hwndFileName, lpstrAllFile);
870 }
871 else
872 {
873 *(lpstrTemp - 3) = '\0';
874 SetWindowTextA(fodInfos->DlgInfos.hwndFileName, lpstrAllFile + 1);
875 }
876
877 fodInfos->DlgInfos.dwDlgProp |= FODPROP_USEVIEW;
878 SendCustomDlgNotificationMessage(This->hwndOwner, CDN_SELCHANGE);
879 SHFree( lpstrAllFile );
880 }
881 else
882 {
883 SetWindowTextA(fodInfos->DlgInfos.hwndFileName, "");
884 }
885
886 if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
887 SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner, IDOK, "&Save");
888 else
889 SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner, IDOK, "&Open");
890
891 fodInfos->DlgInfos.dwDlgProp &= ~FODPROP_USEVIEW;
892
893 return nFileSelected ? S_OK : E_FAIL;
894}
895
896/***********************************************************************
897 * GetSelectedPidl
898 *
899 * Return the pidl of the first selected item in the view
900 */
901LPITEMIDLIST GetSelectedPidl(IShellView *ppshv)
902{
903
904 IDataObject *doSelected;
905 LPITEMIDLIST pidlSelected = NULL;
906
907 TRACE("sv=%p\n", ppshv);
908
909 /* Get an IDataObject from the view */
910 if(SUCCEEDED(IShellView_GetItemObject(ppshv,
911 SVGIO_SELECTION,
912 &IID_IDataObject,
913 (LPVOID *)&doSelected)))
914 {
915 STGMEDIUM medium;
916 FORMATETC formatetc;
917
918 /* Set the FORMATETC structure*/
919 SETDefFormatEtc(formatetc,
920 RegisterClipboardFormatA(CFSTR_SHELLIDLIST),
921 TYMED_HGLOBAL);
922
923 /* Get the pidl from IDataObject */
924 if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
925 {
926 LPIDA cida = GlobalLock(medium.u.hGlobal);
927 TRACE("cida=%p\n", cida);
928 pidlSelected = COMDLG32_PIDL_ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[1]]));
929
930 if(medium.pUnkForRelease)
931 IUnknown_Release(medium.pUnkForRelease);
932 else
933 {
934 GlobalUnlock(medium.u.hGlobal);
935 GlobalFree(medium.u.hGlobal);
936 }
937 }
938 IDataObject_Release(doSelected);
939 return pidlSelected;
940 }
941
942 return NULL;
943}
944
945/***********************************************************************
946 * EnumSelectedPidls
947 *
948 * Return the pidl(s) of the selected item(s) in the view.
949 *
950*/
951BOOL EnumSelectedPidls( IShellView *ppshv, /*[in]*/
952 UINT nPidlIndex, /*[in]*/
953 LPITEMIDLIST *pidlSelected /*[out]*/ )
954{
955
956 IDataObject *doSelected;
957 BOOL retVal = TRUE;
958
959 /* Get an IDataObject from the view */
960 if(SUCCEEDED(IShellView_GetItemObject(ppshv,
961 SVGIO_SELECTION,
962 &IID_IDataObject,
963 (LPVOID *)&doSelected)))
964 {
965 STGMEDIUM medium;
966 FORMATETC formatetc;
967
968 /* Set the FORMATETC structure*/
969 SETDefFormatEtc(formatetc,
970 RegisterClipboardFormatA(CFSTR_SHELLIDLIST),
971 TYMED_HGLOBAL);
972
973 /* Get the pidls from IDataObject */
974 if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
975 {
976 LPIDA cida = GlobalLock(medium.u.hGlobal);
977 if(nPidlIndex < cida->cidl)
978 {
979 *pidlSelected = COMDLG32_PIDL_ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[nPidlIndex + 1]]));
980 }
981 else
982 {
983 retVal = FALSE;
984 }
985
986 if(medium.pUnkForRelease)
987 {
988 IUnknown_Release(medium.pUnkForRelease);
989 }
990 else
991 {
992 GlobalUnlock(medium.u.hGlobal);
993 GlobalFree(medium.u.hGlobal);
994 }
995 }
996 IDataObject_Release(doSelected);
997 return retVal;
998 }
999 return FALSE;
1000}
1001
1002/***********************************************************************
1003 * GetNumSelected
1004 *
1005 * Return the number of selected items in the view.
1006 *
1007*/
1008UINT GetNumSelected( IShellView *ppshv )
1009{
1010 IDataObject *doSelected;
1011 UINT retVal = 0;
1012
1013 /* Get an IDataObject from the view */
1014 if(SUCCEEDED(IShellView_GetItemObject(ppshv,
1015 SVGIO_SELECTION,
1016 &IID_IDataObject,
1017 (LPVOID *)&doSelected)))
1018 {
1019 STGMEDIUM medium;
1020 FORMATETC formatetc;
1021
1022 /* Set the FORMATETC structure*/
1023 SETDefFormatEtc(formatetc,
1024 RegisterClipboardFormatA(CFSTR_SHELLIDLIST),
1025 TYMED_HGLOBAL);
1026
1027 /* Get the pidls from IDataObject */
1028 if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
1029 {
1030 LPIDA cida = GlobalLock(medium.u.hGlobal);
1031 retVal = cida->cidl;
1032
1033 if(medium.pUnkForRelease)
1034 IUnknown_Release(medium.pUnkForRelease);
1035 else
1036 {
1037 GlobalUnlock(medium.u.hGlobal);
1038 GlobalFree(medium.u.hGlobal);
1039 }
1040 }
1041 IDataObject_Release(doSelected);
1042 return retVal;
1043 }
1044
1045 return 0;
1046}
1047
1048
1049
Note: See TracBrowser for help on using the repository browser.