Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/comdlg32/filedlgbrowser.c
8841 views
1
/*
2
* Implementation of IShellBrowser for the File Open common dialog
3
*
4
* Copyright 1999 Francois Boisvert
5
* Copyright 1999, 2000 Juergen Schmied
6
*
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20
*/
21
22
#include <stdarg.h>
23
#include <stdio.h>
24
#include <string.h>
25
26
#define COBJMACROS
27
#include "windef.h"
28
#include "winbase.h"
29
#include "winnls.h"
30
#include "wingdi.h"
31
#include "winuser.h"
32
#include "winreg.h"
33
34
#define NO_SHLWAPI_STREAM
35
#include "shlwapi.h"
36
#include "filedlgbrowser.h"
37
#include "cdlg.h"
38
#include "shlguid.h"
39
#include "servprov.h"
40
#include "wine/debug.h"
41
42
WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
43
44
typedef struct
45
{
46
47
IShellBrowser IShellBrowser_iface;
48
ICommDlgBrowser ICommDlgBrowser_iface;
49
IServiceProvider IServiceProvider_iface;
50
LONG ref; /* Reference counter */
51
HWND hwndOwner; /* Owner dialog of the interface */
52
53
} IShellBrowserImpl;
54
55
static inline IShellBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
56
{
57
return CONTAINING_RECORD(iface, IShellBrowserImpl, IShellBrowser_iface);
58
}
59
60
static inline IShellBrowserImpl *impl_from_ICommDlgBrowser( ICommDlgBrowser *iface )
61
{
62
return CONTAINING_RECORD(iface, IShellBrowserImpl, ICommDlgBrowser_iface);
63
}
64
65
static inline IShellBrowserImpl *impl_from_IServiceProvider( IServiceProvider *iface )
66
{
67
return CONTAINING_RECORD(iface, IShellBrowserImpl, IServiceProvider_iface);
68
}
69
70
/**************************************************************************
71
* vtable
72
*/
73
static const IShellBrowserVtbl IShellBrowserImpl_Vtbl;
74
static const ICommDlgBrowserVtbl IShellBrowserImpl_ICommDlgBrowser_Vtbl;
75
static const IServiceProviderVtbl IShellBrowserImpl_IServiceProvider_Vtbl;
76
77
/*
78
* Helper functions
79
*/
80
81
#define add_flag(a) if (flags & a) {strcat(str, #a );strcat(str," ");}
82
static void COMDLG32_DumpSBSPFlags(UINT uflags)
83
{
84
if (TRACE_ON(commdlg))
85
{
86
unsigned int i;
87
static const struct {
88
DWORD mask;
89
const char *name;
90
} flags[] = {
91
#define FE(x) { x, #x}
92
/* SBSP_DEFBROWSER == 0 */
93
FE(SBSP_SAMEBROWSER),
94
FE(SBSP_NEWBROWSER),
95
96
/* SBSP_DEFMODE == 0 */
97
FE(SBSP_OPENMODE),
98
FE(SBSP_EXPLOREMODE),
99
FE(SBSP_HELPMODE),
100
FE(SBSP_NOTRANSFERHIST),
101
102
/* SBSP_ABSOLUTE == 0 */
103
FE(SBSP_RELATIVE),
104
FE(SBSP_PARENT),
105
FE(SBSP_NAVIGATEBACK),
106
FE(SBSP_NAVIGATEFORWARD),
107
FE(SBSP_ALLOW_AUTONAVIGATE),
108
109
FE(SBSP_NOAUTOSELECT),
110
FE(SBSP_WRITENOHISTORY),
111
112
FE(SBSP_REDIRECT),
113
FE(SBSP_INITIATEDBYHLINKFRAME),
114
};
115
#undef FE
116
TRACE("SBSP Flags: %08x =", uflags);
117
for (i = 0; i < ARRAY_SIZE(flags); i++)
118
if (flags[i].mask & uflags)
119
TRACE("%s ", flags[i].name);
120
TRACE("\n");
121
}
122
}
123
124
static void COMDLG32_UpdateCurrentDir(const FileOpenDlgInfos *fodInfos)
125
{
126
LPSHELLFOLDER psfDesktop;
127
STRRET strret;
128
HRESULT res;
129
130
res = SHGetDesktopFolder(&psfDesktop);
131
if (FAILED(res))
132
return;
133
134
res = IShellFolder_GetDisplayNameOf(psfDesktop, fodInfos->ShellInfos.pidlAbsCurrent,
135
SHGDN_FORPARSING, &strret);
136
if (SUCCEEDED(res)) {
137
WCHAR wszCurrentDir[MAX_PATH];
138
139
res = StrRetToBufW(&strret, fodInfos->ShellInfos.pidlAbsCurrent, wszCurrentDir, MAX_PATH);
140
if (SUCCEEDED(res))
141
SetCurrentDirectoryW(wszCurrentDir);
142
}
143
144
IShellFolder_Release(psfDesktop);
145
}
146
147
/*
148
* IShellBrowser
149
*/
150
151
/**************************************************************************
152
* IShellBrowserImpl_Construct
153
*/
154
IShellBrowser * IShellBrowserImpl_Construct(HWND hwndOwner)
155
{
156
FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwndOwner);
157
IShellBrowserImpl *sb;
158
159
sb = malloc(sizeof(*sb));
160
161
/* Initialisation of the member variables */
162
sb->ref=1;
163
sb->hwndOwner = hwndOwner;
164
165
/* Initialisation of the vTables */
166
sb->IShellBrowser_iface.lpVtbl = &IShellBrowserImpl_Vtbl;
167
sb->ICommDlgBrowser_iface.lpVtbl = &IShellBrowserImpl_ICommDlgBrowser_Vtbl;
168
sb->IServiceProvider_iface.lpVtbl = &IShellBrowserImpl_IServiceProvider_Vtbl;
169
SHGetSpecialFolderLocation(hwndOwner, CSIDL_DESKTOP,
170
&fodInfos->ShellInfos.pidlAbsCurrent);
171
172
TRACE("%p\n", sb);
173
174
return &sb->IShellBrowser_iface;
175
}
176
177
/***************************************************************************
178
* IShellBrowserImpl_QueryInterface
179
*/
180
static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface, REFIID riid, void **ppvObj)
181
{
182
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
183
184
TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObj);
185
186
*ppvObj = NULL;
187
188
if(IsEqualIID(riid, &IID_IUnknown))
189
*ppvObj = &This->IShellBrowser_iface;
190
else if(IsEqualIID(riid, &IID_IOleWindow))
191
*ppvObj = &This->IShellBrowser_iface;
192
else if(IsEqualIID(riid, &IID_IShellBrowser))
193
*ppvObj = &This->IShellBrowser_iface;
194
else if(IsEqualIID(riid, &IID_ICommDlgBrowser))
195
*ppvObj = &This->ICommDlgBrowser_iface;
196
else if(IsEqualIID(riid, &IID_IServiceProvider))
197
*ppvObj = &This->IServiceProvider_iface;
198
199
if(*ppvObj) {
200
IUnknown_AddRef((IUnknown*)*ppvObj);
201
return S_OK;
202
}
203
204
FIXME("unsupported interface, %s\n", debugstr_guid(riid));
205
return E_NOINTERFACE;
206
}
207
208
/**************************************************************************
209
* IShellBrowser::AddRef
210
*/
211
static ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
212
{
213
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
214
ULONG ref = InterlockedIncrement(&This->ref);
215
216
TRACE("(%p,%lu)\n", This, ref - 1);
217
218
return ref;
219
}
220
221
/**************************************************************************
222
* IShellBrowserImpl_Release
223
*/
224
static ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
225
{
226
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
227
ULONG ref = InterlockedDecrement(&This->ref);
228
229
TRACE("(%p,%lu)\n", This, ref + 1);
230
231
if (!ref)
232
free(This);
233
234
return ref;
235
}
236
237
/*
238
* IOleWindow
239
*/
240
241
/**************************************************************************
242
* IShellBrowserImpl_GetWindow (IOleWindow)
243
*
244
* Inherited from IOleWindow::GetWindow
245
*
246
* See Windows documentation for more details
247
*
248
* Note : We will never be window less in the File Open dialog
249
*
250
*/
251
static HRESULT WINAPI IShellBrowserImpl_GetWindow(IShellBrowser * iface,
252
HWND * phwnd)
253
{
254
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
255
256
TRACE("(%p)\n", This);
257
258
if(!This->hwndOwner)
259
return E_FAIL;
260
261
*phwnd = This->hwndOwner;
262
263
return (*phwnd) ? S_OK : E_UNEXPECTED;
264
265
}
266
267
/**************************************************************************
268
* IShellBrowserImpl_ContextSensitiveHelp
269
*/
270
static HRESULT WINAPI IShellBrowserImpl_ContextSensitiveHelp(IShellBrowser * iface,
271
BOOL fEnterMode)
272
{
273
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
274
275
TRACE("(%p)\n", This);
276
277
/* Feature not implemented */
278
return E_NOTIMPL;
279
}
280
281
/*
282
* IShellBrowser
283
*/
284
285
/**************************************************************************
286
* IShellBrowserImpl_BrowseObject
287
*
288
* See Windows documentation on IShellBrowser::BrowseObject for more details
289
*
290
* This function will override user specified flags and will always
291
* use SBSP_DEFBROWSER and SBSP_DEFMODE.
292
*/
293
static HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface,
294
LPCITEMIDLIST pidl,
295
UINT wFlags)
296
{
297
HRESULT hRes;
298
IShellFolder *folder;
299
IShellView *psvTmp;
300
FileOpenDlgInfos *fodInfos;
301
LPITEMIDLIST pidlTmp;
302
HWND hwndView;
303
HWND hDlgWnd;
304
BOOL bViewHasFocus;
305
RECT rectView;
306
307
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
308
309
TRACE("(%p)(pidl=%p,flags=0x%08x)\n", This, pidl, wFlags);
310
COMDLG32_DumpSBSPFlags(wFlags);
311
312
fodInfos = get_filedlg_infoptr(This->hwndOwner);
313
314
/* Format the pidl according to its parameter's category */
315
if(wFlags & SBSP_RELATIVE)
316
{
317
318
/* SBSP_RELATIVE A relative pidl (relative from the current folder) */
319
if (FAILED(hRes = IShellFolder_BindToObject(fodInfos->Shell.FOIShellFolder,
320
pidl, NULL, &IID_IShellFolder, (void **)&folder)))
321
{
322
ERR("bind to object failed\n");
323
return hRes;
324
}
325
/* create an absolute pidl */
326
pidlTmp = ILCombine(fodInfos->ShellInfos.pidlAbsCurrent, pidl);
327
}
328
else if(wFlags & SBSP_PARENT)
329
{
330
/* Browse the parent folder (ignores the pidl) */
331
pidlTmp = GetParentPidl(fodInfos->ShellInfos.pidlAbsCurrent);
332
folder = GetShellFolderFromPidl(pidlTmp);
333
}
334
else /* SBSP_ABSOLUTE is 0x0000 */
335
{
336
/* An absolute pidl (relative from the desktop) */
337
pidlTmp = ILClone(pidl);
338
folder = GetShellFolderFromPidl(pidlTmp);
339
}
340
341
if (!folder)
342
{
343
ERR("could not browse to folder\n");
344
ILFree(pidlTmp);
345
return E_FAIL;
346
}
347
348
/* If the pidl to browse to is equal to the actual pidl ...
349
do nothing and pretend you did it*/
350
if (ILIsEqual(pidlTmp, fodInfos->ShellInfos.pidlAbsCurrent))
351
{
352
IShellFolder_Release(folder);
353
ILFree(pidlTmp);
354
TRACE("keep current folder\n");
355
return S_OK;
356
}
357
358
/* Release the current DataObject */
359
if (fodInfos->Shell.FOIDataObject)
360
{
361
IDataObject_Release(fodInfos->Shell.FOIDataObject);
362
fodInfos->Shell.FOIDataObject = NULL;
363
}
364
365
/* Create the associated view */
366
TRACE("create view object\n");
367
if (FAILED(hRes = IShellFolder_CreateViewObject(folder, fodInfos->ShellInfos.hwndOwner,
368
&IID_IShellView, (void **)&psvTmp)))
369
{
370
IShellFolder_Release(folder);
371
ILFree(pidlTmp);
372
return hRes;
373
}
374
375
/* Check if listview has focus */
376
bViewHasFocus = IsChild(fodInfos->ShellInfos.hwndView,GetFocus());
377
378
/* Get the foldersettings from the old view */
379
if(fodInfos->Shell.FOIShellView)
380
IShellView_GetCurrentInfo(fodInfos->Shell.FOIShellView, &fodInfos->ShellInfos.folderSettings);
381
382
/* Release the old fodInfos->Shell.FOIShellView and update its value.
383
We have to update this early since ShellView_CreateViewWindow of native
384
shell32 calls OnStateChange and needs the correct view here.*/
385
if(fodInfos->Shell.FOIShellView)
386
{
387
IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
388
IShellView_Release(fodInfos->Shell.FOIShellView);
389
}
390
fodInfos->Shell.FOIShellView = psvTmp;
391
392
/* Release old FOIShellFolder and update its value */
393
if (fodInfos->Shell.FOIShellFolder)
394
IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
395
fodInfos->Shell.FOIShellFolder = folder;
396
397
/* Release old pidlAbsCurrent and update its value */
398
ILFree(fodInfos->ShellInfos.pidlAbsCurrent);
399
fodInfos->ShellInfos.pidlAbsCurrent = pidlTmp;
400
401
COMDLG32_UpdateCurrentDir(fodInfos);
402
403
GetWindowRect(GetDlgItem(This->hwndOwner, IDC_SHELLSTATIC), &rectView);
404
MapWindowPoints(0, This->hwndOwner, (LPPOINT)&rectView, 2);
405
406
/* Create the window */
407
TRACE("create view window\n");
408
if (FAILED(hRes = IShellView_CreateViewWindow(psvTmp, NULL,
409
&fodInfos->ShellInfos.folderSettings, fodInfos->Shell.FOIShellBrowser,
410
&rectView, &hwndView)))
411
{
412
WARN("Failed to create view window, hr %#lx.\n", hRes);
413
return hRes;
414
}
415
416
fodInfos->ShellInfos.hwndView = hwndView;
417
418
/* Set view window control id to 5002 */
419
SetWindowLongPtrW(hwndView, GWLP_ID, lst2);
420
SendMessageW( hwndView, WM_SETFONT, SendMessageW( GetParent(hwndView), WM_GETFONT, 0, 0 ), FALSE );
421
422
/* Select the new folder in the Look In combo box of the Open file dialog */
423
FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,fodInfos->ShellInfos.pidlAbsCurrent);
424
425
/* changes the tab order of the ListView to reflect the window's File Dialog */
426
hDlgWnd = GetDlgItem(GetParent(hwndView), IDC_LOOKIN);
427
SetWindowPos(hwndView, hDlgWnd, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
428
429
/* Since we destroyed the old view if it had focus set focus to the newly created view */
430
if (bViewHasFocus)
431
SetFocus(fodInfos->ShellInfos.hwndView);
432
433
return hRes;
434
}
435
436
/**************************************************************************
437
* IShellBrowserImpl_EnableModelessSB
438
*/
439
static HRESULT WINAPI IShellBrowserImpl_EnableModelessSB(IShellBrowser *iface,
440
BOOL fEnable)
441
442
{
443
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
444
445
TRACE("(%p)\n", This);
446
447
/* Feature not implemented */
448
return E_NOTIMPL;
449
}
450
451
/**************************************************************************
452
* IShellBrowserImpl_GetControlWindow
453
*/
454
static HRESULT WINAPI IShellBrowserImpl_GetControlWindow(IShellBrowser *iface,
455
UINT id,
456
HWND *lphwnd)
457
458
{
459
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
460
461
TRACE("(%p)\n", This);
462
463
/* Feature not implemented */
464
return E_NOTIMPL;
465
}
466
467
/**************************************************************************
468
* IShellBrowserImpl_GetViewStateStream
469
*/
470
static HRESULT WINAPI IShellBrowserImpl_GetViewStateStream(IShellBrowser *iface,
471
DWORD grfMode,
472
LPSTREAM *ppStrm)
473
474
{
475
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
476
477
FIXME("(%p 0x%08lx %p)\n", This, grfMode, ppStrm);
478
479
/* Feature not implemented */
480
return E_NOTIMPL;
481
}
482
483
/**************************************************************************
484
* IShellBrowserImpl_InsertMenusSB
485
*/
486
static HRESULT WINAPI IShellBrowserImpl_InsertMenusSB(IShellBrowser *iface,
487
HMENU hmenuShared,
488
LPOLEMENUGROUPWIDTHS lpMenuWidths)
489
490
{
491
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
492
493
TRACE("(%p)\n", This);
494
495
/* Feature not implemented */
496
return E_NOTIMPL;
497
}
498
499
/**************************************************************************
500
* IShellBrowserImpl_OnViewWindowActive
501
*/
502
static HRESULT WINAPI IShellBrowserImpl_OnViewWindowActive(IShellBrowser *iface,
503
IShellView *ppshv)
504
505
{
506
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
507
508
TRACE("(%p)\n", This);
509
510
/* Feature not implemented */
511
return E_NOTIMPL;
512
}
513
514
/**************************************************************************
515
* IShellBrowserImpl_QueryActiveShellView
516
*/
517
static HRESULT WINAPI IShellBrowserImpl_QueryActiveShellView(IShellBrowser *iface,
518
IShellView **ppshv)
519
520
{
521
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
522
523
FileOpenDlgInfos *fodInfos;
524
525
TRACE("(%p)\n", This);
526
527
fodInfos = get_filedlg_infoptr(This->hwndOwner);
528
529
if(!(*ppshv = fodInfos->Shell.FOIShellView))
530
{
531
return E_FAIL;
532
}
533
IShellView_AddRef(fodInfos->Shell.FOIShellView);
534
return NOERROR;
535
}
536
537
/**************************************************************************
538
* IShellBrowserImpl_RemoveMenusSB
539
*/
540
static HRESULT WINAPI IShellBrowserImpl_RemoveMenusSB(IShellBrowser *iface,
541
HMENU hmenuShared)
542
543
{
544
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
545
546
TRACE("(%p)\n", This);
547
548
/* Feature not implemented */
549
return E_NOTIMPL;
550
}
551
552
/**************************************************************************
553
* IShellBrowserImpl_SendControlMsg
554
*/
555
static HRESULT WINAPI IShellBrowserImpl_SendControlMsg(IShellBrowser *iface,
556
UINT id,
557
UINT uMsg,
558
WPARAM wParam,
559
LPARAM lParam,
560
LRESULT *pret)
561
562
{
563
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
564
LRESULT lres;
565
566
TRACE("(%p)->(0x%08x 0x%08x 0x%08Ix 0x%08Ix %p)\n", This, id, uMsg, wParam, lParam, pret);
567
568
switch (id)
569
{
570
case FCW_TOOLBAR:
571
lres = SendDlgItemMessageA( This->hwndOwner, IDC_TOOLBAR, uMsg, wParam, lParam);
572
break;
573
default:
574
FIXME("ctrl id: %x\n", id);
575
return E_NOTIMPL;
576
}
577
if (pret) *pret = lres;
578
return S_OK;
579
}
580
581
/**************************************************************************
582
* IShellBrowserImpl_SetMenuSB
583
*/
584
static HRESULT WINAPI IShellBrowserImpl_SetMenuSB(IShellBrowser *iface,
585
HMENU hmenuShared,
586
HOLEMENU holemenuReserved,
587
HWND hwndActiveObject)
588
589
{
590
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
591
592
TRACE("(%p)\n", This);
593
594
/* Feature not implemented */
595
return E_NOTIMPL;
596
}
597
598
/**************************************************************************
599
* IShellBrowserImpl_SetStatusTextSB
600
*/
601
static HRESULT WINAPI IShellBrowserImpl_SetStatusTextSB(IShellBrowser *iface,
602
LPCOLESTR lpszStatusText)
603
604
{
605
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
606
607
TRACE("(%p)\n", This);
608
609
/* Feature not implemented */
610
return E_NOTIMPL;
611
}
612
613
/**************************************************************************
614
* IShellBrowserImpl_SetToolbarItems
615
*/
616
static HRESULT WINAPI IShellBrowserImpl_SetToolbarItems(IShellBrowser *iface,
617
LPTBBUTTON lpButtons,
618
UINT nButtons,
619
UINT uFlags)
620
621
{
622
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
623
624
TRACE("(%p)\n", This);
625
626
/* Feature not implemented */
627
return E_NOTIMPL;
628
}
629
630
/**************************************************************************
631
* IShellBrowserImpl_TranslateAcceleratorSB
632
*/
633
static HRESULT WINAPI IShellBrowserImpl_TranslateAcceleratorSB(IShellBrowser *iface,
634
LPMSG lpmsg,
635
WORD wID)
636
637
{
638
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
639
640
TRACE("(%p)\n", This);
641
642
/* Feature not implemented */
643
return E_NOTIMPL;
644
}
645
646
static const IShellBrowserVtbl IShellBrowserImpl_Vtbl =
647
{
648
/* IUnknown */
649
IShellBrowserImpl_QueryInterface,
650
IShellBrowserImpl_AddRef,
651
IShellBrowserImpl_Release,
652
/* IOleWindow */
653
IShellBrowserImpl_GetWindow,
654
IShellBrowserImpl_ContextSensitiveHelp,
655
/* IShellBrowser */
656
IShellBrowserImpl_InsertMenusSB,
657
IShellBrowserImpl_SetMenuSB,
658
IShellBrowserImpl_RemoveMenusSB,
659
IShellBrowserImpl_SetStatusTextSB,
660
IShellBrowserImpl_EnableModelessSB,
661
IShellBrowserImpl_TranslateAcceleratorSB,
662
IShellBrowserImpl_BrowseObject,
663
IShellBrowserImpl_GetViewStateStream,
664
IShellBrowserImpl_GetControlWindow,
665
IShellBrowserImpl_SendControlMsg,
666
IShellBrowserImpl_QueryActiveShellView,
667
IShellBrowserImpl_OnViewWindowActive,
668
IShellBrowserImpl_SetToolbarItems
669
};
670
671
672
673
/*
674
* ICommDlgBrowser
675
*/
676
677
/***************************************************************************
678
* IShellBrowserImpl_ICommDlgBrowser_QueryInterface
679
*/
680
static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_QueryInterface(
681
ICommDlgBrowser *iface,
682
REFIID riid,
683
LPVOID *ppvObj)
684
{
685
IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface);
686
687
TRACE("(%p)\n", This);
688
689
return IShellBrowserImpl_QueryInterface(&This->IShellBrowser_iface,riid,ppvObj);
690
}
691
692
/**************************************************************************
693
* IShellBrowserImpl_ICommDlgBrowser_AddRef
694
*/
695
static ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_AddRef(ICommDlgBrowser * iface)
696
{
697
IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface);
698
699
TRACE("(%p)\n", This);
700
701
return IShellBrowserImpl_AddRef(&This->IShellBrowser_iface);
702
}
703
704
/**************************************************************************
705
* IShellBrowserImpl_ICommDlgBrowser_Release
706
*/
707
static ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_Release(ICommDlgBrowser * iface)
708
{
709
IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface);
710
711
TRACE("(%p)\n", This);
712
713
return IShellBrowserImpl_Release(&This->IShellBrowser_iface);
714
}
715
716
/**************************************************************************
717
* IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand
718
*
719
* Called when a user double-clicks in the view or presses the ENTER key
720
*/
721
static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand(ICommDlgBrowser *iface,
722
IShellView *ppshv)
723
{
724
LPITEMIDLIST pidl;
725
FileOpenDlgInfos *fodInfos;
726
727
IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface);
728
729
TRACE("(%p)\n", This);
730
731
fodInfos = get_filedlg_infoptr(This->hwndOwner);
732
733
/* If the selected object is not a folder, send an IDOK command to parent window */
734
if((pidl = GetPidlFromDataObject(fodInfos->Shell.FOIDataObject, 1)))
735
{
736
HRESULT hRes;
737
738
ULONG ulAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
739
IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, (LPCITEMIDLIST *)&pidl, &ulAttr);
740
if (ulAttr & (SFGAO_FOLDER | SFGAO_HASSUBFOLDER) )
741
{
742
hRes = IShellBrowser_BrowseObject(&This->IShellBrowser_iface,pidl,SBSP_RELATIVE);
743
if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
744
SendCustomDlgNotificationMessage(This->hwndOwner, CDN_FOLDERCHANGE);
745
}
746
else
747
{
748
/* Tell the dialog that the user selected a file */
749
PostMessageA(This->hwndOwner, WM_COMMAND, IDOK, 0L);
750
hRes = S_OK;
751
}
752
753
ILFree(pidl);
754
755
return hRes;
756
}
757
758
return E_FAIL;
759
}
760
761
/**************************************************************************
762
* IShellBrowserImpl_OnSelChange
763
*/
764
static HRESULT IShellBrowserImpl_OnSelChange(IShellBrowserImpl *This, const IShellView *ppshv)
765
{
766
FileOpenDlgInfos *fodInfos;
767
768
fodInfos = get_filedlg_infoptr(This->hwndOwner);
769
TRACE("(%p do=%p view=%p)\n", This, fodInfos->Shell.FOIDataObject, fodInfos->Shell.FOIShellView);
770
771
/* release old selections */
772
if (fodInfos->Shell.FOIDataObject)
773
IDataObject_Release(fodInfos->Shell.FOIDataObject);
774
775
/* get a new DataObject from the ShellView */
776
if(FAILED(IShellView_GetItemObject(fodInfos->Shell.FOIShellView, SVGIO_SELECTION,
777
&IID_IDataObject, (void**)&fodInfos->Shell.FOIDataObject)))
778
return E_FAIL;
779
780
FILEDLG95_FILENAME_FillFromSelection(This->hwndOwner);
781
782
if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
783
SendCustomDlgNotificationMessage(This->hwndOwner, CDN_SELCHANGE);
784
return S_OK;
785
}
786
787
/**************************************************************************
788
* IShellBrowserImpl_ICommDlgBrowser_OnStateChange
789
*/
790
static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnStateChange(ICommDlgBrowser *iface,
791
IShellView *ppshv,
792
ULONG uChange)
793
{
794
795
IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface);
796
797
TRACE("(%p shv=%p)\n", This, ppshv);
798
799
switch (uChange)
800
{
801
case CDBOSC_SETFOCUS:
802
/* FIXME: Reset the default button.
803
This should be taken care of by defdlg. If control
804
other than button receives focus the default button
805
should be restored. */
806
SendMessageA(This->hwndOwner, DM_SETDEFID, IDOK, 0);
807
808
break;
809
case CDBOSC_KILLFOCUS:
810
{
811
FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(This->hwndOwner);
812
if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
813
{
814
WCHAR szSave[16];
815
LoadStringW(COMDLG32_hInstance, IDS_SAVE_BUTTON, szSave, ARRAY_SIZE(szSave));
816
SetDlgItemTextW(fodInfos->ShellInfos.hwndOwner, IDOK, szSave);
817
}
818
}
819
break;
820
case CDBOSC_SELCHANGE:
821
return IShellBrowserImpl_OnSelChange(This, ppshv);
822
case CDBOSC_RENAME:
823
/* nothing to do */
824
break;
825
}
826
827
return NOERROR;
828
}
829
830
/* send_includeitem_notification
831
*
832
* Sends a CDN_INCLUDEITEM notification for "pidl" to hwndParentDlg
833
*/
834
static LRESULT send_includeitem_notification(HWND hwndParentDlg, LPCITEMIDLIST pidl)
835
{
836
LRESULT hook_result = 0;
837
FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwndParentDlg);
838
839
if(!fodInfos) return 0;
840
841
if(fodInfos->DlgInfos.hwndCustomDlg)
842
{
843
TRACE("call notify CDN_INCLUDEITEM for pidl=%p\n", pidl);
844
if(fodInfos->unicode)
845
{
846
OFNOTIFYEXW ofnNotify;
847
ofnNotify.psf = fodInfos->Shell.FOIShellFolder;
848
ofnNotify.pidl = (LPITEMIDLIST)pidl;
849
ofnNotify.hdr.hwndFrom = hwndParentDlg;
850
ofnNotify.hdr.idFrom = 0;
851
ofnNotify.hdr.code = CDN_INCLUDEITEM;
852
ofnNotify.lpOFN = fodInfos->ofnInfos;
853
hook_result = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify);
854
}
855
else
856
{
857
OFNOTIFYEXA ofnNotify;
858
ofnNotify.psf = fodInfos->Shell.FOIShellFolder;
859
ofnNotify.pidl = (LPITEMIDLIST)pidl;
860
ofnNotify.hdr.hwndFrom = hwndParentDlg;
861
ofnNotify.hdr.idFrom = 0;
862
ofnNotify.hdr.code = CDN_INCLUDEITEM;
863
ofnNotify.lpOFN = (LPOPENFILENAMEA)fodInfos->ofnInfos;
864
hook_result = SendMessageA(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify);
865
}
866
}
867
TRACE("Retval: 0x%08Ix\n", hook_result);
868
return hook_result;
869
}
870
871
/**************************************************************************
872
* IShellBrowserImpl_ICommDlgBrowser_IncludeObject
873
*/
874
static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_IncludeObject(ICommDlgBrowser *iface,
875
IShellView * ppshv,
876
LPCITEMIDLIST pidl)
877
{
878
FileOpenDlgInfos *fodInfos;
879
ULONG ulAttr;
880
STRRET str;
881
WCHAR szPathW[MAX_PATH];
882
883
IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface);
884
885
TRACE("(%p)\n", This);
886
887
fodInfos = get_filedlg_infoptr(This->hwndOwner);
888
889
ulAttr = SFGAO_HIDDEN | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_LINK;
890
IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr);
891
892
if( (ulAttr & SFGAO_HIDDEN) || /* hidden */
893
!(ulAttr & (SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR))) /* special folder */
894
return S_FALSE;
895
896
/* always include directories and links */
897
if(ulAttr & (SFGAO_FOLDER | SFGAO_LINK))
898
return S_OK;
899
900
/* if the application takes care of including the item we are done */
901
if(fodInfos->ofnInfos->Flags & OFN_ENABLEINCLUDENOTIFY &&
902
send_includeitem_notification(This->hwndOwner, pidl))
903
return S_OK;
904
905
/* Check if there is a mask to apply if not */
906
if(!fodInfos->ShellInfos.lpstrCurrentFilter || !fodInfos->ShellInfos.lpstrCurrentFilter[0])
907
return S_OK;
908
909
if (SUCCEEDED(IShellFolder_GetDisplayNameOf(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &str)))
910
{
911
if (SUCCEEDED(StrRetToBufW(&str, pidl, szPathW, MAX_PATH)))
912
{
913
if (PathMatchSpecW(szPathW, fodInfos->ShellInfos.lpstrCurrentFilter))
914
return S_OK;
915
}
916
}
917
return S_FALSE;
918
919
}
920
921
static const ICommDlgBrowserVtbl IShellBrowserImpl_ICommDlgBrowser_Vtbl =
922
{
923
/* IUnknown */
924
IShellBrowserImpl_ICommDlgBrowser_QueryInterface,
925
IShellBrowserImpl_ICommDlgBrowser_AddRef,
926
IShellBrowserImpl_ICommDlgBrowser_Release,
927
/* ICommDlgBrowser */
928
IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand,
929
IShellBrowserImpl_ICommDlgBrowser_OnStateChange,
930
IShellBrowserImpl_ICommDlgBrowser_IncludeObject
931
};
932
933
934
935
936
/*
937
* IServiceProvider
938
*/
939
940
/***************************************************************************
941
* IShellBrowserImpl_IServiceProvider_QueryInterface
942
*/
943
static HRESULT WINAPI IShellBrowserImpl_IServiceProvider_QueryInterface(
944
IServiceProvider *iface,
945
REFIID riid,
946
LPVOID *ppvObj)
947
{
948
IShellBrowserImpl *This = impl_from_IServiceProvider(iface);
949
950
FIXME("(%p)\n", This);
951
952
return IShellBrowserImpl_QueryInterface(&This->IShellBrowser_iface,riid,ppvObj);
953
}
954
955
/**************************************************************************
956
* IShellBrowserImpl_IServiceProvider_AddRef
957
*/
958
static ULONG WINAPI IShellBrowserImpl_IServiceProvider_AddRef(IServiceProvider * iface)
959
{
960
IShellBrowserImpl *This = impl_from_IServiceProvider(iface);
961
962
FIXME("(%p)\n", This);
963
964
return IShellBrowserImpl_AddRef(&This->IShellBrowser_iface);
965
}
966
967
/**************************************************************************
968
* IShellBrowserImpl_IServiceProvider_Release
969
*/
970
static ULONG WINAPI IShellBrowserImpl_IServiceProvider_Release(IServiceProvider * iface)
971
{
972
IShellBrowserImpl *This = impl_from_IServiceProvider(iface);
973
974
FIXME("(%p)\n", This);
975
976
return IShellBrowserImpl_Release(&This->IShellBrowser_iface);
977
}
978
979
/**************************************************************************
980
* IShellBrowserImpl_IServiceProvider_Release
981
*
982
* NOTES
983
* the w2k shellview asks for (guidService = SID_STopLevelBrowser,
984
* riid = IShellBrowser) to call SendControlMsg ().
985
*
986
* FIXME
987
* this is a hack!
988
*/
989
990
static HRESULT WINAPI IShellBrowserImpl_IServiceProvider_QueryService(
991
IServiceProvider * iface,
992
REFGUID guidService,
993
REFIID riid,
994
void** ppv)
995
{
996
IShellBrowserImpl *This = impl_from_IServiceProvider(iface);
997
998
FIXME("(%p)\n\t%s\n\t%s\n", This,debugstr_guid(guidService), debugstr_guid(riid) );
999
1000
*ppv = NULL;
1001
if(guidService && IsEqualIID(guidService, &SID_STopLevelBrowser))
1002
return IShellBrowserImpl_QueryInterface(&This->IShellBrowser_iface,riid,ppv);
1003
1004
FIXME("(%p) unknown interface requested\n", This);
1005
return E_NOINTERFACE;
1006
1007
}
1008
1009
static const IServiceProviderVtbl IShellBrowserImpl_IServiceProvider_Vtbl =
1010
{
1011
/* IUnknown */
1012
IShellBrowserImpl_IServiceProvider_QueryInterface,
1013
IShellBrowserImpl_IServiceProvider_AddRef,
1014
IShellBrowserImpl_IServiceProvider_Release,
1015
/* IServiceProvider */
1016
IShellBrowserImpl_IServiceProvider_QueryService
1017
};
1018
1019