Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/programs/explorer/desktop.c
4388 views
1
/*
2
* Explorer desktop support
3
*
4
* Copyright 2006 Alexandre Julliard
5
* Copyright 2013 Hans Leidekker for CodeWeavers
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 <stdio.h>
23
24
#define COBJMACROS
25
#define OEMRESOURCE
26
#include <windows.h>
27
#include <winternl.h>
28
#include <rpc.h>
29
#include <shlobj.h>
30
#include <shellapi.h>
31
#include <ntuser.h>
32
#include "exdisp.h"
33
34
#include "wine/debug.h"
35
#include "explorer_private.h"
36
#include "resource.h"
37
38
WINE_DEFAULT_DEBUG_CHANNEL(explorer);
39
40
#define DESKTOP_CLASS_ATOM ((LPCWSTR)MAKEINTATOM(32769))
41
#define DESKTOP_ALL_ACCESS 0x01ff
42
43
static const WCHAR default_driver[] = L"mac,x11,wayland";
44
45
static BOOL using_root = TRUE;
46
47
struct launcher
48
{
49
WCHAR *path;
50
HICON icon;
51
WCHAR *title;
52
};
53
54
static WCHAR *desktop_folder;
55
static WCHAR *desktop_folder_public;
56
57
static int icon_cx, icon_cy, icon_offset_cx, icon_offset_cy;
58
static int title_cx, title_cy, title_offset_cx, title_offset_cy;
59
static int desktop_width, launcher_size, launchers_per_row;
60
61
static struct launcher **launchers;
62
static unsigned int nb_launchers, nb_allocated;
63
64
static REFIID tid_ids[] =
65
{
66
&IID_IShellWindows,
67
&IID_IWebBrowser2
68
};
69
70
typedef enum
71
{
72
IShellWindows_tid,
73
IWebBrowser2_tid,
74
LAST_tid
75
} tid_t;
76
77
static ITypeLib *typelib;
78
static ITypeInfo *typeinfos[LAST_tid];
79
80
static HRESULT load_typelib(void)
81
{
82
HRESULT hres;
83
ITypeLib *tl;
84
85
hres = LoadRegTypeLib(&LIBID_SHDocVw, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
86
if (FAILED(hres))
87
{
88
ERR("LoadRegTypeLib failed: %08lx\n", hres);
89
return hres;
90
}
91
92
if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
93
ITypeLib_Release(tl);
94
return hres;
95
}
96
97
static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
98
{
99
HRESULT hres;
100
101
if (!typelib) {
102
hres = load_typelib();
103
if (!typelib)
104
return hres;
105
}
106
107
if (!typeinfos[tid]) {
108
ITypeInfo *ti;
109
110
hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
111
if (FAILED(hres)) {
112
ERR("GetTypeInfoOfGuid(%s) failed: %08lx\n", debugstr_guid(tid_ids[tid]), hres);
113
return hres;
114
}
115
116
if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
117
ITypeInfo_Release(ti);
118
}
119
120
*typeinfo = typeinfos[tid];
121
ITypeInfo_AddRef(*typeinfo);
122
return S_OK;
123
}
124
125
static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
126
{
127
unsigned int new_capacity, max_capacity;
128
void *new_elements;
129
130
if (count <= *capacity)
131
return TRUE;
132
133
max_capacity = ~(SIZE_T)0 / size;
134
if (count > max_capacity)
135
return FALSE;
136
137
new_capacity = max(4, *capacity);
138
while (new_capacity < count && new_capacity <= max_capacity / 2)
139
new_capacity *= 2;
140
if (new_capacity < count)
141
new_capacity = max_capacity;
142
143
if (!(new_elements = realloc(*elements, new_capacity * size)))
144
return FALSE;
145
146
*elements = new_elements;
147
*capacity = new_capacity;
148
149
return TRUE;
150
}
151
152
static LONG cookie_counter;
153
154
struct window
155
{
156
LONG cookie, hwnd;
157
int class;
158
ITEMIDLIST *pidl;
159
};
160
161
struct shellwindows
162
{
163
IShellWindows IShellWindows_iface;
164
CRITICAL_SECTION cs;
165
166
unsigned int count, max;
167
struct window *windows;
168
};
169
170
/* This is not limited to desktop itself, every file browser window that
171
explorer creates supports that. Desktop instance is special in some
172
aspects, for example navigation is not possible, you can't show/hide it,
173
or bring up a menu. CLSID_ShellBrowserWindow class could be used to
174
create instances like that, and they should be registered with
175
IShellWindows as well. */
176
struct shellbrowserwindow
177
{
178
IWebBrowser2 IWebBrowser2_iface;
179
IServiceProvider IServiceProvider_iface;
180
IShellBrowser IShellBrowser_iface;
181
IShellView *view;
182
};
183
184
static struct shellwindows shellwindows;
185
static struct shellbrowserwindow desktopshellbrowserwindow;
186
187
static inline struct shellwindows *impl_from_IShellWindows(IShellWindows *iface)
188
{
189
return CONTAINING_RECORD(iface, struct shellwindows, IShellWindows_iface);
190
}
191
192
static inline struct shellbrowserwindow *impl_from_IWebBrowser2(IWebBrowser2 *iface)
193
{
194
return CONTAINING_RECORD(iface, struct shellbrowserwindow, IWebBrowser2_iface);
195
}
196
197
static inline struct shellbrowserwindow *impl_from_IServiceProvider(IServiceProvider *iface)
198
{
199
return CONTAINING_RECORD(iface, struct shellbrowserwindow, IServiceProvider_iface);
200
}
201
202
static inline struct shellbrowserwindow *impl_from_IShellBrowser(IShellBrowser *iface)
203
{
204
return CONTAINING_RECORD(iface, struct shellbrowserwindow, IShellBrowser_iface);
205
}
206
207
static void shellwindows_init(void);
208
static void desktopshellbrowserwindow_init(void);
209
210
static RECT get_icon_rect( unsigned int index )
211
{
212
RECT rect;
213
unsigned int row = index / launchers_per_row;
214
unsigned int col = index % launchers_per_row;
215
216
rect.left = col * launcher_size + icon_offset_cx;
217
rect.right = rect.left + icon_cx;
218
rect.top = row * launcher_size + icon_offset_cy;
219
rect.bottom = rect.top + icon_cy;
220
return rect;
221
}
222
223
static RECT get_title_rect( unsigned int index )
224
{
225
RECT rect;
226
unsigned int row = index / launchers_per_row;
227
unsigned int col = index % launchers_per_row;
228
229
rect.left = col * launcher_size + title_offset_cx;
230
rect.right = rect.left + title_cx;
231
rect.top = row * launcher_size + title_offset_cy;
232
rect.bottom = rect.top + title_cy;
233
return rect;
234
}
235
236
static const struct launcher *launcher_from_point( int x, int y )
237
{
238
RECT icon, title;
239
unsigned int index;
240
241
if (!nb_launchers) return NULL;
242
index = x / launcher_size + (y / launcher_size) * launchers_per_row;
243
if (index >= nb_launchers) return NULL;
244
245
icon = get_icon_rect( index );
246
title = get_title_rect( index );
247
if ((x < icon.left || x > icon.right || y < icon.top || y > icon.bottom) &&
248
(x < title.left || x > title.right || y < title.top || y > title.bottom)) return NULL;
249
return launchers[index];
250
}
251
252
static void draw_launchers( HDC hdc, RECT update_rect )
253
{
254
COLORREF color = SetTextColor( hdc, RGB(255,255,255) ); /* FIXME: depends on background color */
255
int mode = SetBkMode( hdc, TRANSPARENT );
256
unsigned int i;
257
LOGFONTW lf;
258
HFONT font;
259
260
SystemParametersInfoW( SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0 );
261
font = SelectObject( hdc, CreateFontIndirectW( &lf ) );
262
263
for (i = 0; i < nb_launchers; i++)
264
{
265
RECT dummy, icon = get_icon_rect( i ), title = get_title_rect( i );
266
267
if (IntersectRect( &dummy, &icon, &update_rect ))
268
DrawIconEx( hdc, icon.left, icon.top, launchers[i]->icon, icon_cx, icon_cy,
269
0, 0, DI_DEFAULTSIZE|DI_NORMAL );
270
271
if (IntersectRect( &dummy, &title, &update_rect ))
272
DrawTextW( hdc, launchers[i]->title, -1, &title,
273
DT_CENTER|DT_WORDBREAK|DT_EDITCONTROL|DT_END_ELLIPSIS );
274
}
275
276
font = SelectObject( hdc, font );
277
DeleteObject( font );
278
SetTextColor( hdc, color );
279
SetBkMode( hdc, mode );
280
}
281
282
static WCHAR *append_path( const WCHAR *path, const WCHAR *filename, int len_filename )
283
{
284
int len_path = lstrlenW( path );
285
WCHAR *ret;
286
287
if (len_filename == -1) len_filename = lstrlenW( filename );
288
if (!(ret = malloc( (len_path + len_filename + 2) * sizeof(WCHAR) ))) return NULL;
289
memcpy( ret, path, len_path * sizeof(WCHAR) );
290
ret[len_path] = '\\';
291
memcpy( ret + len_path + 1, filename, len_filename * sizeof(WCHAR) );
292
ret[len_path + 1 + len_filename] = 0;
293
return ret;
294
}
295
296
static IShellLinkW *load_shelllink( const WCHAR *path )
297
{
298
HRESULT hr;
299
IShellLinkW *link;
300
IPersistFile *file;
301
302
hr = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW,
303
(void **)&link );
304
if (FAILED( hr )) return NULL;
305
306
hr = IShellLinkW_QueryInterface( link, &IID_IPersistFile, (void **)&file );
307
if (FAILED( hr ))
308
{
309
IShellLinkW_Release( link );
310
return NULL;
311
}
312
hr = IPersistFile_Load( file, path, 0 );
313
IPersistFile_Release( file );
314
if (FAILED( hr ))
315
{
316
IShellLinkW_Release( link );
317
return NULL;
318
}
319
return link;
320
}
321
322
static HICON extract_icon( IShellLinkW *link )
323
{
324
WCHAR tmp_path[MAX_PATH], icon_path[MAX_PATH], target_path[MAX_PATH];
325
HICON icon = NULL;
326
int index;
327
328
tmp_path[0] = 0;
329
IShellLinkW_GetIconLocation( link, tmp_path, MAX_PATH, &index );
330
ExpandEnvironmentStringsW( tmp_path, icon_path, MAX_PATH );
331
332
if (icon_path[0]) ExtractIconExW( icon_path, index, &icon, NULL, 1 );
333
if (!icon)
334
{
335
tmp_path[0] = 0;
336
IShellLinkW_GetPath( link, tmp_path, MAX_PATH, NULL, SLGP_RAWPATH );
337
ExpandEnvironmentStringsW( tmp_path, target_path, MAX_PATH );
338
ExtractIconExW( target_path, index, &icon, NULL, 1 );
339
}
340
return icon;
341
}
342
343
static WCHAR *build_title( const WCHAR *filename, int len )
344
{
345
const WCHAR *p;
346
WCHAR *ret;
347
348
if (len == -1) len = lstrlenW( filename );
349
for (p = filename + len - 1; p >= filename; p--)
350
{
351
if (*p == '.')
352
{
353
len = p - filename;
354
break;
355
}
356
}
357
if (!(ret = malloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
358
memcpy( ret, filename, len * sizeof(WCHAR) );
359
ret[len] = 0;
360
return ret;
361
}
362
363
static BOOL add_launcher( const WCHAR *folder, const WCHAR *filename, int len_filename )
364
{
365
struct launcher *launcher;
366
IShellLinkW *link;
367
368
if (nb_launchers == nb_allocated)
369
{
370
unsigned int count = nb_allocated * 2;
371
struct launcher **tmp = realloc( launchers, count * sizeof(*tmp) );
372
if (!tmp) return FALSE;
373
launchers = tmp;
374
nb_allocated = count;
375
}
376
377
if (!(launcher = malloc( sizeof(*launcher) ))) return FALSE;
378
if (!(launcher->path = append_path( folder, filename, len_filename ))) goto error;
379
if (!(link = load_shelllink( launcher->path ))) goto error;
380
381
launcher->icon = extract_icon( link );
382
launcher->title = build_title( filename, len_filename );
383
IShellLinkW_Release( link );
384
if (launcher->icon && launcher->title)
385
{
386
launchers[nb_launchers++] = launcher;
387
return TRUE;
388
}
389
free( launcher->title );
390
DestroyIcon( launcher->icon );
391
392
error:
393
free( launcher->path );
394
free( launcher );
395
return FALSE;
396
}
397
398
static void free_launcher( struct launcher *launcher )
399
{
400
DestroyIcon( launcher->icon );
401
free( launcher->path );
402
free( launcher->title );
403
free( launcher );
404
}
405
406
static BOOL remove_launcher( const WCHAR *folder, const WCHAR *filename, int len_filename )
407
{
408
UINT i;
409
WCHAR *path;
410
BOOL ret = FALSE;
411
412
if (!(path = append_path( folder, filename, len_filename ))) return FALSE;
413
for (i = 0; i < nb_launchers; i++)
414
{
415
if (!wcsicmp( launchers[i]->path, path ))
416
{
417
free_launcher( launchers[i] );
418
if (--nb_launchers)
419
memmove( &launchers[i], &launchers[i + 1], sizeof(launchers[i]) * (nb_launchers - i) );
420
ret = TRUE;
421
break;
422
}
423
}
424
free( path );
425
return ret;
426
}
427
428
static BOOL get_icon_text_metrics( HWND hwnd, TEXTMETRICW *tm )
429
{
430
BOOL ret;
431
HDC hdc;
432
LOGFONTW lf;
433
HFONT hfont;
434
435
hdc = GetDC( hwnd );
436
SystemParametersInfoW( SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0 );
437
hfont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
438
ret = GetTextMetricsW( hdc, tm );
439
hfont = SelectObject( hdc, hfont );
440
DeleteObject( hfont );
441
ReleaseDC( hwnd, hdc );
442
return ret;
443
}
444
445
static BOOL process_changes( const WCHAR *folder, char *buf )
446
{
447
FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION *)buf;
448
BOOL ret = FALSE;
449
450
for (;;)
451
{
452
switch (info->Action)
453
{
454
case FILE_ACTION_ADDED:
455
case FILE_ACTION_RENAMED_NEW_NAME:
456
if (add_launcher( folder, info->FileName, info->FileNameLength / sizeof(WCHAR) ))
457
ret = TRUE;
458
break;
459
460
case FILE_ACTION_REMOVED:
461
case FILE_ACTION_RENAMED_OLD_NAME:
462
if (remove_launcher( folder, info->FileName, info->FileNameLength / sizeof(WCHAR) ))
463
ret = TRUE;
464
break;
465
466
default:
467
WARN( "unexpected action %lu\n", info->Action );
468
break;
469
}
470
if (!info->NextEntryOffset) break;
471
info = (FILE_NOTIFY_INFORMATION *)((char *)info + info->NextEntryOffset);
472
}
473
return ret;
474
}
475
476
static DWORD CALLBACK watch_desktop_folders( LPVOID param )
477
{
478
HWND hwnd = param;
479
HRESULT init = CoInitialize( NULL );
480
HANDLE dir0, dir1, events[2];
481
OVERLAPPED ovl0, ovl1;
482
char *buf0 = NULL, *buf1 = NULL;
483
DWORD count, size = 4096, error = ERROR_OUTOFMEMORY;
484
BOOL ret, redraw;
485
486
dir0 = CreateFileW( desktop_folder, FILE_LIST_DIRECTORY|SYNCHRONIZE, FILE_SHARE_READ|FILE_SHARE_WRITE,
487
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL );
488
if (dir0 == INVALID_HANDLE_VALUE) return GetLastError();
489
dir1 = CreateFileW( desktop_folder_public, FILE_LIST_DIRECTORY|SYNCHRONIZE, FILE_SHARE_READ|FILE_SHARE_WRITE,
490
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL );
491
if (dir1 == INVALID_HANDLE_VALUE)
492
{
493
CloseHandle( dir0 );
494
return GetLastError();
495
}
496
if (!(ovl0.hEvent = events[0] = CreateEventW( NULL, FALSE, FALSE, NULL ))) goto error;
497
if (!(ovl1.hEvent = events[1] = CreateEventW( NULL, FALSE, FALSE, NULL ))) goto error;
498
if (!(buf0 = malloc( size ))) goto error;
499
if (!(buf1 = malloc( size ))) goto error;
500
501
for (;;)
502
{
503
ret = ReadDirectoryChangesW( dir0, buf0, size, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ovl0, NULL );
504
if (!ret)
505
{
506
error = GetLastError();
507
goto error;
508
}
509
ret = ReadDirectoryChangesW( dir1, buf1, size, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ovl1, NULL );
510
if (!ret)
511
{
512
error = GetLastError();
513
goto error;
514
}
515
516
redraw = FALSE;
517
switch ((error = WaitForMultipleObjects( 2, events, FALSE, INFINITE )))
518
{
519
case WAIT_OBJECT_0:
520
if (!GetOverlappedResult( dir0, &ovl0, &count, FALSE ) || !count) break;
521
if (process_changes( desktop_folder, buf0 )) redraw = TRUE;
522
break;
523
524
case WAIT_OBJECT_0 + 1:
525
if (!GetOverlappedResult( dir1, &ovl1, &count, FALSE ) || !count) break;
526
if (process_changes( desktop_folder_public, buf1 )) redraw = TRUE;
527
break;
528
529
default:
530
goto error;
531
}
532
if (redraw) InvalidateRect( hwnd, NULL, TRUE );
533
}
534
535
error:
536
CloseHandle( dir0 );
537
CloseHandle( dir1 );
538
CloseHandle( events[0] );
539
CloseHandle( events[1] );
540
free( buf0 );
541
free( buf1 );
542
if (SUCCEEDED( init )) CoUninitialize();
543
return error;
544
}
545
546
static void add_folder( const WCHAR *folder )
547
{
548
static const WCHAR lnkW[] = L"\\*.lnk";
549
int len = lstrlenW( folder ) + lstrlenW( lnkW );
550
WIN32_FIND_DATAW data;
551
HANDLE handle;
552
WCHAR *glob;
553
554
if (!(glob = malloc( (len + 1) * sizeof(WCHAR) ))) return;
555
lstrcpyW( glob, folder );
556
lstrcatW( glob, lnkW );
557
558
if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
559
{
560
do { add_launcher( folder, data.cFileName, -1 ); } while (FindNextFileW( handle, &data ));
561
FindClose( handle );
562
}
563
free( glob );
564
}
565
566
#define BORDER_SIZE 4
567
#define PADDING_SIZE 4
568
#define TITLE_CHARS 14
569
570
static void initialize_launchers( HWND hwnd )
571
{
572
HRESULT hr, init;
573
TEXTMETRICW tm;
574
int icon_size;
575
576
if (!(get_icon_text_metrics( hwnd, &tm ))) return;
577
578
icon_cx = GetSystemMetrics( SM_CXICON );
579
icon_cy = GetSystemMetrics( SM_CYICON );
580
icon_size = max( icon_cx, icon_cy );
581
title_cy = tm.tmHeight * 2;
582
title_cx = max( tm.tmAveCharWidth * TITLE_CHARS, icon_size + PADDING_SIZE + title_cy );
583
launcher_size = BORDER_SIZE + title_cx + BORDER_SIZE;
584
icon_offset_cx = (launcher_size - icon_cx) / 2;
585
icon_offset_cy = BORDER_SIZE + (icon_size - icon_cy) / 2;
586
title_offset_cx = BORDER_SIZE;
587
title_offset_cy = BORDER_SIZE + icon_size + PADDING_SIZE;
588
desktop_width = GetSystemMetrics( SM_CXSCREEN );
589
launchers_per_row = desktop_width / launcher_size;
590
if (!launchers_per_row) launchers_per_row = 1;
591
592
hr = SHGetKnownFolderPath( &FOLDERID_Desktop, KF_FLAG_CREATE, NULL, &desktop_folder );
593
if (FAILED( hr ))
594
{
595
ERR( "Could not get user desktop folder\n" );
596
return;
597
}
598
hr = SHGetKnownFolderPath( &FOLDERID_PublicDesktop, KF_FLAG_CREATE, NULL, &desktop_folder_public );
599
if (FAILED( hr ))
600
{
601
ERR( "Could not get public desktop folder\n" );
602
CoTaskMemFree( desktop_folder );
603
return;
604
}
605
if ((launchers = malloc( 2 * sizeof(launchers[0]) )))
606
{
607
nb_allocated = 2;
608
609
init = CoInitialize( NULL );
610
add_folder( desktop_folder );
611
add_folder( desktop_folder_public );
612
if (SUCCEEDED( init )) CoUninitialize();
613
614
CreateThread( NULL, 0, watch_desktop_folders, hwnd, 0, NULL );
615
}
616
}
617
618
static void wait_named_mutex( const WCHAR *name )
619
{
620
HANDLE mutex;
621
622
mutex = CreateMutexW( NULL, TRUE, name );
623
if (GetLastError() == ERROR_ALREADY_EXISTS)
624
{
625
TRACE( "waiting for mutex %s\n", debugstr_w( name ));
626
WaitForSingleObject( mutex, INFINITE );
627
}
628
}
629
630
/**************************************************************************
631
* wait_clipboard_mutex
632
*
633
* Make sure that there's only one clipboard thread per window station.
634
*/
635
static BOOL wait_clipboard_mutex(void)
636
{
637
static const WCHAR prefix[] = L"__wine_clipboard_";
638
WCHAR buffer[MAX_PATH + ARRAY_SIZE( prefix )];
639
640
memcpy( buffer, prefix, sizeof(prefix) );
641
if (!GetUserObjectInformationW( GetProcessWindowStation(), UOI_NAME,
642
buffer + ARRAY_SIZE( prefix ) - 1,
643
sizeof(buffer) - sizeof(prefix), NULL ))
644
{
645
ERR( "failed to get winstation name\n" );
646
return FALSE;
647
}
648
wait_named_mutex( buffer );
649
return TRUE;
650
}
651
652
653
/**************************************************************************
654
* clipboard_wndproc
655
*
656
* Window procedure for the clipboard manager.
657
*/
658
static LRESULT CALLBACK clipboard_wndproc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
659
{
660
switch (msg)
661
{
662
case WM_NCCREATE:
663
case WM_CLIPBOARDUPDATE:
664
case WM_RENDERFORMAT:
665
case WM_TIMER:
666
case WM_DESTROYCLIPBOARD:
667
case WM_USER:
668
return NtUserMessageCall( hwnd, msg, wp, lp, 0, NtUserClipboardWindowProc, FALSE );
669
}
670
671
return DefWindowProcW( hwnd, msg, wp, lp );
672
}
673
674
675
/**************************************************************************
676
* clipboard_thread
677
*
678
* Thread running inside the desktop process to manage the clipboard
679
*/
680
static DWORD WINAPI clipboard_thread( void *arg )
681
{
682
static const WCHAR clipboard_classname[] = L"__wine_clipboard_manager";
683
WNDCLASSW class;
684
ATOM atom;
685
MSG msg;
686
687
if (!wait_clipboard_mutex()) return 0;
688
689
memset( &class, 0, sizeof(class) );
690
class.lpfnWndProc = clipboard_wndproc;
691
class.lpszClassName = clipboard_classname;
692
693
if (!(atom = RegisterClassW( &class )) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
694
{
695
ERR( "could not register clipboard window class err %lu\n", GetLastError() );
696
return 0;
697
}
698
if (!CreateWindowW( clipboard_classname, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, NULL ))
699
{
700
TRACE( "failed to create clipboard window err %lu\n", GetLastError() );
701
UnregisterClassW( MAKEINTRESOURCEW(atom), NULL );
702
return 0;
703
}
704
705
while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
706
return 0;
707
}
708
709
static HANDLE fullscreen_process;
710
711
static LRESULT WINAPI display_settings_restorer_wndproc( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
712
{
713
TRACE( "got msg %04x wp %Ix lp %Ix\n", message, wp, lp );
714
715
switch(message)
716
{
717
case WM_USER + 0:
718
TRACE( "fullscreen process id %Iu.\n", lp );
719
720
if (fullscreen_process)
721
{
722
CloseHandle( fullscreen_process );
723
fullscreen_process = NULL;
724
}
725
726
if (lp)
727
fullscreen_process = OpenProcess( SYNCHRONIZE, FALSE, lp );
728
729
return 0;
730
}
731
732
return DefWindowProcW( hwnd, message, wp, lp );
733
}
734
735
static DWORD WINAPI display_settings_restorer_thread( void *param )
736
{
737
static const WCHAR *display_settings_restorer_classname = L"__wine_display_settings_restorer";
738
DWORD wait_result;
739
WNDCLASSW class;
740
MSG msg;
741
742
SetThreadDescription( GetCurrentThread(), L"wine_explorer_display_settings_restorer" );
743
744
wait_named_mutex( L"__wine_display_settings_restorer_mutex" );
745
746
memset( &class, 0, sizeof(class) );
747
class.lpfnWndProc = display_settings_restorer_wndproc;
748
class.lpszClassName = display_settings_restorer_classname;
749
750
if (!RegisterClassW( &class ) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
751
{
752
ERR( "could not register display settings restorer window class err %lu\n", GetLastError() );
753
return 0;
754
}
755
if (!CreateWindowW( display_settings_restorer_classname, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, NULL ))
756
{
757
WARN( "failed to create display settings restorer window err %lu\n", GetLastError() );
758
UnregisterClassW( display_settings_restorer_classname, NULL );
759
return 0;
760
}
761
762
for (;;)
763
{
764
if (PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE ))
765
{
766
if (msg.message == WM_QUIT)
767
break;
768
DispatchMessageW( &msg );
769
continue;
770
}
771
772
wait_result = MsgWaitForMultipleObjects( fullscreen_process ? 1 : 0, &fullscreen_process,
773
FALSE, INFINITE, QS_ALLINPUT );
774
if (wait_result == WAIT_FAILED)
775
break;
776
if (!fullscreen_process || wait_result != WAIT_OBJECT_0)
777
continue;
778
779
TRACE( "restoring display settings on process exit\n" );
780
781
ChangeDisplaySettingsExW( NULL, NULL, NULL, 0, NULL );
782
783
CloseHandle( fullscreen_process );
784
fullscreen_process = NULL;
785
}
786
787
return 0;
788
}
789
790
static WNDPROC desktop_orig_wndproc;
791
792
/* window procedure for the desktop window */
793
static LRESULT WINAPI desktop_wnd_proc( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
794
{
795
TRACE( "got msg %04x wp %Ix lp %Ix\n", message, wp, lp );
796
797
switch(message)
798
{
799
case WM_SYSCOMMAND:
800
switch(wp & 0xfff0)
801
{
802
case SC_CLOSE:
803
ExitWindows( 0, 0 );
804
return 0;
805
}
806
break;
807
808
case WM_CLOSE:
809
PostQuitMessage(0);
810
return 0;
811
812
case WM_SETCURSOR:
813
return (LRESULT)SetCursor( LoadCursorA( 0, (LPSTR)IDC_ARROW ) );
814
815
case WM_NCHITTEST:
816
return HTCLIENT;
817
818
case WM_ERASEBKGND:
819
if (!using_root) PaintDesktop( (HDC)wp );
820
return TRUE;
821
822
case WM_SETTINGCHANGE:
823
if (wp == SPI_SETDESKWALLPAPER)
824
SystemParametersInfoW( SPI_SETDESKWALLPAPER, 0, NULL, FALSE );
825
return 0;
826
827
case WM_PARENTNOTIFY:
828
handle_parent_notify( (HWND)lp, wp );
829
return 0;
830
831
case WM_LBUTTONDBLCLK:
832
if (!using_root)
833
{
834
const struct launcher *launcher = launcher_from_point( (short)LOWORD(lp), (short)HIWORD(lp) );
835
if (launcher) ShellExecuteW( NULL, L"open", launcher->path, NULL, NULL, 0 );
836
}
837
return 0;
838
839
case WM_PAINT:
840
{
841
PAINTSTRUCT ps;
842
BeginPaint( hwnd, &ps );
843
if (!using_root)
844
{
845
PaintDesktop( ps.hdc );
846
draw_launchers( ps.hdc, ps.rcPaint );
847
}
848
EndPaint( hwnd, &ps );
849
}
850
return 0;
851
}
852
853
return desktop_orig_wndproc( hwnd, message, wp, lp );
854
}
855
856
/* parse the desktop size specification */
857
static BOOL parse_size( const WCHAR *size, unsigned int *width, unsigned int *height )
858
{
859
WCHAR *end;
860
861
*width = wcstoul( size, &end, 10 );
862
if (end == size) return FALSE;
863
if (*end != 'x') return FALSE;
864
size = end + 1;
865
*height = wcstoul( size, &end, 10 );
866
return !*end;
867
}
868
869
/* retrieve the desktop name to use if not specified on the command line */
870
static const WCHAR *get_default_desktop_name(void)
871
{
872
static WCHAR buffer[MAX_PATH];
873
DWORD size = sizeof(buffer);
874
HDESK desk = GetThreadDesktop( GetCurrentThreadId() );
875
WCHAR *ret = NULL;
876
HKEY hkey;
877
878
if (desk && GetUserObjectInformationW( desk, UOI_NAME, buffer, ARRAY_SIZE( buffer ), NULL ))
879
{
880
if (wcsicmp( buffer, L"Default" )) return buffer;
881
}
882
883
/* @@ Wine registry key: HKCU\Software\Wine\Explorer */
884
if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Explorer", &hkey ))
885
{
886
if (!RegQueryValueExW( hkey, L"Desktop", 0, NULL, (LPBYTE)buffer, &size ) && *buffer) ret = buffer;
887
RegCloseKey( hkey );
888
}
889
return ret;
890
}
891
892
/* retrieve the default desktop size from the registry */
893
static BOOL get_default_desktop_size( const WCHAR *name, unsigned int *width, unsigned int *height )
894
{
895
HKEY hkey;
896
WCHAR buffer[64];
897
DWORD size = sizeof(buffer);
898
BOOL found = FALSE;
899
900
*width = 800;
901
*height = 600;
902
903
/* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
904
if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Explorer\\Desktops", &hkey ))
905
{
906
if (!RegQueryValueExW( hkey, name, 0, NULL, (LPBYTE)buffer, &size ))
907
{
908
found = TRUE;
909
if (!parse_size( buffer, width, height )) *width = *height = 0;
910
}
911
RegCloseKey( hkey );
912
}
913
return found;
914
}
915
916
static BOOL get_default_enable_shell( const WCHAR *name )
917
{
918
HKEY hkey;
919
BOOL found = FALSE;
920
BOOL result;
921
DWORD size = sizeof(result);
922
923
/* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
924
if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Explorer\\Desktops", &hkey ))
925
{
926
if (!RegGetValueW( hkey, name, L"EnableShell", RRF_RT_REG_DWORD, NULL, &result, &size ))
927
found = TRUE;
928
RegCloseKey( hkey );
929
}
930
/* Default off, except for the magic desktop name "shell" */
931
if (!found) result = (lstrcmpiW( name, L"shell" ) == 0);
932
return result;
933
}
934
935
static BOOL get_default_enable_launchers(void)
936
{
937
BOOL result;
938
DWORD size = sizeof(result);
939
940
if (!RegGetValueW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
941
L"NoDesktop", RRF_RT_REG_DWORD, NULL, &result, &size ))
942
return !result;
943
944
if (!RegGetValueW( HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
945
L"NoDesktop", RRF_RT_REG_DWORD, NULL, &result, &size ))
946
return !result;
947
948
return TRUE;
949
}
950
951
static BOOL get_default_show_systray( const WCHAR *name )
952
{
953
HKEY hkey;
954
BOOL found = FALSE;
955
BOOL result;
956
DWORD size = sizeof(result);
957
958
/* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
959
if (name && !RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Explorer\\Desktops", &hkey ))
960
{
961
if (!RegGetValueW( hkey, name, L"ShowSystray", RRF_RT_REG_DWORD, NULL, &result, &size ))
962
found = TRUE;
963
RegCloseKey( hkey );
964
}
965
966
/* Try again with a global Explorer setting */
967
/* @@ Wine registry key: HKCU\Software\Wine\Explorer */
968
if (!found && !RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Explorer", &hkey ))
969
{
970
if (!RegGetValueW( hkey, NULL, L"ShowSystray", RRF_RT_REG_DWORD, NULL, &result, &size ))
971
found = TRUE;
972
RegCloseKey( hkey );
973
}
974
975
/* Default on */
976
if (!found) result = TRUE;
977
return result;
978
}
979
980
static BOOL get_no_tray_items_display(void)
981
{
982
BOOL result;
983
DWORD size = sizeof(result);
984
985
if (!RegGetValueW( HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
986
L"NoTrayItemsDisplay", RRF_RT_REG_DWORD, NULL, &result, &size ))
987
return result;
988
989
if (!RegGetValueW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
990
L"NoTrayItemsDisplay", RRF_RT_REG_DWORD, NULL, &result, &size ))
991
return result;
992
993
return FALSE;
994
}
995
996
static void load_graphics_driver( const WCHAR *driver, GUID *guid )
997
{
998
static const WCHAR device_keyW[] = L"System\\CurrentControlSet\\Control\\Video\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\0000";
999
1000
WCHAR buffer[MAX_PATH], libname[32], *name, *next;
1001
WCHAR key[ARRAY_SIZE( device_keyW ) + 39];
1002
BOOL null_driver = FALSE;
1003
HMODULE module = 0;
1004
HKEY hkey;
1005
char error[80];
1006
1007
if (!driver)
1008
{
1009
lstrcpyW( buffer, default_driver );
1010
1011
/* @@ Wine registry key: HKCU\Software\Wine\Drivers */
1012
if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Drivers", &hkey ))
1013
{
1014
DWORD count = sizeof(buffer);
1015
RegQueryValueExW( hkey, L"Graphics", 0, NULL, (LPBYTE)buffer, &count );
1016
RegCloseKey( hkey );
1017
}
1018
}
1019
else lstrcpynW( buffer, driver, ARRAY_SIZE( buffer ));
1020
1021
name = buffer;
1022
while (name)
1023
{
1024
next = wcschr( name, ',' );
1025
if (next) *next++ = 0;
1026
1027
if (!wcscmp( name, L"null" ))
1028
{
1029
memset( guid, 0, sizeof(*guid) );
1030
TRACE( "display %s using null driver\n", debugstr_guid(guid) );
1031
wcscpy( libname, L"null" );
1032
null_driver = TRUE;
1033
break;
1034
}
1035
1036
swprintf( libname, ARRAY_SIZE( libname ), L"wine%s.drv", name );
1037
if ((module = LoadLibraryW( libname )) != 0) break;
1038
switch (GetLastError())
1039
{
1040
case ERROR_MOD_NOT_FOUND:
1041
strcpy( error, "The graphics driver is missing. Check your build!" );
1042
break;
1043
case ERROR_DLL_INIT_FAILED:
1044
strcpy( error, "Make sure that your display server is running and that its variables are set." );
1045
break;
1046
default:
1047
sprintf( error, "Unknown error (%lu).", GetLastError() );
1048
break;
1049
}
1050
name = next;
1051
}
1052
1053
TRACE( "display %s driver %s\n", debugstr_guid(guid), debugstr_w(libname) );
1054
1055
swprintf( key, ARRAY_SIZE(key), device_keyW, guid->Data1, guid->Data2, guid->Data3,
1056
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
1057
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
1058
1059
if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, key, 0, NULL,
1060
REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL ))
1061
{
1062
if (module || null_driver)
1063
RegSetValueExW( hkey, L"GraphicsDriver", 0, REG_SZ,
1064
(BYTE *)libname, (lstrlenW(libname) + 1) * sizeof(WCHAR) );
1065
else
1066
RegSetValueExA( hkey, "DriverError", 0, REG_SZ, (BYTE *)error, strlen(error) + 1 );
1067
RegCloseKey( hkey );
1068
}
1069
}
1070
1071
static const char *debugstr_devmodew( const DEVMODEW *devmode )
1072
{
1073
char position[32] = {0};
1074
1075
if (devmode->dmFields & DM_POSITION)
1076
{
1077
snprintf( position, sizeof(position), " at (%d,%d)",
1078
(int)devmode->dmPosition.x, (int)devmode->dmPosition.y );
1079
}
1080
1081
return wine_dbg_sprintf( "%ux%u %ubits %uHz rotated %u degrees%s",
1082
(unsigned int)devmode->dmPelsWidth,
1083
(unsigned int)devmode->dmPelsHeight,
1084
(unsigned int)devmode->dmBitsPerPel,
1085
(unsigned int)devmode->dmDisplayFrequency,
1086
(unsigned int)devmode->dmDisplayOrientation * 90,
1087
position );
1088
}
1089
1090
static void initialize_display_settings( unsigned int width, unsigned int height )
1091
{
1092
DISPLAY_DEVICEW device = {.cb = sizeof(DISPLAY_DEVICEW)};
1093
DWORD i = 0, flags = CDS_GLOBAL | CDS_UPDATEREGISTRY;
1094
HANDLE thread;
1095
1096
/* Store current display mode in the registry */
1097
while (EnumDisplayDevicesW( NULL, i++, &device, 0 ))
1098
{
1099
DEVMODEW devmode = {.dmSize = sizeof(DEVMODEW)};
1100
1101
if (!EnumDisplaySettingsExW( device.DeviceName, ENUM_CURRENT_SETTINGS, &devmode, 0))
1102
{
1103
ERR( "Failed to query current display settings for %s.\n", debugstr_w( device.DeviceName ) );
1104
continue;
1105
}
1106
1107
TRACE( "Device %s current display mode %s.\n", debugstr_w( device.DeviceName ), debugstr_devmodew( &devmode ) );
1108
1109
if (ChangeDisplaySettingsExW( device.DeviceName, &devmode, 0, flags | CDS_NORESET, 0 ))
1110
ERR( "Failed to initialize registry display settings for %s.\n", debugstr_w( device.DeviceName ) );
1111
}
1112
1113
if (!using_root)
1114
{
1115
DEVMODEW devmode =
1116
{
1117
.dmSize = sizeof(DEVMODEW),
1118
.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT,
1119
.dmPelsWidth = width,
1120
.dmPelsHeight = height,
1121
};
1122
1123
/* in virtual desktop mode, set the primary display settings to match desktop size */
1124
if (ChangeDisplaySettingsExW( NULL, &devmode, 0, flags, NULL ))
1125
ERR( "Failed to set primary display settings.\n" );
1126
}
1127
1128
thread = CreateThread( NULL, 0, display_settings_restorer_thread, NULL, 0, NULL );
1129
if (thread) CloseHandle( thread );
1130
}
1131
1132
static void set_desktop_window_title( HWND hwnd, const WCHAR *name )
1133
{
1134
static const WCHAR desktop_name_separatorW[] = L" - ";
1135
WCHAR desktop_titleW[64];
1136
WCHAR *window_titleW = NULL;
1137
int window_title_len;
1138
1139
LoadStringW( NULL, IDS_DESKTOP_TITLE, desktop_titleW, ARRAY_SIZE(desktop_titleW) );
1140
1141
if (!name[0] || !wcscmp( name, L"Default" ))
1142
{
1143
SetWindowTextW( hwnd, desktop_titleW );
1144
return;
1145
}
1146
1147
window_title_len = (wcslen(name) + wcslen(desktop_titleW)) * sizeof(WCHAR)
1148
+ sizeof(desktop_name_separatorW);
1149
window_titleW = malloc( window_title_len );
1150
if (!window_titleW)
1151
{
1152
SetWindowTextW( hwnd, desktop_titleW );
1153
return;
1154
}
1155
1156
lstrcpyW( window_titleW, name );
1157
lstrcatW( window_titleW, desktop_name_separatorW );
1158
lstrcatW( window_titleW, desktop_titleW );
1159
1160
SetWindowTextW( hwnd, window_titleW );
1161
free( window_titleW );
1162
}
1163
1164
static inline BOOL is_whitespace(WCHAR c)
1165
{
1166
return c == ' ' || c == '\t';
1167
}
1168
1169
/* Set the shell window if appropriate for the current desktop. We should set
1170
the shell window on the "Default" desktop on a visible window station, but
1171
not for other desktops. */
1172
static void set_shell_window( HWND hwnd )
1173
{
1174
HWINSTA winsta;
1175
USEROBJECTFLAGS flags;
1176
HDESK desk;
1177
WCHAR desk_name[MAX_PATH];
1178
1179
if (!(winsta = GetProcessWindowStation()) ||
1180
!GetUserObjectInformationW( winsta, UOI_FLAGS, &flags, sizeof(flags), NULL ) ||
1181
!(flags.dwFlags & WSF_VISIBLE))
1182
{
1183
return;
1184
}
1185
1186
if (!(desk = GetThreadDesktop( GetCurrentThreadId() )) ||
1187
!GetUserObjectInformationW( desk, UOI_NAME, desk_name, ARRAY_SIZE( desk_name ), NULL ) ||
1188
wcscmp( desk_name, L"Default" ))
1189
{
1190
return;
1191
}
1192
1193
SetShellWindow( hwnd );
1194
}
1195
1196
/* main desktop management function */
1197
void manage_desktop( WCHAR *arg )
1198
{
1199
HDESK desktop = 0;
1200
GUID guid;
1201
MSG msg;
1202
HWND hwnd;
1203
unsigned int width, height;
1204
WCHAR *cmdline = NULL, *driver = NULL;
1205
WCHAR *p = arg;
1206
const WCHAR *name = NULL;
1207
BOOL enable_shell, enable_launchers, show_systray, no_tray_items;
1208
void (WINAPI *pShellDDEInit)( BOOL ) = NULL;
1209
HMODULE shell32;
1210
HANDLE thread;
1211
DWORD id;
1212
NTSTATUS status;
1213
1214
/* get the rest of the command line (if any) */
1215
while (*p && !is_whitespace(*p)) p++;
1216
if (*p)
1217
{
1218
*p++ = 0;
1219
while (*p && is_whitespace(*p)) p++;
1220
if (*p) cmdline = p;
1221
}
1222
1223
/* parse the desktop option */
1224
/* the option is of the form /desktop=name[,widthxheight[,driver]] */
1225
if ((arg[0] == '=' || arg[0] == ',') && arg[1] && arg[1] != ',')
1226
{
1227
arg++;
1228
name = arg;
1229
if ((p = wcschr( arg, ',' )))
1230
{
1231
*p++ = 0;
1232
if ((driver = wcschr( p, ',' ))) *driver++ = 0;
1233
}
1234
if (!p || !parse_size( p, &width, &height ))
1235
get_default_desktop_size( name, &width, &height );
1236
}
1237
else if ((name = get_default_desktop_name()))
1238
{
1239
if (!get_default_desktop_size( name, &width, &height )) width = height = 0;
1240
}
1241
1242
enable_shell = name ? get_default_enable_shell( name ) : FALSE;
1243
enable_launchers = get_default_enable_launchers();
1244
show_systray = get_default_show_systray( name );
1245
no_tray_items = get_no_tray_items_display();
1246
1247
UuidCreate( &guid );
1248
TRACE( "display guid %s\n", debugstr_guid(&guid) );
1249
load_graphics_driver( driver, &guid );
1250
1251
if (name && width && height)
1252
{
1253
DEVMODEW devmode = {.dmPelsWidth = width, .dmPelsHeight = height};
1254
/* magic: desktop "root" means use the root window */
1255
if ((using_root = !wcsicmp( name, L"root" ))) desktop = CreateDesktopW( name, NULL, NULL, DF_WINE_ROOT_DESKTOP, DESKTOP_ALL_ACCESS, NULL );
1256
else desktop = CreateDesktopW( name, NULL, &devmode, DF_WINE_VIRTUAL_DESKTOP, DESKTOP_ALL_ACCESS, NULL );
1257
if (!desktop)
1258
{
1259
ERR( "failed to create desktop %s error %ld\n", debugstr_w(name), GetLastError() );
1260
ExitProcess( 1 );
1261
}
1262
SetThreadDesktop( desktop );
1263
}
1264
1265
/* the desktop process should always have an admin token */
1266
status = NtSetInformationProcess( GetCurrentProcess(), ProcessWineGrantAdminToken, NULL, 0 );
1267
if (status) WARN( "couldn't set admin token for desktop, error %08lx\n", status );
1268
1269
/* create the desktop window */
1270
hwnd = CreateWindowExW( 0, DESKTOP_CLASS_ATOM, NULL,
1271
WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 0, 0, 0, 0, 0, &guid );
1272
1273
if (hwnd)
1274
{
1275
/* create the HWND_MESSAGE parent */
1276
CreateWindowExW( 0, L"Message", NULL, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
1277
0, 0, 100, 100, 0, 0, 0, NULL );
1278
1279
desktop_orig_wndproc = (WNDPROC)SetWindowLongPtrW( hwnd, GWLP_WNDPROC,
1280
(LONG_PTR)desktop_wnd_proc );
1281
SendMessageW( hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW( 0, MAKEINTRESOURCEW(OIC_WINLOGO)));
1282
if (name) set_desktop_window_title( hwnd, name );
1283
SetWindowPos( hwnd, 0, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN),
1284
GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN),
1285
SWP_SHOWWINDOW );
1286
thread = CreateThread( NULL, 0, clipboard_thread, NULL, 0, &id );
1287
if (thread) CloseHandle( thread );
1288
SystemParametersInfoW( SPI_SETDESKWALLPAPER, 0, NULL, FALSE );
1289
ClipCursor( NULL );
1290
initialize_display_settings( width, height );
1291
initialize_appbar();
1292
1293
initialize_systray( using_root, enable_shell, show_systray, no_tray_items );
1294
if (!using_root && enable_launchers) initialize_launchers( hwnd );
1295
1296
if ((shell32 = LoadLibraryW( L"shell32.dll" )) &&
1297
(pShellDDEInit = (void *)GetProcAddress( shell32, (LPCSTR)188)))
1298
{
1299
pShellDDEInit( TRUE );
1300
}
1301
}
1302
1303
/* if we have a command line, execute it */
1304
if (cmdline)
1305
{
1306
STARTUPINFOW si;
1307
PROCESS_INFORMATION pi;
1308
1309
memset( &si, 0, sizeof(si) );
1310
si.cb = sizeof(si);
1311
TRACE( "starting %s\n", debugstr_w(cmdline) );
1312
if (CreateProcessW( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ))
1313
{
1314
CloseHandle( pi.hThread );
1315
CloseHandle( pi.hProcess );
1316
}
1317
}
1318
1319
desktopshellbrowserwindow_init();
1320
shellwindows_init();
1321
1322
/* Ideally we would set the window of an IShellView here, but we never
1323
actually create one, so the desktop window itself will have to do. */
1324
set_shell_window( hwnd );
1325
1326
/* run the desktop message loop */
1327
if (hwnd)
1328
{
1329
TRACE( "desktop message loop starting on hwnd %p\n", hwnd );
1330
while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
1331
TRACE( "desktop message loop exiting for hwnd %p\n", hwnd );
1332
}
1333
1334
if (pShellDDEInit) pShellDDEInit( FALSE );
1335
1336
ExitProcess( 0 );
1337
}
1338
1339
/* IShellWindows implementation */
1340
static HRESULT WINAPI shellwindows_QueryInterface(IShellWindows *iface, REFIID riid, void **ppvObject)
1341
{
1342
struct shellwindows *This = impl_from_IShellWindows(iface);
1343
1344
TRACE("%s %p\n", debugstr_guid(riid), ppvObject);
1345
1346
if (IsEqualGUID(riid, &IID_IShellWindows) ||
1347
IsEqualGUID(riid, &IID_IDispatch) ||
1348
IsEqualGUID(riid, &IID_IUnknown))
1349
{
1350
*ppvObject = &This->IShellWindows_iface;
1351
}
1352
else
1353
{
1354
WARN("Unsupported interface %s\n", debugstr_guid(riid));
1355
*ppvObject = NULL;
1356
}
1357
1358
if (*ppvObject)
1359
{
1360
IUnknown_AddRef((IUnknown*)*ppvObject);
1361
return S_OK;
1362
}
1363
1364
return E_NOINTERFACE;
1365
}
1366
1367
static ULONG WINAPI shellwindows_AddRef(IShellWindows *iface)
1368
{
1369
return 2;
1370
}
1371
1372
static ULONG WINAPI shellwindows_Release(IShellWindows *iface)
1373
{
1374
return 1;
1375
}
1376
1377
static HRESULT WINAPI shellwindows_GetTypeInfoCount(IShellWindows *iface, UINT *pctinfo)
1378
{
1379
TRACE("%p\n", pctinfo);
1380
*pctinfo = 1;
1381
return S_OK;
1382
}
1383
1384
static HRESULT WINAPI shellwindows_GetTypeInfo(IShellWindows *iface,
1385
UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1386
{
1387
TRACE("%d %ld %p\n", iTInfo, lcid, ppTInfo);
1388
return get_typeinfo(IShellWindows_tid, ppTInfo);
1389
}
1390
1391
static HRESULT WINAPI shellwindows_GetIDsOfNames(IShellWindows *iface,
1392
REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
1393
DISPID *rgDispId)
1394
{
1395
ITypeInfo *typeinfo;
1396
HRESULT hr;
1397
1398
TRACE("%s %p %d %ld %p\n", debugstr_guid(riid), rgszNames, cNames,
1399
lcid, rgDispId);
1400
1401
if (!rgszNames || cNames == 0 || !rgDispId)
1402
return E_INVALIDARG;
1403
1404
hr = get_typeinfo(IShellWindows_tid, &typeinfo);
1405
if (SUCCEEDED(hr))
1406
{
1407
hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1408
ITypeInfo_Release(typeinfo);
1409
}
1410
1411
return hr;
1412
}
1413
1414
static HRESULT WINAPI shellwindows_Invoke(IShellWindows *iface,
1415
DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
1416
DISPPARAMS *pDispParams, VARIANT *pVarResult,
1417
EXCEPINFO *pExcepInfo, UINT *puArgErr)
1418
{
1419
ITypeInfo *typeinfo;
1420
HRESULT hr;
1421
1422
TRACE("%ld %s %ld %08x %p %p %p %p\n", dispIdMember, debugstr_guid(riid),
1423
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1424
1425
hr = get_typeinfo(IShellWindows_tid, &typeinfo);
1426
if (SUCCEEDED(hr))
1427
{
1428
hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
1429
pDispParams, pVarResult, pExcepInfo, puArgErr);
1430
ITypeInfo_Release(typeinfo);
1431
}
1432
1433
return hr;
1434
}
1435
1436
static HRESULT WINAPI shellwindows_get_Count(IShellWindows *iface, LONG *count)
1437
{
1438
FIXME("%p\n", count);
1439
return E_NOTIMPL;
1440
}
1441
1442
static HRESULT WINAPI shellwindows_Item(IShellWindows *iface, VARIANT index,
1443
IDispatch **folder)
1444
{
1445
FIXME("%s %p\n", debugstr_variant(&index), folder);
1446
return E_NOTIMPL;
1447
}
1448
1449
static HRESULT WINAPI shellwindows__NewEnum(IShellWindows *iface, IUnknown **ppunk)
1450
{
1451
FIXME("%p\n", ppunk);
1452
return E_NOTIMPL;
1453
}
1454
1455
static HRESULT WINAPI shellwindows_Register(IShellWindows *iface,
1456
IDispatch *disp, LONG hwnd, int class, LONG *cookie)
1457
{
1458
struct shellwindows *sw = impl_from_IShellWindows(iface);
1459
struct window *window;
1460
1461
TRACE("iface %p, disp %p, hwnd %#lx, class %u, cookie %p.\n", iface, disp, hwnd, class, cookie);
1462
1463
if (!hwnd)
1464
return E_POINTER;
1465
1466
if (disp)
1467
FIXME("Ignoring IDispatch %p.\n", disp);
1468
1469
EnterCriticalSection(&sw->cs);
1470
1471
if (!array_reserve((void **)&sw->windows, &sw->max, sw->count + 1, sizeof(*sw->windows)))
1472
{
1473
LeaveCriticalSection(&sw->cs);
1474
return E_OUTOFMEMORY;
1475
}
1476
1477
window = &sw->windows[sw->count++];
1478
window->hwnd = hwnd;
1479
window->class = class;
1480
*cookie = window->cookie = ++cookie_counter;
1481
window->pidl = NULL;
1482
1483
LeaveCriticalSection(&sw->cs);
1484
return S_OK;
1485
}
1486
1487
static HRESULT WINAPI shellwindows_RegisterPending(IShellWindows *iface,
1488
LONG threadid, VARIANT *loc, VARIANT *root, int class, LONG *cookie)
1489
{
1490
FIXME("0x%lx %s %s 0x%x %p\n", threadid, debugstr_variant(loc), debugstr_variant(root),
1491
class, cookie);
1492
return E_NOTIMPL;
1493
}
1494
1495
static HRESULT WINAPI shellwindows_Revoke(IShellWindows *iface, LONG cookie)
1496
{
1497
struct shellwindows *sw = impl_from_IShellWindows(iface);
1498
unsigned int i;
1499
1500
TRACE("iface %p, cookie %lu.\n", iface, cookie);
1501
1502
EnterCriticalSection(&sw->cs);
1503
1504
for (i = 0; i < sw->count; ++i)
1505
{
1506
if (sw->windows[i].cookie == cookie)
1507
{
1508
--sw->count;
1509
memmove(&sw->windows[i], &sw->windows[i + 1], (sw->count - i) * sizeof(*sw->windows));
1510
LeaveCriticalSection(&sw->cs);
1511
return S_OK;
1512
}
1513
}
1514
1515
LeaveCriticalSection(&sw->cs);
1516
return S_FALSE;
1517
}
1518
1519
static HRESULT WINAPI shellwindows_OnNavigate(IShellWindows *iface, LONG cookie, VARIANT *location)
1520
{
1521
struct shellwindows *sw = impl_from_IShellWindows(iface);
1522
unsigned int i;
1523
1524
TRACE("iface %p, cookie %lu, location %s.\n", iface, cookie, debugstr_variant(location));
1525
1526
if (V_VT(location) != (VT_ARRAY | VT_UI1))
1527
{
1528
FIXME("Unexpected variant type %s.\n", debugstr_vt(V_VT(location)));
1529
return E_NOTIMPL;
1530
}
1531
1532
EnterCriticalSection(&sw->cs);
1533
1534
for (i = 0; i < sw->count; ++i)
1535
{
1536
if (sw->windows[i].cookie == cookie)
1537
{
1538
size_t len = V_ARRAY(location)->rgsabound[0].cElements;
1539
if (!(sw->windows[i].pidl = realloc(sw->windows[i].pidl, len)))
1540
{
1541
LeaveCriticalSection(&sw->cs);
1542
return E_OUTOFMEMORY;
1543
}
1544
memcpy(sw->windows[i].pidl, V_ARRAY(location)->pvData, len);
1545
1546
LeaveCriticalSection(&sw->cs);
1547
return S_OK;
1548
}
1549
}
1550
1551
LeaveCriticalSection(&sw->cs);
1552
return E_INVALIDARG;
1553
}
1554
1555
static HRESULT WINAPI shellwindows_OnActivated(IShellWindows *iface, LONG cookie, VARIANT_BOOL active)
1556
{
1557
FIXME("0x%lx 0x%x\n", cookie, active);
1558
return E_NOTIMPL;
1559
}
1560
1561
static HRESULT WINAPI shellwindows_FindWindowSW(IShellWindows *iface, VARIANT *location,
1562
VARIANT *root, int class, LONG *hwnd, int options, IDispatch **disp)
1563
{
1564
struct shellwindows *sw = impl_from_IShellWindows(iface);
1565
unsigned int i;
1566
1567
TRACE("iface %p, location %p, root %p, class %#x, hwnd %p, options %#x, disp %p.\n",
1568
iface, location, root, class, hwnd, options, disp);
1569
1570
if (class == SWC_DESKTOP)
1571
{
1572
*hwnd = (LONG)(LONG_PTR)GetDesktopWindow();
1573
if (options & SWFO_NEEDDISPATCH)
1574
{
1575
*disp = (IDispatch *)&desktopshellbrowserwindow.IWebBrowser2_iface;
1576
IDispatch_AddRef(*disp);
1577
}
1578
return S_OK;
1579
}
1580
1581
if (options)
1582
FIXME("Ignoring options %#x.\n", options);
1583
1584
if (V_VT(location) != (VT_ARRAY | VT_UI1))
1585
{
1586
FIXME("Unexpected variant type %s.\n", debugstr_vt(V_VT(location)));
1587
return E_NOTIMPL;
1588
}
1589
1590
EnterCriticalSection(&sw->cs);
1591
1592
for (i = 0; i < sw->count; ++i)
1593
{
1594
if (sw->windows[i].class == class && ILIsEqual(V_ARRAY(location)->pvData, sw->windows[i].pidl))
1595
{
1596
*hwnd = sw->windows[i].hwnd;
1597
LeaveCriticalSection(&sw->cs);
1598
return S_OK;
1599
}
1600
}
1601
1602
LeaveCriticalSection(&sw->cs);
1603
return S_FALSE;
1604
}
1605
1606
static HRESULT WINAPI shellwindows_OnCreated(IShellWindows *iface, LONG cookie, IUnknown *punk)
1607
{
1608
FIXME("0x%lx %p\n", cookie, punk);
1609
return E_NOTIMPL;
1610
}
1611
1612
static HRESULT WINAPI shellwindows_ProcessAttachDetach(IShellWindows *iface, VARIANT_BOOL attach)
1613
{
1614
FIXME("0x%x\n", attach);
1615
return E_NOTIMPL;
1616
}
1617
1618
static const IShellWindowsVtbl shellwindowsvtbl =
1619
{
1620
shellwindows_QueryInterface,
1621
shellwindows_AddRef,
1622
shellwindows_Release,
1623
shellwindows_GetTypeInfoCount,
1624
shellwindows_GetTypeInfo,
1625
shellwindows_GetIDsOfNames,
1626
shellwindows_Invoke,
1627
shellwindows_get_Count,
1628
shellwindows_Item,
1629
shellwindows__NewEnum,
1630
shellwindows_Register,
1631
shellwindows_RegisterPending,
1632
shellwindows_Revoke,
1633
shellwindows_OnNavigate,
1634
shellwindows_OnActivated,
1635
shellwindows_FindWindowSW,
1636
shellwindows_OnCreated,
1637
shellwindows_ProcessAttachDetach
1638
};
1639
1640
struct shellwindows_classfactory
1641
{
1642
IClassFactory IClassFactory_iface;
1643
DWORD classreg;
1644
};
1645
1646
static inline struct shellwindows_classfactory *impl_from_IClassFactory(IClassFactory *iface)
1647
{
1648
return CONTAINING_RECORD(iface, struct shellwindows_classfactory, IClassFactory_iface);
1649
}
1650
1651
static HRESULT WINAPI swclassfactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppvObject)
1652
{
1653
struct shellwindows_classfactory *This = impl_from_IClassFactory(iface);
1654
1655
TRACE("%s %p\n", debugstr_guid(riid), ppvObject);
1656
1657
if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IClassFactory))
1658
{
1659
*ppvObject = &This->IClassFactory_iface;
1660
}
1661
else
1662
{
1663
WARN("Unsupported interface %s\n", debugstr_guid(riid));
1664
*ppvObject = NULL;
1665
}
1666
1667
if (*ppvObject)
1668
{
1669
IUnknown_AddRef((IUnknown*)*ppvObject);
1670
return S_OK;
1671
}
1672
1673
return E_NOINTERFACE;
1674
}
1675
1676
static ULONG WINAPI swclassfactory_AddRef(IClassFactory *iface)
1677
{
1678
return 2;
1679
}
1680
1681
static ULONG WINAPI swclassfactory_Release(IClassFactory *iface)
1682
{
1683
return 1;
1684
}
1685
1686
static HRESULT WINAPI swclassfactory_CreateInstance(IClassFactory *iface,
1687
IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
1688
{
1689
TRACE("%p %s %p\n", pUnkOuter, debugstr_guid(riid), ppvObject);
1690
return IShellWindows_QueryInterface(&shellwindows.IShellWindows_iface, riid, ppvObject);
1691
}
1692
1693
static HRESULT WINAPI swclassfactory_LockServer(IClassFactory *iface, BOOL lock)
1694
{
1695
TRACE("%u\n", lock);
1696
return E_NOTIMPL;
1697
}
1698
1699
static const IClassFactoryVtbl swclassfactoryvtbl =
1700
{
1701
swclassfactory_QueryInterface,
1702
swclassfactory_AddRef,
1703
swclassfactory_Release,
1704
swclassfactory_CreateInstance,
1705
swclassfactory_LockServer
1706
};
1707
1708
static struct shellwindows_classfactory shellwindows_classfactory = { { &swclassfactoryvtbl } };
1709
1710
static HRESULT WINAPI webbrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid, void **ppv)
1711
{
1712
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1713
1714
*ppv = NULL;
1715
1716
if (IsEqualGUID(&IID_IWebBrowser2, riid) ||
1717
IsEqualGUID(&IID_IWebBrowserApp, riid) ||
1718
IsEqualGUID(&IID_IWebBrowser, riid) ||
1719
IsEqualGUID(&IID_IDispatch, riid) ||
1720
IsEqualGUID(&IID_IUnknown, riid))
1721
{
1722
*ppv = &This->IWebBrowser2_iface;
1723
}
1724
else if (IsEqualGUID(&IID_IServiceProvider, riid))
1725
{
1726
*ppv = &This->IServiceProvider_iface;
1727
}
1728
1729
if (*ppv)
1730
{
1731
IUnknown_AddRef((IUnknown*)*ppv);
1732
return S_OK;
1733
}
1734
1735
FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
1736
return E_NOINTERFACE;
1737
}
1738
1739
static ULONG WINAPI webbrowser_AddRef(IWebBrowser2 *iface)
1740
{
1741
return 2;
1742
}
1743
1744
static ULONG WINAPI webbrowser_Release(IWebBrowser2 *iface)
1745
{
1746
return 1;
1747
}
1748
1749
/* IDispatch methods */
1750
static HRESULT WINAPI webbrowser_GetTypeInfoCount(IWebBrowser2 *iface, UINT *pctinfo)
1751
{
1752
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1753
TRACE("(%p)->(%p)\n", This, pctinfo);
1754
*pctinfo = 1;
1755
return S_OK;
1756
}
1757
1758
static HRESULT WINAPI webbrowser_GetTypeInfo(IWebBrowser2 *iface, UINT iTInfo, LCID lcid,
1759
LPTYPEINFO *ppTInfo)
1760
{
1761
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1762
TRACE("(%p)->(%d %ld %p)\n", This, iTInfo, lcid, ppTInfo);
1763
return get_typeinfo(IWebBrowser2_tid, ppTInfo);
1764
}
1765
1766
static HRESULT WINAPI webbrowser_GetIDsOfNames(IWebBrowser2 *iface, REFIID riid,
1767
LPOLESTR *rgszNames, UINT cNames,
1768
LCID lcid, DISPID *rgDispId)
1769
{
1770
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1771
ITypeInfo *typeinfo;
1772
HRESULT hr;
1773
1774
TRACE("(%p)->(%s %p %d %ld %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1775
lcid, rgDispId);
1776
1777
if(!rgszNames || cNames == 0 || !rgDispId)
1778
return E_INVALIDARG;
1779
1780
hr = get_typeinfo(IWebBrowser2_tid, &typeinfo);
1781
if (SUCCEEDED(hr))
1782
{
1783
hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1784
ITypeInfo_Release(typeinfo);
1785
}
1786
1787
return hr;
1788
}
1789
1790
static HRESULT WINAPI webbrowser_Invoke(IWebBrowser2 *iface, DISPID dispIdMember,
1791
REFIID riid, LCID lcid, WORD wFlags,
1792
DISPPARAMS *pDispParams, VARIANT *pVarResult,
1793
EXCEPINFO *pExcepInfo, UINT *puArgErr)
1794
{
1795
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1796
ITypeInfo *typeinfo;
1797
HRESULT hr;
1798
1799
TRACE("(%p)->(%ld %s %ld %08x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1800
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1801
1802
hr = get_typeinfo(IWebBrowser2_tid, &typeinfo);
1803
if (SUCCEEDED(hr))
1804
{
1805
hr = ITypeInfo_Invoke(typeinfo, &This->IWebBrowser2_iface, dispIdMember, wFlags,
1806
pDispParams, pVarResult, pExcepInfo, puArgErr);
1807
ITypeInfo_Release(typeinfo);
1808
}
1809
1810
return hr;
1811
}
1812
1813
/* IWebBrowser methods */
1814
static HRESULT WINAPI webbrowser_GoBack(IWebBrowser2 *iface)
1815
{
1816
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1817
FIXME("(%p): stub\n", This);
1818
return E_NOTIMPL;
1819
}
1820
1821
static HRESULT WINAPI webbrowser_GoForward(IWebBrowser2 *iface)
1822
{
1823
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1824
FIXME("(%p): stub\n", This);
1825
return E_NOTIMPL;
1826
}
1827
1828
static HRESULT WINAPI webbrowser_GoHome(IWebBrowser2 *iface)
1829
{
1830
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1831
FIXME("(%p): stub\n", This);
1832
return E_NOTIMPL;
1833
}
1834
1835
static HRESULT WINAPI webbrowser_GoSearch(IWebBrowser2 *iface)
1836
{
1837
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1838
FIXME("(%p)\n", This);
1839
return E_NOTIMPL;
1840
}
1841
1842
static HRESULT WINAPI webbrowser_Navigate(IWebBrowser2 *iface, BSTR szUrl,
1843
VARIANT *Flags, VARIANT *TargetFrameName,
1844
VARIANT *PostData, VARIANT *Headers)
1845
{
1846
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1847
FIXME("(%p)->(%s %s %s %s %s): stub\n", This, debugstr_w(szUrl), debugstr_variant(Flags),
1848
debugstr_variant(TargetFrameName), debugstr_variant(PostData),
1849
debugstr_variant(Headers));
1850
return E_NOTIMPL;
1851
}
1852
1853
static HRESULT WINAPI webbrowser_Refresh(IWebBrowser2 *iface)
1854
{
1855
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1856
FIXME("(%p): stub\n", This);
1857
return E_NOTIMPL;
1858
}
1859
1860
static HRESULT WINAPI webbrowser_Refresh2(IWebBrowser2 *iface, VARIANT *Level)
1861
{
1862
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1863
FIXME("(%p)->(%s): stub\n", This, debugstr_variant(Level));
1864
return E_NOTIMPL;
1865
}
1866
1867
static HRESULT WINAPI webbrowser_Stop(IWebBrowser2 *iface)
1868
{
1869
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1870
FIXME("(%p): stub\n", This);
1871
return E_NOTIMPL;
1872
}
1873
1874
static HRESULT WINAPI webbrowser_get_Application(IWebBrowser2 *iface, IDispatch **ppDisp)
1875
{
1876
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1877
1878
TRACE("(%p)->(%p)\n", This, ppDisp);
1879
1880
*ppDisp = (IDispatch*)iface;
1881
IDispatch_AddRef(*ppDisp);
1882
1883
return S_OK;
1884
}
1885
1886
static HRESULT WINAPI webbrowser_get_Parent(IWebBrowser2 *iface, IDispatch **ppDisp)
1887
{
1888
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1889
FIXME("(%p)->(%p)\n", This, ppDisp);
1890
return E_NOTIMPL;
1891
}
1892
1893
static HRESULT WINAPI webbrowser_get_Container(IWebBrowser2 *iface, IDispatch **ppDisp)
1894
{
1895
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1896
FIXME("(%p)->(%p)\n", This, ppDisp);
1897
return E_NOTIMPL;
1898
}
1899
1900
static HRESULT WINAPI webbrowser_get_Document(IWebBrowser2 *iface, IDispatch **ppDisp)
1901
{
1902
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1903
FIXME("(%p)->(%p)\n", This, ppDisp);
1904
return E_NOTIMPL;
1905
}
1906
1907
static HRESULT WINAPI webbrowser_get_TopLevelContainer(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
1908
{
1909
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1910
FIXME("(%p)->(%p)\n", This, pBool);
1911
return E_NOTIMPL;
1912
}
1913
1914
static HRESULT WINAPI webbrowser_get_Type(IWebBrowser2 *iface, BSTR *Type)
1915
{
1916
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1917
FIXME("(%p)->(%p)\n", This, Type);
1918
return E_NOTIMPL;
1919
}
1920
1921
static HRESULT WINAPI webbrowser_get_Left(IWebBrowser2 *iface, LONG *pl)
1922
{
1923
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1924
FIXME("(%p)->(%p)\n", This, pl);
1925
return E_NOTIMPL;
1926
}
1927
1928
static HRESULT WINAPI webbrowser_put_Left(IWebBrowser2 *iface, LONG Left)
1929
{
1930
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1931
FIXME("(%p)->(%ld)\n", This, Left);
1932
return E_NOTIMPL;
1933
}
1934
1935
static HRESULT WINAPI webbrowser_get_Top(IWebBrowser2 *iface, LONG *pl)
1936
{
1937
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1938
FIXME("(%p)->(%p)\n", This, pl);
1939
return E_NOTIMPL;
1940
}
1941
1942
static HRESULT WINAPI webbrowser_put_Top(IWebBrowser2 *iface, LONG Top)
1943
{
1944
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1945
FIXME("(%p)->(%ld)\n", This, Top);
1946
return E_NOTIMPL;
1947
}
1948
1949
static HRESULT WINAPI webbrowser_get_Width(IWebBrowser2 *iface, LONG *pl)
1950
{
1951
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1952
FIXME("(%p)->(%p)\n", This, pl);
1953
return E_NOTIMPL;
1954
}
1955
1956
static HRESULT WINAPI webbrowser_put_Width(IWebBrowser2 *iface, LONG Width)
1957
{
1958
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1959
FIXME("(%p)->(%ld)\n", This, Width);
1960
return E_NOTIMPL;
1961
}
1962
1963
static HRESULT WINAPI webbrowser_get_Height(IWebBrowser2 *iface, LONG *pl)
1964
{
1965
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1966
FIXME("(%p)->(%p)\n", This, pl);
1967
return E_NOTIMPL;
1968
}
1969
1970
static HRESULT WINAPI webbrowser_put_Height(IWebBrowser2 *iface, LONG Height)
1971
{
1972
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1973
FIXME("(%p)->(%ld)\n", This, Height);
1974
return E_NOTIMPL;
1975
}
1976
1977
static HRESULT WINAPI webbrowser_get_LocationName(IWebBrowser2 *iface, BSTR *LocationName)
1978
{
1979
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1980
FIXME("(%p)->(%p)\n", This, LocationName);
1981
return E_NOTIMPL;
1982
}
1983
1984
static HRESULT WINAPI webbrowser_get_LocationURL(IWebBrowser2 *iface, BSTR *LocationURL)
1985
{
1986
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1987
FIXME("(%p)->(%p)\n", This, LocationURL);
1988
return E_NOTIMPL;
1989
}
1990
1991
static HRESULT WINAPI webbrowser_get_Busy(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
1992
{
1993
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1994
FIXME("(%p)->(%p)\n", This, pBool);
1995
return E_NOTIMPL;
1996
}
1997
1998
static HRESULT WINAPI webbrowser_Quit(IWebBrowser2 *iface)
1999
{
2000
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2001
FIXME("(%p)\n", This);
2002
return E_NOTIMPL;
2003
}
2004
2005
static HRESULT WINAPI webbrowser_ClientToWindow(IWebBrowser2 *iface, int *pcx, int *pcy)
2006
{
2007
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2008
FIXME("(%p)->(%p %p)\n", This, pcx, pcy);
2009
return E_NOTIMPL;
2010
}
2011
2012
static HRESULT WINAPI webbrowser_PutProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT vtValue)
2013
{
2014
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2015
FIXME("(%p)->(%s %s)\n", This, debugstr_w(szProperty), debugstr_variant(&vtValue));
2016
return E_NOTIMPL;
2017
}
2018
2019
static HRESULT WINAPI webbrowser_GetProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT *pvtValue)
2020
{
2021
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2022
FIXME("(%p)->(%s %s)\n", This, debugstr_w(szProperty), debugstr_variant(pvtValue));
2023
return E_NOTIMPL;
2024
}
2025
2026
static HRESULT WINAPI webbrowser_get_Name(IWebBrowser2 *iface, BSTR *Name)
2027
{
2028
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2029
FIXME("(%p)->(%p)\n", This, Name);
2030
return E_NOTIMPL;
2031
}
2032
2033
static HRESULT WINAPI webbrowser_get_HWND(IWebBrowser2 *iface, SHANDLE_PTR *pHWND)
2034
{
2035
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2036
FIXME("(%p)->(%p)\n", This, pHWND);
2037
return E_NOTIMPL;
2038
}
2039
2040
static HRESULT WINAPI webbrowser_get_FullName(IWebBrowser2 *iface, BSTR *FullName)
2041
{
2042
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2043
FIXME("(%p)->(%p)\n", This, FullName);
2044
return E_NOTIMPL;
2045
}
2046
2047
static HRESULT WINAPI webbrowser_get_Path(IWebBrowser2 *iface, BSTR *Path)
2048
{
2049
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2050
FIXME("(%p)->(%p)\n", This, Path);
2051
return E_NOTIMPL;
2052
}
2053
2054
static HRESULT WINAPI webbrowser_get_Visible(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
2055
{
2056
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2057
FIXME("(%p)->(%p)\n", This, pBool);
2058
return E_NOTIMPL;
2059
}
2060
2061
static HRESULT WINAPI webbrowser_put_Visible(IWebBrowser2 *iface, VARIANT_BOOL Value)
2062
{
2063
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2064
FIXME("(%p)->(%x)\n", This, Value);
2065
return E_NOTIMPL;
2066
}
2067
2068
static HRESULT WINAPI webbrowser_get_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
2069
{
2070
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2071
FIXME("(%p)->(%p)\n", This, pBool);
2072
return E_NOTIMPL;
2073
}
2074
2075
static HRESULT WINAPI webbrowser_put_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
2076
{
2077
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2078
FIXME("(%p)->(%x)\n", This, Value);
2079
return E_NOTIMPL;
2080
}
2081
2082
static HRESULT WINAPI webbrowser_get_StatusText(IWebBrowser2 *iface, BSTR *StatusText)
2083
{
2084
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2085
FIXME("(%p)->(%p)\n", This, StatusText);
2086
return E_NOTIMPL;
2087
}
2088
2089
static HRESULT WINAPI webbrowser_put_StatusText(IWebBrowser2 *iface, BSTR StatusText)
2090
{
2091
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2092
FIXME("(%p)->(%s)\n", This, debugstr_w(StatusText));
2093
return E_NOTIMPL;
2094
}
2095
2096
static HRESULT WINAPI webbrowser_get_ToolBar(IWebBrowser2 *iface, int *Value)
2097
{
2098
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2099
FIXME("(%p)->(%p)\n", This, Value);
2100
return E_NOTIMPL;
2101
}
2102
2103
static HRESULT WINAPI webbrowser_put_ToolBar(IWebBrowser2 *iface, int Value)
2104
{
2105
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2106
FIXME("(%p)->(%x)\n", This, Value);
2107
return E_NOTIMPL;
2108
}
2109
2110
static HRESULT WINAPI webbrowser_get_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
2111
{
2112
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2113
FIXME("(%p)->(%p)\n", This, Value);
2114
return E_NOTIMPL;
2115
}
2116
2117
static HRESULT WINAPI webbrowser_put_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
2118
{
2119
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2120
FIXME("(%p)->(%x)\n", This, Value);
2121
return E_NOTIMPL;
2122
}
2123
2124
static HRESULT WINAPI webbrowser_get_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL *pbFullScreen)
2125
{
2126
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2127
FIXME("(%p)->(%p)\n", This, pbFullScreen);
2128
return E_NOTIMPL;
2129
}
2130
2131
static HRESULT WINAPI webbrowser_put_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL bFullScreen)
2132
{
2133
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2134
FIXME("(%p)->(%x)\n", This, bFullScreen);
2135
return E_NOTIMPL;
2136
}
2137
2138
static HRESULT WINAPI webbrowser_Navigate2(IWebBrowser2 *iface, VARIANT *URL, VARIANT *Flags,
2139
VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
2140
{
2141
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2142
FIXME("(%p)->(%s %s %s %s %s)\n", This, debugstr_variant(URL), debugstr_variant(Flags),
2143
debugstr_variant(TargetFrameName), debugstr_variant(PostData), debugstr_variant(Headers));
2144
return E_NOTIMPL;
2145
}
2146
2147
static HRESULT WINAPI webbrowser_QueryStatusWB(IWebBrowser2 *iface, OLECMDID cmdID, OLECMDF *pcmdf)
2148
{
2149
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2150
FIXME("(%p)->(%d %p)\n", This, cmdID, pcmdf);
2151
return E_NOTIMPL;
2152
}
2153
2154
static HRESULT WINAPI webbrowser_ExecWB(IWebBrowser2 *iface, OLECMDID cmdID,
2155
OLECMDEXECOPT cmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
2156
{
2157
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2158
FIXME("(%p)->(%d %d %s %p)\n", This, cmdID, cmdexecopt, debugstr_variant(pvaIn), pvaOut);
2159
return E_NOTIMPL;
2160
}
2161
2162
static HRESULT WINAPI webbrowser_ShowBrowserBar(IWebBrowser2 *iface, VARIANT *pvaClsid,
2163
VARIANT *pvarShow, VARIANT *pvarSize)
2164
{
2165
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2166
FIXME("(%p)->(%s %s %s)\n", This, debugstr_variant(pvaClsid), debugstr_variant(pvarShow),
2167
debugstr_variant(pvarSize));
2168
return E_NOTIMPL;
2169
}
2170
2171
static HRESULT WINAPI webbrowser_get_ReadyState(IWebBrowser2 *iface, READYSTATE *lpReadyState)
2172
{
2173
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2174
FIXME("(%p)->(%p)\n", This, lpReadyState);
2175
return E_NOTIMPL;
2176
}
2177
2178
static HRESULT WINAPI webbrowser_get_Offline(IWebBrowser2 *iface, VARIANT_BOOL *pbOffline)
2179
{
2180
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2181
FIXME("(%p)->(%p)\n", This, pbOffline);
2182
return E_NOTIMPL;
2183
}
2184
2185
static HRESULT WINAPI webbrowser_put_Offline(IWebBrowser2 *iface, VARIANT_BOOL bOffline)
2186
{
2187
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2188
FIXME("(%p)->(%x)\n", This, bOffline);
2189
return E_NOTIMPL;
2190
}
2191
2192
static HRESULT WINAPI webbrowser_get_Silent(IWebBrowser2 *iface, VARIANT_BOOL *pbSilent)
2193
{
2194
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2195
FIXME("(%p)->(%p)\n", This, pbSilent);
2196
return E_NOTIMPL;
2197
}
2198
2199
static HRESULT WINAPI webbrowser_put_Silent(IWebBrowser2 *iface, VARIANT_BOOL bSilent)
2200
{
2201
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2202
FIXME("(%p)->(%x)\n", This, bSilent);
2203
return E_NOTIMPL;
2204
}
2205
2206
static HRESULT WINAPI webbrowser_get_RegisterAsBrowser(IWebBrowser2 *iface,
2207
VARIANT_BOOL *pbRegister)
2208
{
2209
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2210
FIXME("(%p)->(%p)\n", This, pbRegister);
2211
return E_NOTIMPL;
2212
}
2213
2214
static HRESULT WINAPI webbrowser_put_RegisterAsBrowser(IWebBrowser2 *iface,
2215
VARIANT_BOOL bRegister)
2216
{
2217
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2218
FIXME("(%p)->(%x)\n", This, bRegister);
2219
return E_NOTIMPL;
2220
}
2221
2222
static HRESULT WINAPI webbrowser_get_RegisterAsDropTarget(IWebBrowser2 *iface,
2223
VARIANT_BOOL *pbRegister)
2224
{
2225
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2226
FIXME("(%p)->(%p)\n", This, pbRegister);
2227
return E_NOTIMPL;
2228
}
2229
2230
static HRESULT WINAPI webbrowser_put_RegisterAsDropTarget(IWebBrowser2 *iface,
2231
VARIANT_BOOL bRegister)
2232
{
2233
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2234
FIXME("(%p)->(%x)\n", This, bRegister);
2235
return E_NOTIMPL;
2236
}
2237
2238
static HRESULT WINAPI webbrowser_get_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL *pbRegister)
2239
{
2240
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2241
FIXME("(%p)->(%p)\n", This, pbRegister);
2242
return E_NOTIMPL;
2243
}
2244
2245
static HRESULT WINAPI webbrowser_put_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL bRegister)
2246
{
2247
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2248
TRACE("(%p)->(%x)\n", This, bRegister);
2249
return E_NOTIMPL;
2250
}
2251
2252
static HRESULT WINAPI webbrowser_get_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
2253
{
2254
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2255
FIXME("(%p)->(%p)\n", This, Value);
2256
return E_NOTIMPL;
2257
}
2258
2259
static HRESULT WINAPI webbrowser_put_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
2260
{
2261
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2262
FIXME("(%p)->(%x)\n", This, Value);
2263
return E_NOTIMPL;
2264
}
2265
2266
static HRESULT WINAPI webbrowser_get_Resizable(IWebBrowser2 *iface, VARIANT_BOOL *Value)
2267
{
2268
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2269
FIXME("(%p)->(%p)\n", This, Value);
2270
return E_NOTIMPL;
2271
}
2272
2273
static HRESULT WINAPI webbrowser_put_Resizable(IWebBrowser2 *iface, VARIANT_BOOL Value)
2274
{
2275
struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
2276
FIXME("(%p)->(%x)\n", This, Value);
2277
return E_NOTIMPL;
2278
}
2279
2280
static const IWebBrowser2Vtbl webbrowser2vtbl =
2281
{
2282
webbrowser_QueryInterface,
2283
webbrowser_AddRef,
2284
webbrowser_Release,
2285
webbrowser_GetTypeInfoCount,
2286
webbrowser_GetTypeInfo,
2287
webbrowser_GetIDsOfNames,
2288
webbrowser_Invoke,
2289
webbrowser_GoBack,
2290
webbrowser_GoForward,
2291
webbrowser_GoHome,
2292
webbrowser_GoSearch,
2293
webbrowser_Navigate,
2294
webbrowser_Refresh,
2295
webbrowser_Refresh2,
2296
webbrowser_Stop,
2297
webbrowser_get_Application,
2298
webbrowser_get_Parent,
2299
webbrowser_get_Container,
2300
webbrowser_get_Document,
2301
webbrowser_get_TopLevelContainer,
2302
webbrowser_get_Type,
2303
webbrowser_get_Left,
2304
webbrowser_put_Left,
2305
webbrowser_get_Top,
2306
webbrowser_put_Top,
2307
webbrowser_get_Width,
2308
webbrowser_put_Width,
2309
webbrowser_get_Height,
2310
webbrowser_put_Height,
2311
webbrowser_get_LocationName,
2312
webbrowser_get_LocationURL,
2313
webbrowser_get_Busy,
2314
webbrowser_Quit,
2315
webbrowser_ClientToWindow,
2316
webbrowser_PutProperty,
2317
webbrowser_GetProperty,
2318
webbrowser_get_Name,
2319
webbrowser_get_HWND,
2320
webbrowser_get_FullName,
2321
webbrowser_get_Path,
2322
webbrowser_get_Visible,
2323
webbrowser_put_Visible,
2324
webbrowser_get_StatusBar,
2325
webbrowser_put_StatusBar,
2326
webbrowser_get_StatusText,
2327
webbrowser_put_StatusText,
2328
webbrowser_get_ToolBar,
2329
webbrowser_put_ToolBar,
2330
webbrowser_get_MenuBar,
2331
webbrowser_put_MenuBar,
2332
webbrowser_get_FullScreen,
2333
webbrowser_put_FullScreen,
2334
webbrowser_Navigate2,
2335
webbrowser_QueryStatusWB,
2336
webbrowser_ExecWB,
2337
webbrowser_ShowBrowserBar,
2338
webbrowser_get_ReadyState,
2339
webbrowser_get_Offline,
2340
webbrowser_put_Offline,
2341
webbrowser_get_Silent,
2342
webbrowser_put_Silent,
2343
webbrowser_get_RegisterAsBrowser,
2344
webbrowser_put_RegisterAsBrowser,
2345
webbrowser_get_RegisterAsDropTarget,
2346
webbrowser_put_RegisterAsDropTarget,
2347
webbrowser_get_TheaterMode,
2348
webbrowser_put_TheaterMode,
2349
webbrowser_get_AddressBar,
2350
webbrowser_put_AddressBar,
2351
webbrowser_get_Resizable,
2352
webbrowser_put_Resizable
2353
};
2354
2355
static HRESULT WINAPI serviceprovider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
2356
{
2357
struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
2358
return IWebBrowser2_QueryInterface(&This->IWebBrowser2_iface, riid, ppv);
2359
}
2360
2361
static ULONG WINAPI serviceprovider_AddRef(IServiceProvider *iface)
2362
{
2363
struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
2364
return IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
2365
}
2366
2367
static ULONG WINAPI serviceprovider_Release(IServiceProvider *iface)
2368
{
2369
struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
2370
return IWebBrowser2_Release(&This->IWebBrowser2_iface);
2371
}
2372
2373
static HRESULT WINAPI serviceprovider_QueryService(IServiceProvider *iface, REFGUID service,
2374
REFIID riid, void **ppv)
2375
{
2376
struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
2377
2378
TRACE("%s %s %p\n", debugstr_guid(service), debugstr_guid(riid), ppv);
2379
2380
if (IsEqualGUID(service, &SID_STopLevelBrowser))
2381
return IShellBrowser_QueryInterface(&This->IShellBrowser_iface, riid, ppv);
2382
2383
WARN("unknown service id %s\n", debugstr_guid(service));
2384
return E_NOTIMPL;
2385
}
2386
2387
static const IServiceProviderVtbl serviceprovidervtbl =
2388
{
2389
serviceprovider_QueryInterface,
2390
serviceprovider_AddRef,
2391
serviceprovider_Release,
2392
serviceprovider_QueryService
2393
};
2394
2395
/* IShellBrowser */
2396
static HRESULT WINAPI shellbrowser_QueryInterface(IShellBrowser *iface, REFIID riid, void **ppv)
2397
{
2398
TRACE("%s %p\n", debugstr_guid(riid), ppv);
2399
2400
*ppv = NULL;
2401
2402
if (IsEqualGUID(&IID_IShellBrowser, riid) ||
2403
IsEqualGUID(&IID_IOleWindow, riid) ||
2404
IsEqualGUID(&IID_IUnknown, riid))
2405
{
2406
*ppv = iface;
2407
}
2408
2409
if (*ppv)
2410
{
2411
IUnknown_AddRef((IUnknown*)*ppv);
2412
return S_OK;
2413
}
2414
2415
return E_NOINTERFACE;
2416
}
2417
2418
static ULONG WINAPI shellbrowser_AddRef(IShellBrowser *iface)
2419
{
2420
struct shellbrowserwindow *This = impl_from_IShellBrowser(iface);
2421
return IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
2422
}
2423
2424
static ULONG WINAPI shellbrowser_Release(IShellBrowser *iface)
2425
{
2426
struct shellbrowserwindow *This = impl_from_IShellBrowser(iface);
2427
return IWebBrowser2_Release(&This->IWebBrowser2_iface);
2428
}
2429
2430
static HRESULT WINAPI shellbrowser_GetWindow(IShellBrowser *iface, HWND *phwnd)
2431
{
2432
FIXME("%p\n", phwnd);
2433
return E_NOTIMPL;
2434
}
2435
2436
static HRESULT WINAPI shellbrowser_ContextSensitiveHelp(IShellBrowser *iface, BOOL mode)
2437
{
2438
FIXME("%d\n", mode);
2439
return E_NOTIMPL;
2440
}
2441
2442
static HRESULT WINAPI shellbrowser_InsertMenusSB(IShellBrowser *iface, HMENU hmenuShared,
2443
OLEMENUGROUPWIDTHS *menuwidths)
2444
{
2445
FIXME("%p %p\n", hmenuShared, menuwidths);
2446
return E_NOTIMPL;
2447
}
2448
2449
static HRESULT WINAPI shellbrowser_SetMenuSB(IShellBrowser *iface, HMENU hmenuShared,
2450
HOLEMENU holemenuReserved, HWND hwndActiveObject)
2451
{
2452
FIXME("%p %p %p\n", hmenuShared, holemenuReserved, hwndActiveObject);
2453
return E_NOTIMPL;
2454
}
2455
2456
static HRESULT WINAPI shellbrowser_RemoveMenusSB(IShellBrowser *iface, HMENU hmenuShared)
2457
{
2458
FIXME("%p\n", hmenuShared);
2459
return E_NOTIMPL;
2460
}
2461
2462
static HRESULT WINAPI shellbrowser_SetStatusTextSB(IShellBrowser *iface, LPCOLESTR text)
2463
{
2464
FIXME("%s\n", debugstr_w(text));
2465
return E_NOTIMPL;
2466
}
2467
2468
static HRESULT WINAPI shellbrowser_EnableModelessSB(IShellBrowser *iface, BOOL enable)
2469
{
2470
FIXME("%d\n", enable);
2471
return E_NOTIMPL;
2472
}
2473
2474
static HRESULT WINAPI shellbrowser_TranslateAcceleratorSB(IShellBrowser *iface, MSG *pmsg, WORD wID)
2475
{
2476
FIXME("%p 0x%x\n", pmsg, wID);
2477
return E_NOTIMPL;
2478
}
2479
2480
static HRESULT WINAPI shellbrowser_BrowseObject(IShellBrowser *iface, LPCITEMIDLIST pidl, UINT flags)
2481
{
2482
FIXME("%p %x\n", pidl, flags);
2483
return E_NOTIMPL;
2484
}
2485
2486
static HRESULT WINAPI shellbrowser_GetViewStateStream(IShellBrowser *iface, DWORD mode, IStream **stream)
2487
{
2488
FIXME("0x%lx %p\n", mode, stream);
2489
return E_NOTIMPL;
2490
}
2491
2492
static HRESULT WINAPI shellbrowser_GetControlWindow(IShellBrowser *iface, UINT id, HWND *phwnd)
2493
{
2494
FIXME("%d %p\n", id, phwnd);
2495
return E_NOTIMPL;
2496
}
2497
2498
static HRESULT WINAPI shellbrowser_SendControlMsg(IShellBrowser *iface, UINT id, UINT uMsg,
2499
WPARAM wParam, LPARAM lParam, LRESULT *pret)
2500
{
2501
FIXME("%d %d %Ix %Ix %p\n", id, uMsg, wParam, lParam, pret);
2502
return E_NOTIMPL;
2503
}
2504
2505
static HRESULT WINAPI shellbrowser_QueryActiveShellView(IShellBrowser *iface, IShellView **view)
2506
{
2507
TRACE("%p\n", view);
2508
2509
*view = desktopshellbrowserwindow.view;
2510
IShellView_AddRef(*view);
2511
return S_OK;
2512
}
2513
2514
static HRESULT WINAPI shellbrowser_OnViewWindowActive(IShellBrowser *iface, IShellView *view)
2515
{
2516
FIXME("%p\n", view);
2517
return E_NOTIMPL;
2518
}
2519
2520
static HRESULT WINAPI shellbrowser_SetToolbarItems(IShellBrowser *iface, LPTBBUTTONSB buttons,
2521
UINT count, UINT flags)
2522
{
2523
FIXME("%p %d 0x%x\n", buttons, count, flags);
2524
return E_NOTIMPL;
2525
}
2526
2527
static const IShellBrowserVtbl shellbrowservtbl = {
2528
shellbrowser_QueryInterface,
2529
shellbrowser_AddRef,
2530
shellbrowser_Release,
2531
shellbrowser_GetWindow,
2532
shellbrowser_ContextSensitiveHelp,
2533
shellbrowser_InsertMenusSB,
2534
shellbrowser_SetMenuSB,
2535
shellbrowser_RemoveMenusSB,
2536
shellbrowser_SetStatusTextSB,
2537
shellbrowser_EnableModelessSB,
2538
shellbrowser_TranslateAcceleratorSB,
2539
shellbrowser_BrowseObject,
2540
shellbrowser_GetViewStateStream,
2541
shellbrowser_GetControlWindow,
2542
shellbrowser_SendControlMsg,
2543
shellbrowser_QueryActiveShellView,
2544
shellbrowser_OnViewWindowActive,
2545
shellbrowser_SetToolbarItems
2546
};
2547
2548
static void desktopshellbrowserwindow_init(void)
2549
{
2550
IShellFolder *folder;
2551
2552
desktopshellbrowserwindow.IWebBrowser2_iface.lpVtbl = &webbrowser2vtbl;
2553
desktopshellbrowserwindow.IServiceProvider_iface.lpVtbl = &serviceprovidervtbl;
2554
desktopshellbrowserwindow.IShellBrowser_iface.lpVtbl = &shellbrowservtbl;
2555
2556
if (FAILED(SHGetDesktopFolder(&folder)))
2557
return;
2558
2559
IShellFolder_CreateViewObject(folder, NULL, &IID_IShellView, (void**)&desktopshellbrowserwindow.view);
2560
}
2561
2562
static void shellwindows_init(void)
2563
{
2564
HRESULT hr;
2565
2566
CoInitialize(NULL);
2567
2568
shellwindows.IShellWindows_iface.lpVtbl = &shellwindowsvtbl;
2569
InitializeCriticalSectionEx(&shellwindows.cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
2570
shellwindows.cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": shellwindows.cs");
2571
2572
hr = CoRegisterClassObject(&CLSID_ShellWindows,
2573
(IUnknown*)&shellwindows_classfactory.IClassFactory_iface,
2574
CLSCTX_LOCAL_SERVER,
2575
REGCLS_MULTIPLEUSE,
2576
&shellwindows_classfactory.classreg);
2577
2578
if (FAILED(hr))
2579
WARN("Failed to register ShellWindows object: %08lx\n", hr);
2580
}
2581
2582