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