d3dx9: Use a staging texture to update unmappable surfaces in D3DXLoadSurfaceFromMemo...
[wine.git] / programs / explorer / desktop.c
blobd802bc34656b3565e57fdc62171a9fdf4f566139
1 /*
2 * Explorer desktop support
4 * Copyright 2006 Alexandre Julliard
5 * Copyright 2013 Hans Leidekker for CodeWeavers
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.
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.
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
22 #include "config.h"
23 #include "wine/port.h"
24 #include <stdio.h>
26 #define COBJMACROS
27 #define OEMRESOURCE
28 #include <windows.h>
29 #include <rpc.h>
30 #include <shlobj.h>
31 #include <shellapi.h>
32 #include "exdisp.h"
34 #include "wine/unicode.h"
35 #include "wine/debug.h"
36 #include "explorer_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(explorer);
40 #define DESKTOP_CLASS_ATOM ((LPCWSTR)MAKEINTATOM(32769))
41 #define DESKTOP_ALL_ACCESS 0x01ff
43 #ifdef __APPLE__
44 static const WCHAR default_driver[] = {'m','a','c',',','x','1','1',0};
45 #else
46 static const WCHAR default_driver[] = {'x','1','1',0};
47 #endif
49 static BOOL using_root;
51 struct launcher
53 WCHAR *path;
54 HICON icon;
55 WCHAR *title;
58 static WCHAR *desktop_folder;
59 static WCHAR *desktop_folder_public;
61 static int icon_cx, icon_cy, icon_offset_cx, icon_offset_cy;
62 static int title_cx, title_cy, title_offset_cx, title_offset_cy;
63 static int desktop_width, launcher_size, launchers_per_row;
65 static struct launcher **launchers;
66 static unsigned int nb_launchers, nb_allocated;
68 static REFIID tid_ids[] =
70 &IID_IShellWindows,
71 &IID_IWebBrowser2
74 typedef enum
76 IShellWindows_tid,
77 IWebBrowser2_tid,
78 LAST_tid
79 } tid_t;
81 static ITypeLib *typelib;
82 static ITypeInfo *typeinfos[LAST_tid];
84 static HRESULT load_typelib(void)
86 HRESULT hres;
87 ITypeLib *tl;
89 hres = LoadRegTypeLib(&LIBID_SHDocVw, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
90 if (FAILED(hres))
92 ERR("LoadRegTypeLib failed: %08x\n", hres);
93 return hres;
96 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
97 ITypeLib_Release(tl);
98 return hres;
101 static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
103 HRESULT hres;
105 if (!typelib)
106 hres = load_typelib();
107 if (!typelib)
108 return hres;
110 if (!typeinfos[tid]) {
111 ITypeInfo *ti;
113 hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
114 if (FAILED(hres)) {
115 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
116 return hres;
119 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
120 ITypeInfo_Release(ti);
123 *typeinfo = typeinfos[tid];
124 ITypeInfo_AddRef(*typeinfo);
125 return S_OK;
128 struct shellwindows
130 IShellWindows IShellWindows_iface;
133 /* This is not limited to desktop itself, every file browser window that
134 explorer creates supports that. Desktop instance is special in some
135 aspects, for example navigation is not possible, you can't show/hide it,
136 or bring up a menu. CLSID_ShellBrowserWindow class could be used to
137 create instances like that, and they should be registered with
138 IShellWindows as well. */
139 struct shellbrowserwindow
141 IWebBrowser2 IWebBrowser2_iface;
142 IServiceProvider IServiceProvider_iface;
143 IShellBrowser IShellBrowser_iface;
144 IShellView *view;
147 static struct shellwindows shellwindows;
148 static struct shellbrowserwindow desktopshellbrowserwindow;
150 static inline struct shellwindows *impl_from_IShellWindows(IShellWindows *iface)
152 return CONTAINING_RECORD(iface, struct shellwindows, IShellWindows_iface);
155 static inline struct shellbrowserwindow *impl_from_IWebBrowser2(IWebBrowser2 *iface)
157 return CONTAINING_RECORD(iface, struct shellbrowserwindow, IWebBrowser2_iface);
160 static inline struct shellbrowserwindow *impl_from_IServiceProvider(IServiceProvider *iface)
162 return CONTAINING_RECORD(iface, struct shellbrowserwindow, IServiceProvider_iface);
165 static inline struct shellbrowserwindow *impl_from_IShellBrowser(IShellBrowser *iface)
167 return CONTAINING_RECORD(iface, struct shellbrowserwindow, IShellBrowser_iface);
170 static void shellwindows_init(void);
171 static void desktopshellbrowserwindow_init(void);
173 static RECT get_icon_rect( unsigned int index )
175 RECT rect;
176 unsigned int row = index / launchers_per_row;
177 unsigned int col = index % launchers_per_row;
179 rect.left = col * launcher_size + icon_offset_cx;
180 rect.right = rect.left + icon_cx;
181 rect.top = row * launcher_size + icon_offset_cy;
182 rect.bottom = rect.top + icon_cy;
183 return rect;
186 static RECT get_title_rect( unsigned int index )
188 RECT rect;
189 unsigned int row = index / launchers_per_row;
190 unsigned int col = index % launchers_per_row;
192 rect.left = col * launcher_size + title_offset_cx;
193 rect.right = rect.left + title_cx;
194 rect.top = row * launcher_size + title_offset_cy;
195 rect.bottom = rect.top + title_cy;
196 return rect;
199 static const struct launcher *launcher_from_point( int x, int y )
201 RECT icon, title;
202 unsigned int index;
204 if (!nb_launchers) return NULL;
205 index = x / launcher_size + (y / launcher_size) * launchers_per_row;
206 if (index >= nb_launchers) return NULL;
208 icon = get_icon_rect( index );
209 title = get_title_rect( index );
210 if ((x < icon.left || x > icon.right || y < icon.top || y > icon.bottom) &&
211 (x < title.left || x > title.right || y < title.top || y > title.bottom)) return NULL;
212 return launchers[index];
215 static void draw_launchers( HDC hdc, RECT update_rect )
217 COLORREF color = SetTextColor( hdc, RGB(255,255,255) ); /* FIXME: depends on background color */
218 int mode = SetBkMode( hdc, TRANSPARENT );
219 unsigned int i;
220 LOGFONTW lf;
221 HFONT font;
223 SystemParametersInfoW( SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0 );
224 font = SelectObject( hdc, CreateFontIndirectW( &lf ) );
226 for (i = 0; i < nb_launchers; i++)
228 RECT dummy, icon = get_icon_rect( i ), title = get_title_rect( i );
230 if (IntersectRect( &dummy, &icon, &update_rect ))
231 DrawIconEx( hdc, icon.left, icon.top, launchers[i]->icon, icon_cx, icon_cy,
232 0, 0, DI_DEFAULTSIZE|DI_NORMAL );
234 if (IntersectRect( &dummy, &title, &update_rect ))
235 DrawTextW( hdc, launchers[i]->title, -1, &title,
236 DT_CENTER|DT_WORDBREAK|DT_EDITCONTROL|DT_END_ELLIPSIS );
239 SelectObject( hdc, font );
240 SetTextColor( hdc, color );
241 SetBkMode( hdc, mode );
244 static void do_launch( const struct launcher *launcher )
246 static const WCHAR openW[] = {'o','p','e','n',0};
247 ShellExecuteW( NULL, openW, launcher->path, NULL, NULL, 0 );
250 static WCHAR *append_path( const WCHAR *path, const WCHAR *filename, int len_filename )
252 int len_path = strlenW( path );
253 WCHAR *ret;
255 if (len_filename == -1) len_filename = strlenW( filename );
256 if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len_path + len_filename + 2) * sizeof(WCHAR) )))
257 return NULL;
258 memcpy( ret, path, len_path * sizeof(WCHAR) );
259 ret[len_path] = '\\';
260 memcpy( ret + len_path + 1, filename, len_filename * sizeof(WCHAR) );
261 ret[len_path + 1 + len_filename] = 0;
262 return ret;
265 static IShellLinkW *load_shelllink( const WCHAR *path )
267 HRESULT hr;
268 IShellLinkW *link;
269 IPersistFile *file;
271 hr = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW,
272 (void **)&link );
273 if (FAILED( hr )) return NULL;
275 hr = IShellLinkW_QueryInterface( link, &IID_IPersistFile, (void **)&file );
276 if (FAILED( hr ))
278 IShellLinkW_Release( link );
279 return NULL;
281 hr = IPersistFile_Load( file, path, 0 );
282 IPersistFile_Release( file );
283 if (FAILED( hr ))
285 IShellLinkW_Release( link );
286 return NULL;
288 return link;
291 static HICON extract_icon( IShellLinkW *link )
293 WCHAR tmp_path[MAX_PATH], icon_path[MAX_PATH], target_path[MAX_PATH];
294 HICON icon = NULL;
295 int index;
297 tmp_path[0] = 0;
298 IShellLinkW_GetIconLocation( link, tmp_path, MAX_PATH, &index );
299 ExpandEnvironmentStringsW( tmp_path, icon_path, MAX_PATH );
301 if (icon_path[0]) ExtractIconExW( icon_path, index, &icon, NULL, 1 );
302 if (!icon)
304 tmp_path[0] = 0;
305 IShellLinkW_GetPath( link, tmp_path, MAX_PATH, NULL, SLGP_RAWPATH );
306 ExpandEnvironmentStringsW( tmp_path, target_path, MAX_PATH );
307 ExtractIconExW( target_path, index, &icon, NULL, 1 );
309 return icon;
312 static WCHAR *build_title( const WCHAR *filename, int len )
314 const WCHAR *p;
315 WCHAR *ret;
317 if (len == -1) len = strlenW( filename );
318 for (p = filename + len - 1; p >= filename; p--)
320 if (*p == '.')
322 len = p - filename;
323 break;
326 if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return NULL;
327 memcpy( ret, filename, len * sizeof(WCHAR) );
328 ret[len] = 0;
329 return ret;
332 static BOOL add_launcher( const WCHAR *folder, const WCHAR *filename, int len_filename )
334 struct launcher *launcher;
335 IShellLinkW *link;
337 if (nb_launchers == nb_allocated)
339 unsigned int count = nb_allocated * 2;
340 struct launcher **tmp = HeapReAlloc( GetProcessHeap(), 0, launchers, count * sizeof(*tmp) );
341 if (!tmp) return FALSE;
342 launchers = tmp;
343 nb_allocated = count;
346 if (!(launcher = HeapAlloc( GetProcessHeap(), 0, sizeof(*launcher) ))) return FALSE;
347 if (!(launcher->path = append_path( folder, filename, len_filename ))) goto error;
348 if (!(link = load_shelllink( launcher->path ))) goto error;
350 launcher->icon = extract_icon( link );
351 launcher->title = build_title( filename, len_filename );
352 IShellLinkW_Release( link );
353 if (launcher->icon && launcher->title)
355 launchers[nb_launchers++] = launcher;
356 return TRUE;
358 HeapFree( GetProcessHeap(), 0, launcher->title );
359 DestroyIcon( launcher->icon );
361 error:
362 HeapFree( GetProcessHeap(), 0, launcher->path );
363 HeapFree( GetProcessHeap(), 0, launcher );
364 return FALSE;
367 static void free_launcher( struct launcher *launcher )
369 DestroyIcon( launcher->icon );
370 HeapFree( GetProcessHeap(), 0, launcher->path );
371 HeapFree( GetProcessHeap(), 0, launcher->title );
372 HeapFree( GetProcessHeap(), 0, launcher );
375 static BOOL remove_launcher( const WCHAR *folder, const WCHAR *filename, int len_filename )
377 UINT i;
378 WCHAR *path;
379 BOOL ret = FALSE;
381 if (!(path = append_path( folder, filename, len_filename ))) return FALSE;
382 for (i = 0; i < nb_launchers; i++)
384 if (!strcmpiW( launchers[i]->path, path ))
386 free_launcher( launchers[i] );
387 if (--nb_launchers)
388 memmove( &launchers[i], &launchers[i + 1], sizeof(launchers[i]) * (nb_launchers - i) );
389 ret = TRUE;
390 break;
393 HeapFree( GetProcessHeap(), 0, path );
394 return ret;
397 static BOOL get_icon_text_metrics( HWND hwnd, TEXTMETRICW *tm )
399 BOOL ret;
400 HDC hdc;
401 LOGFONTW lf;
402 HFONT hfont;
404 hdc = GetDC( hwnd );
405 SystemParametersInfoW( SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0 );
406 hfont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
407 ret = GetTextMetricsW( hdc, tm );
408 SelectObject( hdc, hfont );
409 ReleaseDC( hwnd, hdc );
410 return ret;
413 static BOOL process_changes( const WCHAR *folder, char *buf )
415 FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION *)buf;
416 BOOL ret = FALSE;
418 for (;;)
420 switch (info->Action)
422 case FILE_ACTION_ADDED:
423 case FILE_ACTION_RENAMED_NEW_NAME:
424 if (add_launcher( folder, info->FileName, info->FileNameLength / sizeof(WCHAR) ))
425 ret = TRUE;
426 break;
428 case FILE_ACTION_REMOVED:
429 case FILE_ACTION_RENAMED_OLD_NAME:
430 if (remove_launcher( folder, info->FileName, info->FileNameLength / sizeof(WCHAR) ))
431 ret = TRUE;
432 break;
434 default:
435 WARN( "unexpected action %u\n", info->Action );
436 break;
438 if (!info->NextEntryOffset) break;
439 info = (FILE_NOTIFY_INFORMATION *)((char *)info + info->NextEntryOffset);
441 return ret;
444 static DWORD CALLBACK watch_desktop_folders( LPVOID param )
446 HWND hwnd = param;
447 HRESULT init = CoInitialize( NULL );
448 HANDLE dir0, dir1, events[2];
449 OVERLAPPED ovl0, ovl1;
450 char *buf0 = NULL, *buf1 = NULL;
451 DWORD count, size = 4096, error = ERROR_OUTOFMEMORY;
452 BOOL ret, redraw;
454 dir0 = CreateFileW( desktop_folder, FILE_LIST_DIRECTORY|SYNCHRONIZE, FILE_SHARE_READ|FILE_SHARE_WRITE,
455 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL );
456 if (dir0 == INVALID_HANDLE_VALUE) return GetLastError();
457 dir1 = CreateFileW( desktop_folder_public, FILE_LIST_DIRECTORY|SYNCHRONIZE, FILE_SHARE_READ|FILE_SHARE_WRITE,
458 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL );
459 if (dir1 == INVALID_HANDLE_VALUE)
461 CloseHandle( dir0 );
462 return GetLastError();
464 if (!(ovl0.hEvent = events[0] = CreateEventW( NULL, FALSE, FALSE, NULL ))) goto error;
465 if (!(ovl1.hEvent = events[1] = CreateEventW( NULL, FALSE, FALSE, NULL ))) goto error;
466 if (!(buf0 = HeapAlloc( GetProcessHeap(), 0, size ))) goto error;
467 if (!(buf1 = HeapAlloc( GetProcessHeap(), 0, size ))) goto error;
469 for (;;)
471 ret = ReadDirectoryChangesW( dir0, buf0, size, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ovl0, NULL );
472 if (!ret)
474 error = GetLastError();
475 goto error;
477 ret = ReadDirectoryChangesW( dir1, buf1, size, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ovl1, NULL );
478 if (!ret)
480 error = GetLastError();
481 goto error;
484 redraw = FALSE;
485 switch ((error = WaitForMultipleObjects( 2, events, FALSE, INFINITE )))
487 case WAIT_OBJECT_0:
488 if (!GetOverlappedResult( dir0, &ovl0, &count, FALSE ) || !count) break;
489 if (process_changes( desktop_folder, buf0 )) redraw = TRUE;
490 break;
492 case WAIT_OBJECT_0 + 1:
493 if (!GetOverlappedResult( dir1, &ovl1, &count, FALSE ) || !count) break;
494 if (process_changes( desktop_folder_public, buf1 )) redraw = TRUE;
495 break;
497 default:
498 goto error;
500 if (redraw) InvalidateRect( hwnd, NULL, TRUE );
503 error:
504 CloseHandle( dir0 );
505 CloseHandle( dir1 );
506 CloseHandle( events[0] );
507 CloseHandle( events[1] );
508 HeapFree( GetProcessHeap(), 0, buf0 );
509 HeapFree( GetProcessHeap(), 0, buf1 );
510 if (SUCCEEDED( init )) CoUninitialize();
511 return error;
514 static void add_folder( const WCHAR *folder )
516 static const WCHAR lnkW[] = {'\\','*','.','l','n','k',0};
517 int len = strlenW( folder ) + strlenW( lnkW );
518 WIN32_FIND_DATAW data;
519 HANDLE handle;
520 WCHAR *glob;
522 if (!(glob = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return;
523 strcpyW( glob, folder );
524 strcatW( glob, lnkW );
526 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
528 do { add_launcher( folder, data.cFileName, -1 ); } while (FindNextFileW( handle, &data ));
529 FindClose( handle );
531 HeapFree( GetProcessHeap(), 0, glob );
534 #define BORDER_SIZE 4
535 #define PADDING_SIZE 4
536 #define TITLE_CHARS 14
538 static void initialize_launchers( HWND hwnd )
540 HRESULT hr, init;
541 TEXTMETRICW tm;
542 int icon_size;
544 if (!(get_icon_text_metrics( hwnd, &tm ))) return;
546 icon_cx = GetSystemMetrics( SM_CXICON );
547 icon_cy = GetSystemMetrics( SM_CYICON );
548 icon_size = max( icon_cx, icon_cy );
549 title_cy = tm.tmHeight * 2;
550 title_cx = max( tm.tmAveCharWidth * TITLE_CHARS, icon_size + PADDING_SIZE + title_cy );
551 launcher_size = BORDER_SIZE + title_cx + BORDER_SIZE;
552 icon_offset_cx = (launcher_size - icon_cx) / 2;
553 icon_offset_cy = BORDER_SIZE + (icon_size - icon_cy) / 2;
554 title_offset_cx = BORDER_SIZE;
555 title_offset_cy = BORDER_SIZE + icon_size + PADDING_SIZE;
556 desktop_width = GetSystemMetrics( SM_CXSCREEN );
557 launchers_per_row = desktop_width / launcher_size;
558 if (!launchers_per_row) launchers_per_row = 1;
560 hr = SHGetKnownFolderPath( &FOLDERID_Desktop, KF_FLAG_CREATE, NULL, &desktop_folder );
561 if (FAILED( hr ))
563 WINE_ERR("Could not get user desktop folder\n");
564 return;
566 hr = SHGetKnownFolderPath( &FOLDERID_PublicDesktop, KF_FLAG_CREATE, NULL, &desktop_folder_public );
567 if (FAILED( hr ))
569 WINE_ERR("Could not get public desktop folder\n");
570 CoTaskMemFree( desktop_folder );
571 return;
573 if ((launchers = HeapAlloc( GetProcessHeap(), 0, 2 * sizeof(launchers[0]) )))
575 nb_allocated = 2;
577 init = CoInitialize( NULL );
578 add_folder( desktop_folder );
579 add_folder( desktop_folder_public );
580 if (SUCCEEDED( init )) CoUninitialize();
582 CreateThread( NULL, 0, watch_desktop_folders, hwnd, 0, NULL );
586 /* screen saver handler */
587 static BOOL start_screensaver( void )
589 if (using_root)
591 const char *argv[3] = { "xdg-screensaver", "activate", NULL };
592 int pid = _spawnvp( _P_DETACH, argv[0], argv );
593 if (pid > 0)
595 WINE_TRACE( "started process %d\n", pid );
596 return TRUE;
599 return FALSE;
602 static WNDPROC desktop_orig_wndproc;
604 /* window procedure for the desktop window */
605 static LRESULT WINAPI desktop_wnd_proc( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
607 WINE_TRACE( "got msg %04x wp %lx lp %lx\n", message, wp, lp );
609 switch(message)
611 case WM_SYSCOMMAND:
612 switch(wp & 0xfff0)
614 case SC_CLOSE:
615 ExitWindows( 0, 0 );
616 break;
617 case SC_SCREENSAVE:
618 return start_screensaver();
620 return 0;
622 case WM_CLOSE:
623 PostQuitMessage(0);
624 return 0;
626 case WM_SETCURSOR:
627 return (LRESULT)SetCursor( LoadCursorA( 0, (LPSTR)IDC_ARROW ) );
629 case WM_NCHITTEST:
630 return HTCLIENT;
632 case WM_ERASEBKGND:
633 if (!using_root) PaintDesktop( (HDC)wp );
634 return TRUE;
636 case WM_SETTINGCHANGE:
637 if (wp == SPI_SETDESKWALLPAPER)
638 SystemParametersInfoW( SPI_SETDESKWALLPAPER, 0, NULL, FALSE );
639 return 0;
641 case WM_PARENTNOTIFY:
642 handle_parent_notify( (HWND)lp, wp );
643 return 0;
645 case WM_LBUTTONDBLCLK:
646 if (!using_root)
648 const struct launcher *launcher = launcher_from_point( (short)LOWORD(lp), (short)HIWORD(lp) );
649 if (launcher) do_launch( launcher );
651 return 0;
653 case WM_PAINT:
655 PAINTSTRUCT ps;
656 BeginPaint( hwnd, &ps );
657 if (!using_root)
659 if (ps.fErase) PaintDesktop( ps.hdc );
660 draw_launchers( ps.hdc, ps.rcPaint );
662 EndPaint( hwnd, &ps );
664 return 0;
667 return desktop_orig_wndproc( hwnd, message, wp, lp );
670 /* create the desktop and the associated driver window, and make it the current desktop */
671 static BOOL create_desktop( HMODULE driver, const WCHAR *name, unsigned int width, unsigned int height )
673 BOOL ret = FALSE;
674 BOOL (CDECL *create_desktop_func)(unsigned int, unsigned int);
676 if (driver)
678 create_desktop_func = (void *)GetProcAddress( driver, "wine_create_desktop" );
679 if (create_desktop_func) ret = create_desktop_func( width, height );
681 return ret;
684 /* parse the desktop size specification */
685 static BOOL parse_size( const WCHAR *size, unsigned int *width, unsigned int *height )
687 WCHAR *end;
689 *width = strtoulW( size, &end, 10 );
690 if (end == size) return FALSE;
691 if (*end != 'x') return FALSE;
692 size = end + 1;
693 *height = strtoulW( size, &end, 10 );
694 return !*end;
697 /* retrieve the desktop name to use if not specified on the command line */
698 static const WCHAR *get_default_desktop_name(void)
700 static const WCHAR desktopW[] = {'D','e','s','k','t','o','p',0};
701 static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',0};
702 static const WCHAR explorer_keyW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
703 'E','x','p','l','o','r','e','r',0};
704 static WCHAR buffer[MAX_PATH];
705 DWORD size = sizeof(buffer);
706 HDESK desk = GetThreadDesktop( GetCurrentThreadId() );
707 WCHAR *ret = NULL;
708 HKEY hkey;
710 if (desk && GetUserObjectInformationW( desk, UOI_NAME, buffer, ARRAY_SIZE( buffer ), NULL ))
712 if (strcmpiW( buffer, defaultW )) return buffer;
715 /* @@ Wine registry key: HKCU\Software\Wine\Explorer */
716 if (!RegOpenKeyW( HKEY_CURRENT_USER, explorer_keyW, &hkey ))
718 if (!RegQueryValueExW( hkey, desktopW, 0, NULL, (LPBYTE)buffer, &size )) ret = buffer;
719 RegCloseKey( hkey );
721 return ret;
724 /* retrieve the default desktop size from the registry */
725 static BOOL get_default_desktop_size( const WCHAR *name, unsigned int *width, unsigned int *height )
727 static const WCHAR desktop_keyW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
728 'E','x','p','l','o','r','e','r','\\',
729 'D','e','s','k','t','o','p','s',0};
730 HKEY hkey;
731 WCHAR buffer[64];
732 DWORD size = sizeof(buffer);
733 BOOL found = FALSE;
735 *width = 800;
736 *height = 600;
738 /* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
739 if (!RegOpenKeyW( HKEY_CURRENT_USER, desktop_keyW, &hkey ))
741 if (!RegQueryValueExW( hkey, name, 0, NULL, (LPBYTE)buffer, &size ))
743 found = TRUE;
744 if (!parse_size( buffer, width, height )) *width = *height = 0;
746 RegCloseKey( hkey );
748 return found;
751 static BOOL get_default_enable_shell( const WCHAR *name )
753 static const WCHAR desktop_keyW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
754 'E','x','p','l','o','r','e','r','\\',
755 'D','e','s','k','t','o','p','s',0};
756 static const WCHAR enable_shellW[] = {'E','n','a','b','l','e','S','h','e','l','l',0};
757 static const WCHAR shellW[] = {'s','h','e','l','l',0};
758 HKEY hkey;
759 BOOL found = FALSE;
760 BOOL result;
761 DWORD size = sizeof(result);
763 /* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
764 if (!RegOpenKeyW( HKEY_CURRENT_USER, desktop_keyW, &hkey ))
766 if (!RegGetValueW( hkey, name, enable_shellW, RRF_RT_REG_DWORD, NULL, &result, &size ))
767 found = TRUE;
768 RegCloseKey( hkey );
770 /* Default off, except for the magic desktop name "shell" */
771 if (!found)
772 result = (lstrcmpiW( name, shellW ) == 0);
773 return result;
776 static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
778 static const WCHAR device_keyW[] = {
779 'S','y','s','t','e','m','\\',
780 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
781 'C','o','n','t','r','o','l','\\',
782 'V','i','d','e','o','\\',
783 '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-',
784 '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x','%','0','2','x',
785 '%','0','2','x','%','0','2','x','%','0','2','x','}','\\','0','0','0','0',0};
786 static const WCHAR graphics_driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
787 static const WCHAR driversW[] = {'S','o','f','t','w','a','r','e','\\',
788 'W','i','n','e','\\','D','r','i','v','e','r','s',0};
789 static const WCHAR graphicsW[] = {'G','r','a','p','h','i','c','s',0};
790 static const WCHAR drv_formatW[] = {'w','i','n','e','%','s','.','d','r','v',0};
792 WCHAR buffer[MAX_PATH], libname[32], *name, *next;
793 WCHAR key[ARRAY_SIZE( device_keyW ) + 39];
794 HMODULE module = 0;
795 HKEY hkey;
796 char error[80];
798 if (!driver)
800 strcpyW( buffer, default_driver );
802 /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
803 if (!RegOpenKeyW( HKEY_CURRENT_USER, driversW, &hkey ))
805 DWORD count = sizeof(buffer);
806 RegQueryValueExW( hkey, graphicsW, 0, NULL, (LPBYTE)buffer, &count );
807 RegCloseKey( hkey );
810 else lstrcpynW( buffer, driver, ARRAY_SIZE( buffer ));
812 name = buffer;
813 while (name)
815 next = strchrW( name, ',' );
816 if (next) *next++ = 0;
818 snprintfW( libname, ARRAY_SIZE( libname ), drv_formatW, name );
819 if ((module = LoadLibraryW( libname )) != 0) break;
820 switch (GetLastError())
822 case ERROR_MOD_NOT_FOUND:
823 strcpy( error, "The graphics driver is missing. Check your build!" );
824 break;
825 case ERROR_DLL_INIT_FAILED:
826 strcpy( error, "Make sure that your X server is running and that $DISPLAY is set correctly." );
827 break;
828 default:
829 sprintf( error, "Unknown error (%u).", GetLastError() );
830 break;
832 name = next;
835 if (module)
837 GetModuleFileNameW( module, buffer, MAX_PATH );
838 TRACE( "display %s driver %s\n", debugstr_guid(guid), debugstr_w(buffer) );
841 sprintfW( key, device_keyW, guid->Data1, guid->Data2, guid->Data3,
842 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
843 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
845 if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, key, 0, NULL,
846 REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL ))
848 if (module)
849 RegSetValueExW( hkey, graphics_driverW, 0, REG_SZ,
850 (BYTE *)buffer, (strlenW(buffer) + 1) * sizeof(WCHAR) );
851 else
852 RegSetValueExA( hkey, "DriverError", 0, REG_SZ, (BYTE *)error, strlen(error) + 1 );
853 RegCloseKey( hkey );
856 return module;
859 static void initialize_display_settings(void)
861 DEVMODEW dmW;
863 /* Store current display mode in the registry */
864 if (EnumDisplaySettingsExW( NULL, ENUM_CURRENT_SETTINGS, &dmW, 0 ))
866 WINE_TRACE( "Current display mode %ux%u %u bpp %u Hz\n", dmW.dmPelsWidth,
867 dmW.dmPelsHeight, dmW.dmBitsPerPel, dmW.dmDisplayFrequency );
868 ChangeDisplaySettingsExW( NULL, &dmW, 0,
869 CDS_GLOBAL | CDS_NORESET | CDS_UPDATEREGISTRY,
870 NULL );
874 static void set_desktop_window_title( HWND hwnd, const WCHAR *name )
876 static const WCHAR desktop_nameW[] = {'W','i','n','e',' ','d','e','s','k','t','o','p',0};
877 static const WCHAR desktop_name_separatorW[] = {' ', '-', ' ', 0};
878 WCHAR *window_titleW = NULL;
879 int window_title_len;
881 if (!name[0])
883 SetWindowTextW( hwnd, desktop_nameW );
884 return;
887 window_title_len = strlenW(name) * sizeof(WCHAR)
888 + sizeof(desktop_name_separatorW)
889 + sizeof(desktop_nameW);
890 window_titleW = HeapAlloc( GetProcessHeap(), 0, window_title_len );
891 if (!window_titleW)
893 SetWindowTextW( hwnd, desktop_nameW );
894 return;
897 strcpyW( window_titleW, name );
898 strcatW( window_titleW, desktop_name_separatorW );
899 strcatW( window_titleW, desktop_nameW );
901 SetWindowTextW( hwnd, window_titleW );
902 HeapFree( GetProcessHeap(), 0, window_titleW );
905 static inline BOOL is_whitespace(WCHAR c)
907 return c == ' ' || c == '\t';
910 /* main desktop management function */
911 void manage_desktop( WCHAR *arg )
913 static const WCHAR messageW[] = {'M','e','s','s','a','g','e',0};
914 HDESK desktop = 0;
915 GUID guid;
916 MSG msg;
917 HWND hwnd;
918 HMODULE graphics_driver;
919 unsigned int width, height;
920 WCHAR *cmdline = NULL, *driver = NULL;
921 WCHAR *p = arg;
922 const WCHAR *name = NULL;
923 BOOL enable_shell = FALSE;
925 /* get the rest of the command line (if any) */
926 while (*p && !is_whitespace(*p)) p++;
927 if (*p)
929 *p++ = 0;
930 while (*p && is_whitespace(*p)) p++;
931 if (*p) cmdline = p;
934 /* parse the desktop option */
935 /* the option is of the form /desktop=name[,widthxheight[,driver]] */
936 if (*arg == '=' || *arg == ',')
938 arg++;
939 name = arg;
940 if ((p = strchrW( arg, ',' )))
942 *p++ = 0;
943 if ((driver = strchrW( p, ',' ))) *driver++ = 0;
945 if (!p || !parse_size( p, &width, &height ))
946 get_default_desktop_size( name, &width, &height );
948 else if ((name = get_default_desktop_name()))
950 if (!get_default_desktop_size( name, &width, &height )) width = height = 0;
953 if (name)
954 enable_shell = get_default_enable_shell( name );
956 if (name && width && height)
958 if (!(desktop = CreateDesktopW( name, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL )))
960 WINE_ERR( "failed to create desktop %s error %d\n", wine_dbgstr_w(name), GetLastError() );
961 ExitProcess( 1 );
963 SetThreadDesktop( desktop );
966 UuidCreate( &guid );
967 TRACE( "display guid %s\n", debugstr_guid(&guid) );
968 graphics_driver = load_graphics_driver( driver, &guid );
970 /* create the desktop window */
971 hwnd = CreateWindowExW( 0, DESKTOP_CLASS_ATOM, NULL,
972 WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 0, 0, 0, 0, 0, &guid );
974 if (hwnd)
976 /* create the HWND_MESSAGE parent */
977 CreateWindowExW( 0, messageW, NULL, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
978 0, 0, 100, 100, 0, 0, 0, NULL );
980 desktop_orig_wndproc = (WNDPROC)SetWindowLongPtrW( hwnd, GWLP_WNDPROC,
981 (LONG_PTR)desktop_wnd_proc );
982 using_root = !desktop || !create_desktop( graphics_driver, name, width, height );
983 SendMessageW( hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW( 0, MAKEINTRESOURCEW(OIC_WINLOGO)));
984 if (name) set_desktop_window_title( hwnd, name );
985 SetWindowPos( hwnd, 0, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN),
986 GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN),
987 SWP_SHOWWINDOW );
988 SystemParametersInfoW( SPI_SETDESKWALLPAPER, 0, NULL, FALSE );
989 ClipCursor( NULL );
990 initialize_display_settings();
991 initialize_appbar();
993 if (graphics_driver)
995 HMODULE shell32;
996 void (WINAPI *pShellDDEInit)( BOOL );
998 if (using_root) enable_shell = FALSE;
1000 initialize_systray( graphics_driver, using_root, enable_shell );
1001 if (!using_root) initialize_launchers( hwnd );
1003 if ((shell32 = LoadLibraryA( "shell32.dll" )) &&
1004 (pShellDDEInit = (void *)GetProcAddress( shell32, (LPCSTR)188)))
1006 pShellDDEInit( TRUE );
1011 /* if we have a command line, execute it */
1012 if (cmdline)
1014 STARTUPINFOW si;
1015 PROCESS_INFORMATION pi;
1017 memset( &si, 0, sizeof(si) );
1018 si.cb = sizeof(si);
1019 WINE_TRACE( "starting %s\n", wine_dbgstr_w(cmdline) );
1020 if (CreateProcessW( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ))
1022 CloseHandle( pi.hThread );
1023 CloseHandle( pi.hProcess );
1027 desktopshellbrowserwindow_init();
1028 shellwindows_init();
1030 /* run the desktop message loop */
1031 if (hwnd)
1033 WINE_TRACE( "desktop message loop starting on hwnd %p\n", hwnd );
1034 while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
1035 WINE_TRACE( "desktop message loop exiting for hwnd %p\n", hwnd );
1038 ExitProcess( 0 );
1041 /* IShellWindows implementation */
1042 static HRESULT WINAPI shellwindows_QueryInterface(IShellWindows *iface, REFIID riid, void **ppvObject)
1044 struct shellwindows *This = impl_from_IShellWindows(iface);
1046 TRACE("%s %p\n", debugstr_guid(riid), ppvObject);
1048 if (IsEqualGUID(riid, &IID_IShellWindows) ||
1049 IsEqualGUID(riid, &IID_IDispatch) ||
1050 IsEqualGUID(riid, &IID_IUnknown))
1052 *ppvObject = &This->IShellWindows_iface;
1054 else
1056 WARN("Unsupported interface %s\n", debugstr_guid(riid));
1057 *ppvObject = NULL;
1060 if (*ppvObject)
1062 IUnknown_AddRef((IUnknown*)*ppvObject);
1063 return S_OK;
1066 return E_NOINTERFACE;
1069 static ULONG WINAPI shellwindows_AddRef(IShellWindows *iface)
1071 return 2;
1074 static ULONG WINAPI shellwindows_Release(IShellWindows *iface)
1076 return 1;
1079 static HRESULT WINAPI shellwindows_GetTypeInfoCount(IShellWindows *iface, UINT *pctinfo)
1081 TRACE("%p\n", pctinfo);
1082 *pctinfo = 1;
1083 return S_OK;
1086 static HRESULT WINAPI shellwindows_GetTypeInfo(IShellWindows *iface,
1087 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1089 TRACE("%d %d %p\n", iTInfo, lcid, ppTInfo);
1090 return get_typeinfo(IShellWindows_tid, ppTInfo);
1093 static HRESULT WINAPI shellwindows_GetIDsOfNames(IShellWindows *iface,
1094 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
1095 DISPID *rgDispId)
1097 ITypeInfo *typeinfo;
1098 HRESULT hr;
1100 TRACE("%s %p %d %d %p\n", debugstr_guid(riid), rgszNames, cNames,
1101 lcid, rgDispId);
1103 if (!rgszNames || cNames == 0 || !rgDispId)
1104 return E_INVALIDARG;
1106 hr = get_typeinfo(IShellWindows_tid, &typeinfo);
1107 if (SUCCEEDED(hr))
1109 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1110 ITypeInfo_Release(typeinfo);
1113 return hr;
1116 static HRESULT WINAPI shellwindows_Invoke(IShellWindows *iface,
1117 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
1118 DISPPARAMS *pDispParams, VARIANT *pVarResult,
1119 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1121 ITypeInfo *typeinfo;
1122 HRESULT hr;
1124 TRACE("%d %s %d %08x %p %p %p %p\n", dispIdMember, debugstr_guid(riid),
1125 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1127 hr = get_typeinfo(IShellWindows_tid, &typeinfo);
1128 if (SUCCEEDED(hr))
1130 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
1131 pDispParams, pVarResult, pExcepInfo, puArgErr);
1132 ITypeInfo_Release(typeinfo);
1135 return hr;
1138 static HRESULT WINAPI shellwindows_get_Count(IShellWindows *iface, LONG *count)
1140 FIXME("%p\n", count);
1141 return E_NOTIMPL;
1144 static HRESULT WINAPI shellwindows_Item(IShellWindows *iface, VARIANT index,
1145 IDispatch **folder)
1147 FIXME("%s %p\n", debugstr_variant(&index), folder);
1148 return E_NOTIMPL;
1151 static HRESULT WINAPI shellwindows__NewEnum(IShellWindows *iface, IUnknown **ppunk)
1153 FIXME("%p\n", ppunk);
1154 return E_NOTIMPL;
1157 static HRESULT WINAPI shellwindows_Register(IShellWindows *iface,
1158 IDispatch *disp, LONG hWnd, int class, LONG *cookie)
1160 FIXME("%p 0x%x 0x%x %p\n", disp, hWnd, class, cookie);
1161 return E_NOTIMPL;
1164 static HRESULT WINAPI shellwindows_RegisterPending(IShellWindows *iface,
1165 LONG threadid, VARIANT *loc, VARIANT *root, int class, LONG *cookie)
1167 FIXME("0x%x %s %s 0x%x %p\n", threadid, debugstr_variant(loc), debugstr_variant(root),
1168 class, cookie);
1169 return E_NOTIMPL;
1172 static HRESULT WINAPI shellwindows_Revoke(IShellWindows *iface, LONG cookie)
1174 FIXME("0x%x\n", cookie);
1175 return E_NOTIMPL;
1178 static HRESULT WINAPI shellwindows_OnNavigate(IShellWindows *iface, LONG cookie, VARIANT *loc)
1180 FIXME("0x%x %s\n", cookie, debugstr_variant(loc));
1181 return E_NOTIMPL;
1184 static HRESULT WINAPI shellwindows_OnActivated(IShellWindows *iface, LONG cookie, VARIANT_BOOL active)
1186 FIXME("0x%x 0x%x\n", cookie, active);
1187 return E_NOTIMPL;
1190 static HRESULT WINAPI shellwindows_FindWindowSW(IShellWindows *iface, VARIANT *loc,
1191 VARIANT *root, int class, LONG *hwnd, int options, IDispatch **disp)
1193 TRACE("%s %s 0x%x %p 0x%x %p\n", debugstr_variant(loc), debugstr_variant(root),
1194 class, hwnd, options, disp);
1196 if (class != SWC_DESKTOP)
1198 WARN("only SWC_DESKTOP class supported.\n");
1199 return E_NOTIMPL;
1202 *hwnd = HandleToLong(GetDesktopWindow());
1203 if (options & SWFO_NEEDDISPATCH)
1205 *disp = (IDispatch*)&desktopshellbrowserwindow.IWebBrowser2_iface;
1206 IDispatch_AddRef(*disp);
1209 return S_OK;
1212 static HRESULT WINAPI shellwindows_OnCreated(IShellWindows *iface, LONG cookie, IUnknown *punk)
1214 FIXME("0x%x %p\n", cookie, punk);
1215 return E_NOTIMPL;
1218 static HRESULT WINAPI shellwindows_ProcessAttachDetach(IShellWindows *iface, VARIANT_BOOL attach)
1220 FIXME("0x%x\n", attach);
1221 return E_NOTIMPL;
1224 static const IShellWindowsVtbl shellwindowsvtbl =
1226 shellwindows_QueryInterface,
1227 shellwindows_AddRef,
1228 shellwindows_Release,
1229 shellwindows_GetTypeInfoCount,
1230 shellwindows_GetTypeInfo,
1231 shellwindows_GetIDsOfNames,
1232 shellwindows_Invoke,
1233 shellwindows_get_Count,
1234 shellwindows_Item,
1235 shellwindows__NewEnum,
1236 shellwindows_Register,
1237 shellwindows_RegisterPending,
1238 shellwindows_Revoke,
1239 shellwindows_OnNavigate,
1240 shellwindows_OnActivated,
1241 shellwindows_FindWindowSW,
1242 shellwindows_OnCreated,
1243 shellwindows_ProcessAttachDetach
1246 struct shellwindows_classfactory
1248 IClassFactory IClassFactory_iface;
1249 DWORD classreg;
1252 static inline struct shellwindows_classfactory *impl_from_IClassFactory(IClassFactory *iface)
1254 return CONTAINING_RECORD(iface, struct shellwindows_classfactory, IClassFactory_iface);
1257 static HRESULT WINAPI swclassfactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppvObject)
1259 struct shellwindows_classfactory *This = impl_from_IClassFactory(iface);
1261 TRACE("%s %p\n", debugstr_guid(riid), ppvObject);
1263 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IClassFactory))
1265 *ppvObject = &This->IClassFactory_iface;
1267 else
1269 WARN("Unsupported interface %s\n", debugstr_guid(riid));
1270 *ppvObject = NULL;
1273 if (*ppvObject)
1275 IUnknown_AddRef((IUnknown*)*ppvObject);
1276 return S_OK;
1279 return E_NOINTERFACE;
1282 static ULONG WINAPI swclassfactory_AddRef(IClassFactory *iface)
1284 return 2;
1287 static ULONG WINAPI swclassfactory_Release(IClassFactory *iface)
1289 return 1;
1292 static HRESULT WINAPI swclassfactory_CreateInstance(IClassFactory *iface,
1293 IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
1295 TRACE("%p %s %p\n", pUnkOuter, debugstr_guid(riid), ppvObject);
1296 return IShellWindows_QueryInterface(&shellwindows.IShellWindows_iface, riid, ppvObject);
1299 static HRESULT WINAPI swclassfactory_LockServer(IClassFactory *iface, BOOL lock)
1301 TRACE("%u\n", lock);
1302 return E_NOTIMPL;
1305 static const IClassFactoryVtbl swclassfactoryvtbl =
1307 swclassfactory_QueryInterface,
1308 swclassfactory_AddRef,
1309 swclassfactory_Release,
1310 swclassfactory_CreateInstance,
1311 swclassfactory_LockServer
1314 static struct shellwindows_classfactory shellwindows_classfactory = { { &swclassfactoryvtbl } };
1316 static HRESULT WINAPI webbrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid, void **ppv)
1318 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1320 *ppv = NULL;
1322 if (IsEqualGUID(&IID_IWebBrowser2, riid) ||
1323 IsEqualGUID(&IID_IWebBrowserApp, riid) ||
1324 IsEqualGUID(&IID_IWebBrowser, riid) ||
1325 IsEqualGUID(&IID_IDispatch, riid) ||
1326 IsEqualGUID(&IID_IUnknown, riid))
1328 *ppv = &This->IWebBrowser2_iface;
1330 else if (IsEqualGUID(&IID_IServiceProvider, riid))
1332 *ppv = &This->IServiceProvider_iface;
1335 if (*ppv)
1337 IUnknown_AddRef((IUnknown*)*ppv);
1338 return S_OK;
1341 FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
1342 return E_NOINTERFACE;
1345 static ULONG WINAPI webbrowser_AddRef(IWebBrowser2 *iface)
1347 return 2;
1350 static ULONG WINAPI webbrowser_Release(IWebBrowser2 *iface)
1352 return 1;
1355 /* IDispatch methods */
1356 static HRESULT WINAPI webbrowser_GetTypeInfoCount(IWebBrowser2 *iface, UINT *pctinfo)
1358 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1359 TRACE("(%p)->(%p)\n", This, pctinfo);
1360 *pctinfo = 1;
1361 return S_OK;
1364 static HRESULT WINAPI webbrowser_GetTypeInfo(IWebBrowser2 *iface, UINT iTInfo, LCID lcid,
1365 LPTYPEINFO *ppTInfo)
1367 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1368 TRACE("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
1369 return get_typeinfo(IWebBrowser2_tid, ppTInfo);
1372 static HRESULT WINAPI webbrowser_GetIDsOfNames(IWebBrowser2 *iface, REFIID riid,
1373 LPOLESTR *rgszNames, UINT cNames,
1374 LCID lcid, DISPID *rgDispId)
1376 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1377 ITypeInfo *typeinfo;
1378 HRESULT hr;
1380 TRACE("(%p)->(%s %p %d %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1381 lcid, rgDispId);
1383 if(!rgszNames || cNames == 0 || !rgDispId)
1384 return E_INVALIDARG;
1386 hr = get_typeinfo(IWebBrowser2_tid, &typeinfo);
1387 if (SUCCEEDED(hr))
1389 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1390 ITypeInfo_Release(typeinfo);
1393 return hr;
1396 static HRESULT WINAPI webbrowser_Invoke(IWebBrowser2 *iface, DISPID dispIdMember,
1397 REFIID riid, LCID lcid, WORD wFlags,
1398 DISPPARAMS *pDispParams, VARIANT *pVarResult,
1399 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1401 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1402 ITypeInfo *typeinfo;
1403 HRESULT hr;
1405 TRACE("(%p)->(%d %s %d %08x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1406 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1408 hr = get_typeinfo(IWebBrowser2_tid, &typeinfo);
1409 if (SUCCEEDED(hr))
1411 hr = ITypeInfo_Invoke(typeinfo, &This->IWebBrowser2_iface, dispIdMember, wFlags,
1412 pDispParams, pVarResult, pExcepInfo, puArgErr);
1413 ITypeInfo_Release(typeinfo);
1416 return hr;
1419 /* IWebBrowser methods */
1420 static HRESULT WINAPI webbrowser_GoBack(IWebBrowser2 *iface)
1422 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1423 FIXME("(%p): stub\n", This);
1424 return E_NOTIMPL;
1427 static HRESULT WINAPI webbrowser_GoForward(IWebBrowser2 *iface)
1429 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1430 FIXME("(%p): stub\n", This);
1431 return E_NOTIMPL;
1434 static HRESULT WINAPI webbrowser_GoHome(IWebBrowser2 *iface)
1436 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1437 FIXME("(%p): stub\n", This);
1438 return E_NOTIMPL;
1441 static HRESULT WINAPI webbrowser_GoSearch(IWebBrowser2 *iface)
1443 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1444 FIXME("(%p)\n", This);
1445 return E_NOTIMPL;
1448 static HRESULT WINAPI webbrowser_Navigate(IWebBrowser2 *iface, BSTR szUrl,
1449 VARIANT *Flags, VARIANT *TargetFrameName,
1450 VARIANT *PostData, VARIANT *Headers)
1452 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1453 FIXME("(%p)->(%s %s %s %s %s): stub\n", This, debugstr_w(szUrl), debugstr_variant(Flags),
1454 debugstr_variant(TargetFrameName), debugstr_variant(PostData),
1455 debugstr_variant(Headers));
1456 return E_NOTIMPL;
1459 static HRESULT WINAPI webbrowser_Refresh(IWebBrowser2 *iface)
1461 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1462 FIXME("(%p): stub\n", This);
1463 return E_NOTIMPL;
1466 static HRESULT WINAPI webbrowser_Refresh2(IWebBrowser2 *iface, VARIANT *Level)
1468 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1469 FIXME("(%p)->(%s): stub\n", This, debugstr_variant(Level));
1470 return E_NOTIMPL;
1473 static HRESULT WINAPI webbrowser_Stop(IWebBrowser2 *iface)
1475 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1476 FIXME("(%p): stub\n", This);
1477 return E_NOTIMPL;
1480 static HRESULT WINAPI webbrowser_get_Application(IWebBrowser2 *iface, IDispatch **ppDisp)
1482 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1484 TRACE("(%p)->(%p)\n", This, ppDisp);
1486 *ppDisp = (IDispatch*)iface;
1487 IDispatch_AddRef(*ppDisp);
1489 return S_OK;
1492 static HRESULT WINAPI webbrowser_get_Parent(IWebBrowser2 *iface, IDispatch **ppDisp)
1494 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1495 FIXME("(%p)->(%p)\n", This, ppDisp);
1496 return E_NOTIMPL;
1499 static HRESULT WINAPI webbrowser_get_Container(IWebBrowser2 *iface, IDispatch **ppDisp)
1501 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1502 FIXME("(%p)->(%p)\n", This, ppDisp);
1503 return E_NOTIMPL;
1506 static HRESULT WINAPI webbrowser_get_Document(IWebBrowser2 *iface, IDispatch **ppDisp)
1508 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1509 FIXME("(%p)->(%p)\n", This, ppDisp);
1510 return E_NOTIMPL;
1513 static HRESULT WINAPI webbrowser_get_TopLevelContainer(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
1515 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1516 FIXME("(%p)->(%p)\n", This, pBool);
1517 return E_NOTIMPL;
1520 static HRESULT WINAPI webbrowser_get_Type(IWebBrowser2 *iface, BSTR *Type)
1522 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1523 FIXME("(%p)->(%p)\n", This, Type);
1524 return E_NOTIMPL;
1527 static HRESULT WINAPI webbrowser_get_Left(IWebBrowser2 *iface, LONG *pl)
1529 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1530 FIXME("(%p)->(%p)\n", This, pl);
1531 return E_NOTIMPL;
1534 static HRESULT WINAPI webbrowser_put_Left(IWebBrowser2 *iface, LONG Left)
1536 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1537 FIXME("(%p)->(%d)\n", This, Left);
1538 return E_NOTIMPL;
1541 static HRESULT WINAPI webbrowser_get_Top(IWebBrowser2 *iface, LONG *pl)
1543 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1544 FIXME("(%p)->(%p)\n", This, pl);
1545 return E_NOTIMPL;
1548 static HRESULT WINAPI webbrowser_put_Top(IWebBrowser2 *iface, LONG Top)
1550 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1551 FIXME("(%p)->(%d)\n", This, Top);
1552 return E_NOTIMPL;
1555 static HRESULT WINAPI webbrowser_get_Width(IWebBrowser2 *iface, LONG *pl)
1557 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1558 FIXME("(%p)->(%p)\n", This, pl);
1559 return E_NOTIMPL;
1562 static HRESULT WINAPI webbrowser_put_Width(IWebBrowser2 *iface, LONG Width)
1564 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1565 FIXME("(%p)->(%d)\n", This, Width);
1566 return E_NOTIMPL;
1569 static HRESULT WINAPI webbrowser_get_Height(IWebBrowser2 *iface, LONG *pl)
1571 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1572 FIXME("(%p)->(%p)\n", This, pl);
1573 return E_NOTIMPL;
1576 static HRESULT WINAPI webbrowser_put_Height(IWebBrowser2 *iface, LONG Height)
1578 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1579 FIXME("(%p)->(%d)\n", This, Height);
1580 return E_NOTIMPL;
1583 static HRESULT WINAPI webbrowser_get_LocationName(IWebBrowser2 *iface, BSTR *LocationName)
1585 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1586 FIXME("(%p)->(%p)\n", This, LocationName);
1587 return E_NOTIMPL;
1590 static HRESULT WINAPI webbrowser_get_LocationURL(IWebBrowser2 *iface, BSTR *LocationURL)
1592 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1593 FIXME("(%p)->(%p)\n", This, LocationURL);
1594 return E_NOTIMPL;
1597 static HRESULT WINAPI webbrowser_get_Busy(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
1599 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1600 FIXME("(%p)->(%p)\n", This, pBool);
1601 return E_NOTIMPL;
1604 static HRESULT WINAPI webbrowser_Quit(IWebBrowser2 *iface)
1606 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1607 FIXME("(%p)\n", This);
1608 return E_NOTIMPL;
1611 static HRESULT WINAPI webbrowser_ClientToWindow(IWebBrowser2 *iface, int *pcx, int *pcy)
1613 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1614 FIXME("(%p)->(%p %p)\n", This, pcx, pcy);
1615 return E_NOTIMPL;
1618 static HRESULT WINAPI webbrowser_PutProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT vtValue)
1620 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1621 FIXME("(%p)->(%s %s)\n", This, debugstr_w(szProperty), debugstr_variant(&vtValue));
1622 return E_NOTIMPL;
1625 static HRESULT WINAPI webbrowser_GetProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT *pvtValue)
1627 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1628 FIXME("(%p)->(%s %s)\n", This, debugstr_w(szProperty), debugstr_variant(pvtValue));
1629 return E_NOTIMPL;
1632 static HRESULT WINAPI webbrowser_get_Name(IWebBrowser2 *iface, BSTR *Name)
1634 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1635 FIXME("(%p)->(%p)\n", This, Name);
1636 return E_NOTIMPL;
1639 static HRESULT WINAPI webbrowser_get_HWND(IWebBrowser2 *iface, SHANDLE_PTR *pHWND)
1641 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1642 FIXME("(%p)->(%p)\n", This, pHWND);
1643 return E_NOTIMPL;
1646 static HRESULT WINAPI webbrowser_get_FullName(IWebBrowser2 *iface, BSTR *FullName)
1648 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1649 FIXME("(%p)->(%p)\n", This, FullName);
1650 return E_NOTIMPL;
1653 static HRESULT WINAPI webbrowser_get_Path(IWebBrowser2 *iface, BSTR *Path)
1655 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1656 FIXME("(%p)->(%p)\n", This, Path);
1657 return E_NOTIMPL;
1660 static HRESULT WINAPI webbrowser_get_Visible(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
1662 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1663 FIXME("(%p)->(%p)\n", This, pBool);
1664 return E_NOTIMPL;
1667 static HRESULT WINAPI webbrowser_put_Visible(IWebBrowser2 *iface, VARIANT_BOOL Value)
1669 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1670 FIXME("(%p)->(%x)\n", This, Value);
1671 return E_NOTIMPL;
1674 static HRESULT WINAPI webbrowser_get_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
1676 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1677 FIXME("(%p)->(%p)\n", This, pBool);
1678 return E_NOTIMPL;
1681 static HRESULT WINAPI webbrowser_put_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
1683 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1684 FIXME("(%p)->(%x)\n", This, Value);
1685 return E_NOTIMPL;
1688 static HRESULT WINAPI webbrowser_get_StatusText(IWebBrowser2 *iface, BSTR *StatusText)
1690 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1691 FIXME("(%p)->(%p)\n", This, StatusText);
1692 return E_NOTIMPL;
1695 static HRESULT WINAPI webbrowser_put_StatusText(IWebBrowser2 *iface, BSTR StatusText)
1697 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1698 FIXME("(%p)->(%s)\n", This, debugstr_w(StatusText));
1699 return E_NOTIMPL;
1702 static HRESULT WINAPI webbrowser_get_ToolBar(IWebBrowser2 *iface, int *Value)
1704 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1705 FIXME("(%p)->(%p)\n", This, Value);
1706 return E_NOTIMPL;
1709 static HRESULT WINAPI webbrowser_put_ToolBar(IWebBrowser2 *iface, int Value)
1711 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1712 FIXME("(%p)->(%x)\n", This, Value);
1713 return E_NOTIMPL;
1716 static HRESULT WINAPI webbrowser_get_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
1718 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1719 FIXME("(%p)->(%p)\n", This, Value);
1720 return E_NOTIMPL;
1723 static HRESULT WINAPI webbrowser_put_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
1725 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1726 FIXME("(%p)->(%x)\n", This, Value);
1727 return E_NOTIMPL;
1730 static HRESULT WINAPI webbrowser_get_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL *pbFullScreen)
1732 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1733 FIXME("(%p)->(%p)\n", This, pbFullScreen);
1734 return E_NOTIMPL;
1737 static HRESULT WINAPI webbrowser_put_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL bFullScreen)
1739 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1740 FIXME("(%p)->(%x)\n", This, bFullScreen);
1741 return E_NOTIMPL;
1744 static HRESULT WINAPI webbrowser_Navigate2(IWebBrowser2 *iface, VARIANT *URL, VARIANT *Flags,
1745 VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
1747 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1748 FIXME("(%p)->(%s %s %s %s %s)\n", This, debugstr_variant(URL), debugstr_variant(Flags),
1749 debugstr_variant(TargetFrameName), debugstr_variant(PostData), debugstr_variant(Headers));
1750 return E_NOTIMPL;
1753 static HRESULT WINAPI webbrowser_QueryStatusWB(IWebBrowser2 *iface, OLECMDID cmdID, OLECMDF *pcmdf)
1755 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1756 FIXME("(%p)->(%d %p)\n", This, cmdID, pcmdf);
1757 return E_NOTIMPL;
1760 static HRESULT WINAPI webbrowser_ExecWB(IWebBrowser2 *iface, OLECMDID cmdID,
1761 OLECMDEXECOPT cmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1763 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1764 FIXME("(%p)->(%d %d %s %p)\n", This, cmdID, cmdexecopt, debugstr_variant(pvaIn), pvaOut);
1765 return E_NOTIMPL;
1768 static HRESULT WINAPI webbrowser_ShowBrowserBar(IWebBrowser2 *iface, VARIANT *pvaClsid,
1769 VARIANT *pvarShow, VARIANT *pvarSize)
1771 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1772 FIXME("(%p)->(%s %s %s)\n", This, debugstr_variant(pvaClsid), debugstr_variant(pvarShow),
1773 debugstr_variant(pvarSize));
1774 return E_NOTIMPL;
1777 static HRESULT WINAPI webbrowser_get_ReadyState(IWebBrowser2 *iface, READYSTATE *lpReadyState)
1779 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1780 FIXME("(%p)->(%p)\n", This, lpReadyState);
1781 return E_NOTIMPL;
1784 static HRESULT WINAPI webbrowser_get_Offline(IWebBrowser2 *iface, VARIANT_BOOL *pbOffline)
1786 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1787 FIXME("(%p)->(%p)\n", This, pbOffline);
1788 return E_NOTIMPL;
1791 static HRESULT WINAPI webbrowser_put_Offline(IWebBrowser2 *iface, VARIANT_BOOL bOffline)
1793 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1794 FIXME("(%p)->(%x)\n", This, bOffline);
1795 return E_NOTIMPL;
1798 static HRESULT WINAPI webbrowser_get_Silent(IWebBrowser2 *iface, VARIANT_BOOL *pbSilent)
1800 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1801 FIXME("(%p)->(%p)\n", This, pbSilent);
1802 return E_NOTIMPL;
1805 static HRESULT WINAPI webbrowser_put_Silent(IWebBrowser2 *iface, VARIANT_BOOL bSilent)
1807 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1808 FIXME("(%p)->(%x)\n", This, bSilent);
1809 return E_NOTIMPL;
1812 static HRESULT WINAPI webbrowser_get_RegisterAsBrowser(IWebBrowser2 *iface,
1813 VARIANT_BOOL *pbRegister)
1815 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1816 FIXME("(%p)->(%p)\n", This, pbRegister);
1817 return E_NOTIMPL;
1820 static HRESULT WINAPI webbrowser_put_RegisterAsBrowser(IWebBrowser2 *iface,
1821 VARIANT_BOOL bRegister)
1823 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1824 FIXME("(%p)->(%x)\n", This, bRegister);
1825 return E_NOTIMPL;
1828 static HRESULT WINAPI webbrowser_get_RegisterAsDropTarget(IWebBrowser2 *iface,
1829 VARIANT_BOOL *pbRegister)
1831 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1832 FIXME("(%p)->(%p)\n", This, pbRegister);
1833 return E_NOTIMPL;
1836 static HRESULT WINAPI webbrowser_put_RegisterAsDropTarget(IWebBrowser2 *iface,
1837 VARIANT_BOOL bRegister)
1839 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1840 FIXME("(%p)->(%x)\n", This, bRegister);
1841 return E_NOTIMPL;
1844 static HRESULT WINAPI webbrowser_get_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL *pbRegister)
1846 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1847 FIXME("(%p)->(%p)\n", This, pbRegister);
1848 return E_NOTIMPL;
1851 static HRESULT WINAPI webbrowser_put_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL bRegister)
1853 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1854 TRACE("(%p)->(%x)\n", This, bRegister);
1855 return E_NOTIMPL;
1858 static HRESULT WINAPI webbrowser_get_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
1860 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1861 FIXME("(%p)->(%p)\n", This, Value);
1862 return E_NOTIMPL;
1865 static HRESULT WINAPI webbrowser_put_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
1867 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1868 FIXME("(%p)->(%x)\n", This, Value);
1869 return E_NOTIMPL;
1872 static HRESULT WINAPI webbrowser_get_Resizable(IWebBrowser2 *iface, VARIANT_BOOL *Value)
1874 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1875 FIXME("(%p)->(%p)\n", This, Value);
1876 return E_NOTIMPL;
1879 static HRESULT WINAPI webbrowser_put_Resizable(IWebBrowser2 *iface, VARIANT_BOOL Value)
1881 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1882 FIXME("(%p)->(%x)\n", This, Value);
1883 return E_NOTIMPL;
1886 static const IWebBrowser2Vtbl webbrowser2vtbl =
1888 webbrowser_QueryInterface,
1889 webbrowser_AddRef,
1890 webbrowser_Release,
1891 webbrowser_GetTypeInfoCount,
1892 webbrowser_GetTypeInfo,
1893 webbrowser_GetIDsOfNames,
1894 webbrowser_Invoke,
1895 webbrowser_GoBack,
1896 webbrowser_GoForward,
1897 webbrowser_GoHome,
1898 webbrowser_GoSearch,
1899 webbrowser_Navigate,
1900 webbrowser_Refresh,
1901 webbrowser_Refresh2,
1902 webbrowser_Stop,
1903 webbrowser_get_Application,
1904 webbrowser_get_Parent,
1905 webbrowser_get_Container,
1906 webbrowser_get_Document,
1907 webbrowser_get_TopLevelContainer,
1908 webbrowser_get_Type,
1909 webbrowser_get_Left,
1910 webbrowser_put_Left,
1911 webbrowser_get_Top,
1912 webbrowser_put_Top,
1913 webbrowser_get_Width,
1914 webbrowser_put_Width,
1915 webbrowser_get_Height,
1916 webbrowser_put_Height,
1917 webbrowser_get_LocationName,
1918 webbrowser_get_LocationURL,
1919 webbrowser_get_Busy,
1920 webbrowser_Quit,
1921 webbrowser_ClientToWindow,
1922 webbrowser_PutProperty,
1923 webbrowser_GetProperty,
1924 webbrowser_get_Name,
1925 webbrowser_get_HWND,
1926 webbrowser_get_FullName,
1927 webbrowser_get_Path,
1928 webbrowser_get_Visible,
1929 webbrowser_put_Visible,
1930 webbrowser_get_StatusBar,
1931 webbrowser_put_StatusBar,
1932 webbrowser_get_StatusText,
1933 webbrowser_put_StatusText,
1934 webbrowser_get_ToolBar,
1935 webbrowser_put_ToolBar,
1936 webbrowser_get_MenuBar,
1937 webbrowser_put_MenuBar,
1938 webbrowser_get_FullScreen,
1939 webbrowser_put_FullScreen,
1940 webbrowser_Navigate2,
1941 webbrowser_QueryStatusWB,
1942 webbrowser_ExecWB,
1943 webbrowser_ShowBrowserBar,
1944 webbrowser_get_ReadyState,
1945 webbrowser_get_Offline,
1946 webbrowser_put_Offline,
1947 webbrowser_get_Silent,
1948 webbrowser_put_Silent,
1949 webbrowser_get_RegisterAsBrowser,
1950 webbrowser_put_RegisterAsBrowser,
1951 webbrowser_get_RegisterAsDropTarget,
1952 webbrowser_put_RegisterAsDropTarget,
1953 webbrowser_get_TheaterMode,
1954 webbrowser_put_TheaterMode,
1955 webbrowser_get_AddressBar,
1956 webbrowser_put_AddressBar,
1957 webbrowser_get_Resizable,
1958 webbrowser_put_Resizable
1961 static HRESULT WINAPI serviceprovider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
1963 struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
1964 return IWebBrowser2_QueryInterface(&This->IWebBrowser2_iface, riid, ppv);
1967 static ULONG WINAPI serviceprovider_AddRef(IServiceProvider *iface)
1969 struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
1970 return IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
1973 static ULONG WINAPI serviceprovider_Release(IServiceProvider *iface)
1975 struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
1976 return IWebBrowser2_Release(&This->IWebBrowser2_iface);
1979 static HRESULT WINAPI serviceprovider_QueryService(IServiceProvider *iface, REFGUID service,
1980 REFIID riid, void **ppv)
1982 struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
1984 TRACE("%s %s %p\n", debugstr_guid(service), debugstr_guid(riid), ppv);
1986 if (IsEqualGUID(service, &SID_STopLevelBrowser))
1987 return IShellBrowser_QueryInterface(&This->IShellBrowser_iface, riid, ppv);
1989 WARN("unknown service id %s\n", debugstr_guid(service));
1990 return E_NOTIMPL;
1993 static const IServiceProviderVtbl serviceprovidervtbl =
1995 serviceprovider_QueryInterface,
1996 serviceprovider_AddRef,
1997 serviceprovider_Release,
1998 serviceprovider_QueryService
2001 /* IShellBrowser */
2002 static HRESULT WINAPI shellbrowser_QueryInterface(IShellBrowser *iface, REFIID riid, void **ppv)
2004 TRACE("%s %p\n", debugstr_guid(riid), ppv);
2006 *ppv = NULL;
2008 if (IsEqualGUID(&IID_IShellBrowser, riid) ||
2009 IsEqualGUID(&IID_IOleWindow, riid) ||
2010 IsEqualGUID(&IID_IUnknown, riid))
2012 *ppv = iface;
2015 if (*ppv)
2017 IUnknown_AddRef((IUnknown*)*ppv);
2018 return S_OK;
2021 return E_NOINTERFACE;
2024 static ULONG WINAPI shellbrowser_AddRef(IShellBrowser *iface)
2026 struct shellbrowserwindow *This = impl_from_IShellBrowser(iface);
2027 return IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
2030 static ULONG WINAPI shellbrowser_Release(IShellBrowser *iface)
2032 struct shellbrowserwindow *This = impl_from_IShellBrowser(iface);
2033 return IWebBrowser2_Release(&This->IWebBrowser2_iface);
2036 static HRESULT WINAPI shellbrowser_GetWindow(IShellBrowser *iface, HWND *phwnd)
2038 FIXME("%p\n", phwnd);
2039 return E_NOTIMPL;
2042 static HRESULT WINAPI shellbrowser_ContextSensitiveHelp(IShellBrowser *iface, BOOL mode)
2044 FIXME("%d\n", mode);
2045 return E_NOTIMPL;
2048 static HRESULT WINAPI shellbrowser_InsertMenusSB(IShellBrowser *iface, HMENU hmenuShared,
2049 OLEMENUGROUPWIDTHS *menuwidths)
2051 FIXME("%p %p\n", hmenuShared, menuwidths);
2052 return E_NOTIMPL;
2055 static HRESULT WINAPI shellbrowser_SetMenuSB(IShellBrowser *iface, HMENU hmenuShared,
2056 HOLEMENU holemenuReserved, HWND hwndActiveObject)
2058 FIXME("%p %p %p\n", hmenuShared, holemenuReserved, hwndActiveObject);
2059 return E_NOTIMPL;
2062 static HRESULT WINAPI shellbrowser_RemoveMenusSB(IShellBrowser *iface, HMENU hmenuShared)
2064 FIXME("%p\n", hmenuShared);
2065 return E_NOTIMPL;
2068 static HRESULT WINAPI shellbrowser_SetStatusTextSB(IShellBrowser *iface, LPCOLESTR text)
2070 FIXME("%s\n", debugstr_w(text));
2071 return E_NOTIMPL;
2074 static HRESULT WINAPI shellbrowser_EnableModelessSB(IShellBrowser *iface, BOOL enable)
2076 FIXME("%d\n", enable);
2077 return E_NOTIMPL;
2080 static HRESULT WINAPI shellbrowser_TranslateAcceleratorSB(IShellBrowser *iface, MSG *pmsg, WORD wID)
2082 FIXME("%p 0x%x\n", pmsg, wID);
2083 return E_NOTIMPL;
2086 static HRESULT WINAPI shellbrowser_BrowseObject(IShellBrowser *iface, LPCITEMIDLIST pidl, UINT flags)
2088 FIXME("%p %x\n", pidl, flags);
2089 return E_NOTIMPL;
2092 static HRESULT WINAPI shellbrowser_GetViewStateStream(IShellBrowser *iface, DWORD mode, IStream **stream)
2094 FIXME("0x%x %p\n", mode, stream);
2095 return E_NOTIMPL;
2098 static HRESULT WINAPI shellbrowser_GetControlWindow(IShellBrowser *iface, UINT id, HWND *phwnd)
2100 FIXME("%d %p\n", id, phwnd);
2101 return E_NOTIMPL;
2104 static HRESULT WINAPI shellbrowser_SendControlMsg(IShellBrowser *iface, UINT id, UINT uMsg,
2105 WPARAM wParam, LPARAM lParam, LRESULT *pret)
2107 FIXME("%d %d %lx %lx %p\n", id, uMsg, wParam, lParam, pret);
2108 return E_NOTIMPL;
2111 static HRESULT WINAPI shellbrowser_QueryActiveShellView(IShellBrowser *iface, IShellView **view)
2113 TRACE("%p\n", view);
2115 *view = desktopshellbrowserwindow.view;
2116 IShellView_AddRef(*view);
2117 return S_OK;
2120 static HRESULT WINAPI shellbrowser_OnViewWindowActive(IShellBrowser *iface, IShellView *view)
2122 FIXME("%p\n", view);
2123 return E_NOTIMPL;
2126 static HRESULT WINAPI shellbrowser_SetToolbarItems(IShellBrowser *iface, LPTBBUTTONSB buttons,
2127 UINT count, UINT flags)
2129 FIXME("%p %d 0x%x\n", buttons, count, flags);
2130 return E_NOTIMPL;
2133 static const IShellBrowserVtbl shellbrowservtbl = {
2134 shellbrowser_QueryInterface,
2135 shellbrowser_AddRef,
2136 shellbrowser_Release,
2137 shellbrowser_GetWindow,
2138 shellbrowser_ContextSensitiveHelp,
2139 shellbrowser_InsertMenusSB,
2140 shellbrowser_SetMenuSB,
2141 shellbrowser_RemoveMenusSB,
2142 shellbrowser_SetStatusTextSB,
2143 shellbrowser_EnableModelessSB,
2144 shellbrowser_TranslateAcceleratorSB,
2145 shellbrowser_BrowseObject,
2146 shellbrowser_GetViewStateStream,
2147 shellbrowser_GetControlWindow,
2148 shellbrowser_SendControlMsg,
2149 shellbrowser_QueryActiveShellView,
2150 shellbrowser_OnViewWindowActive,
2151 shellbrowser_SetToolbarItems
2154 static void desktopshellbrowserwindow_init(void)
2156 IShellFolder *folder;
2158 desktopshellbrowserwindow.IWebBrowser2_iface.lpVtbl = &webbrowser2vtbl;
2159 desktopshellbrowserwindow.IServiceProvider_iface.lpVtbl = &serviceprovidervtbl;
2160 desktopshellbrowserwindow.IShellBrowser_iface.lpVtbl = &shellbrowservtbl;
2162 if (FAILED(SHGetDesktopFolder(&folder)))
2163 return;
2165 IShellFolder_CreateViewObject(folder, NULL, &IID_IShellView, (void**)&desktopshellbrowserwindow.view);
2168 static void shellwindows_init(void)
2170 HRESULT hr;
2172 CoInitialize(NULL);
2174 shellwindows.IShellWindows_iface.lpVtbl = &shellwindowsvtbl;
2176 hr = CoRegisterClassObject(&CLSID_ShellWindows,
2177 (IUnknown*)&shellwindows_classfactory.IClassFactory_iface,
2178 CLSCTX_LOCAL_SERVER,
2179 REGCLS_MULTIPLEUSE,
2180 &shellwindows_classfactory.classreg);
2182 if (FAILED(hr))
2183 WARN("Failed to register ShellWindows object: %08x\n", hr);