d3d8: Fix DrawIndexedPrimitiveUP with non-zero min_vertex_idx.
[wine.git] / programs / explorer / desktop.c
blob7a8252fdd705ef81f6beac56a6a8fd1ffab35a7b
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 /* window procedure for the desktop window */
603 static LRESULT WINAPI desktop_wnd_proc( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
605 WINE_TRACE( "got msg %04x wp %lx lp %lx\n", message, wp, lp );
607 switch(message)
609 case WM_SYSCOMMAND:
610 switch(wp & 0xfff0)
612 case SC_CLOSE:
613 ExitWindows( 0, 0 );
614 break;
615 case SC_SCREENSAVE:
616 return start_screensaver();
618 return 0;
620 case WM_CLOSE:
621 PostQuitMessage(0);
622 return 0;
624 case WM_SETCURSOR:
625 return (LRESULT)SetCursor( LoadCursorA( 0, (LPSTR)IDC_ARROW ) );
627 case WM_NCHITTEST:
628 return HTCLIENT;
630 case WM_ERASEBKGND:
631 if (!using_root) PaintDesktop( (HDC)wp );
632 return TRUE;
634 case WM_SETTINGCHANGE:
635 if (wp == SPI_SETDESKWALLPAPER)
636 SystemParametersInfoW( SPI_SETDESKWALLPAPER, 0, NULL, FALSE );
637 return 0;
639 case WM_PARENTNOTIFY:
640 handle_parent_notify( (HWND)lp, wp );
641 return 0;
643 case WM_LBUTTONDBLCLK:
644 if (!using_root)
646 const struct launcher *launcher = launcher_from_point( (short)LOWORD(lp), (short)HIWORD(lp) );
647 if (launcher) do_launch( launcher );
649 return 0;
651 case WM_PAINT:
653 PAINTSTRUCT ps;
654 BeginPaint( hwnd, &ps );
655 if (!using_root)
657 if (ps.fErase) PaintDesktop( ps.hdc );
658 draw_launchers( ps.hdc, ps.rcPaint );
660 EndPaint( hwnd, &ps );
662 return 0;
664 default:
665 return DefWindowProcW( hwnd, message, wp, lp );
669 /* create the desktop and the associated driver window, and make it the current desktop */
670 static BOOL create_desktop( HMODULE driver, const WCHAR *name, unsigned int width, unsigned int height )
672 static const WCHAR rootW[] = {'r','o','o','t',0};
673 BOOL ret = FALSE;
674 BOOL (CDECL *create_desktop_func)(unsigned int, unsigned int);
676 /* magic: desktop "root" means use the root window */
677 if (driver && strcmpiW( name, rootW ))
679 create_desktop_func = (void *)GetProcAddress( driver, "wine_create_desktop" );
680 if (create_desktop_func) ret = create_desktop_func( width, height );
682 return ret;
685 /* parse the desktop size specification */
686 static BOOL parse_size( const WCHAR *size, unsigned int *width, unsigned int *height )
688 WCHAR *end;
690 *width = strtoulW( size, &end, 10 );
691 if (end == size) return FALSE;
692 if (*end != 'x') return FALSE;
693 size = end + 1;
694 *height = strtoulW( size, &end, 10 );
695 return !*end;
698 /* retrieve the desktop name to use if not specified on the command line */
699 static const WCHAR *get_default_desktop_name(void)
701 static const WCHAR desktopW[] = {'D','e','s','k','t','o','p',0};
702 static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',0};
703 static const WCHAR explorer_keyW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
704 'E','x','p','l','o','r','e','r',0};
705 static WCHAR buffer[MAX_PATH];
706 DWORD size = sizeof(buffer);
707 HDESK desk = GetThreadDesktop( GetCurrentThreadId() );
708 WCHAR *ret = NULL;
709 HKEY hkey;
711 if (desk && GetUserObjectInformationW( desk, UOI_NAME, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
713 if (strcmpiW( buffer, defaultW )) return buffer;
716 /* @@ Wine registry key: HKCU\Software\Wine\Explorer */
717 if (!RegOpenKeyW( HKEY_CURRENT_USER, explorer_keyW, &hkey ))
719 if (!RegQueryValueExW( hkey, desktopW, 0, NULL, (LPBYTE)buffer, &size )) ret = buffer;
720 RegCloseKey( hkey );
722 return ret;
725 /* retrieve the default desktop size from the registry */
726 static BOOL get_default_desktop_size( const WCHAR *name, unsigned int *width, unsigned int *height )
728 static const WCHAR desktop_keyW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
729 'E','x','p','l','o','r','e','r','\\',
730 'D','e','s','k','t','o','p','s',0};
731 HKEY hkey;
732 WCHAR buffer[64];
733 DWORD size = sizeof(buffer);
734 BOOL found = FALSE;
736 *width = 800;
737 *height = 600;
739 /* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
740 if (!RegOpenKeyW( HKEY_CURRENT_USER, desktop_keyW, &hkey ))
742 if (!RegQueryValueExW( hkey, name, 0, NULL, (LPBYTE)buffer, &size ))
744 found = TRUE;
745 if (!parse_size( buffer, width, height )) *width = *height = 0;
747 RegCloseKey( hkey );
749 return found;
752 static BOOL get_default_enable_shell( const WCHAR *name )
754 static const WCHAR desktop_keyW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
755 'E','x','p','l','o','r','e','r','\\',
756 'D','e','s','k','t','o','p','s',0};
757 static const WCHAR enable_shellW[] = {'E','n','a','b','l','e','S','h','e','l','l',0};
758 static const WCHAR shellW[] = {'s','h','e','l','l',0};
759 HKEY hkey;
760 BOOL found = FALSE;
761 BOOL result;
762 DWORD size = sizeof(result);
764 /* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
765 if (!RegOpenKeyW( HKEY_CURRENT_USER, desktop_keyW, &hkey ))
767 if (!RegGetValueW( hkey, name, enable_shellW, RRF_RT_REG_DWORD, NULL, &result, &size ))
768 found = TRUE;
769 RegCloseKey( hkey );
771 /* Default off, except for the magic desktop name "shell" */
772 if (!found)
773 result = (lstrcmpiW( name, shellW ) == 0);
774 return result;
777 static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
779 static const WCHAR device_keyW[] = {
780 'S','y','s','t','e','m','\\',
781 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
782 'C','o','n','t','r','o','l','\\',
783 'V','i','d','e','o','\\',
784 '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-',
785 '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x','%','0','2','x',
786 '%','0','2','x','%','0','2','x','%','0','2','x','}','\\','0','0','0','0',0};
787 static const WCHAR graphics_driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
788 static const WCHAR driversW[] = {'S','o','f','t','w','a','r','e','\\',
789 'W','i','n','e','\\','D','r','i','v','e','r','s',0};
790 static const WCHAR graphicsW[] = {'G','r','a','p','h','i','c','s',0};
791 static const WCHAR drv_formatW[] = {'w','i','n','e','%','s','.','d','r','v',0};
793 WCHAR buffer[MAX_PATH], libname[32], *name, *next;
794 WCHAR key[sizeof(device_keyW)/sizeof(WCHAR) + 39];
795 HMODULE module = 0;
796 HKEY hkey;
797 char error[80];
799 if (!driver)
801 strcpyW( buffer, default_driver );
803 /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
804 if (!RegOpenKeyW( HKEY_CURRENT_USER, driversW, &hkey ))
806 DWORD count = sizeof(buffer);
807 RegQueryValueExW( hkey, graphicsW, 0, NULL, (LPBYTE)buffer, &count );
808 RegCloseKey( hkey );
811 else lstrcpynW( buffer, driver, sizeof(buffer)/sizeof(WCHAR) );
813 name = buffer;
814 while (name)
816 next = strchrW( name, ',' );
817 if (next) *next++ = 0;
819 snprintfW( libname, sizeof(libname)/sizeof(WCHAR), drv_formatW, name );
820 if ((module = LoadLibraryW( libname )) != 0) break;
821 switch (GetLastError())
823 case ERROR_MOD_NOT_FOUND:
824 strcpy( error, "The graphics driver is missing. Check your build!" );
825 break;
826 case ERROR_DLL_INIT_FAILED:
827 strcpy( error, "Make sure that your X server is running and that $DISPLAY is set correctly." );
828 break;
829 default:
830 sprintf( error, "Unknown error (%u).", GetLastError() );
831 break;
833 name = next;
836 if (module)
838 GetModuleFileNameW( module, buffer, MAX_PATH );
839 TRACE( "display %s driver %s\n", debugstr_guid(guid), debugstr_w(buffer) );
842 sprintfW( key, device_keyW, guid->Data1, guid->Data2, guid->Data3,
843 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
844 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
846 if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, key, 0, NULL,
847 REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL ))
849 if (module)
850 RegSetValueExW( hkey, graphics_driverW, 0, REG_SZ,
851 (BYTE *)buffer, (strlenW(buffer) + 1) * sizeof(WCHAR) );
852 else
853 RegSetValueExA( hkey, "DriverError", 0, REG_SZ, (BYTE *)error, strlen(error) + 1 );
854 RegCloseKey( hkey );
857 return module;
860 static void initialize_display_settings(void)
862 DEVMODEW dmW;
864 /* Store current display mode in the registry */
865 if (EnumDisplaySettingsExW( NULL, ENUM_CURRENT_SETTINGS, &dmW, 0 ))
867 WINE_TRACE( "Current display mode %ux%u %u bpp %u Hz\n", dmW.dmPelsWidth,
868 dmW.dmPelsHeight, dmW.dmBitsPerPel, dmW.dmDisplayFrequency );
869 ChangeDisplaySettingsExW( NULL, &dmW, 0,
870 CDS_GLOBAL | CDS_NORESET | CDS_UPDATEREGISTRY,
871 NULL );
875 static void set_desktop_window_title( HWND hwnd, const WCHAR *name )
877 static const WCHAR desktop_nameW[] = {'W','i','n','e',' ','d','e','s','k','t','o','p',0};
878 static const WCHAR desktop_name_separatorW[] = {' ', '-', ' ', 0};
879 WCHAR *window_titleW = NULL;
880 int window_title_len;
882 if (!name[0])
884 SetWindowTextW( hwnd, desktop_nameW );
885 return;
888 window_title_len = strlenW(name) * sizeof(WCHAR)
889 + sizeof(desktop_name_separatorW)
890 + sizeof(desktop_nameW);
891 window_titleW = HeapAlloc( GetProcessHeap(), 0, window_title_len );
892 if (!window_titleW)
894 SetWindowTextW( hwnd, desktop_nameW );
895 return;
898 strcpyW( window_titleW, name );
899 strcatW( window_titleW, desktop_name_separatorW );
900 strcatW( window_titleW, desktop_nameW );
902 SetWindowTextW( hwnd, window_titleW );
903 HeapFree( GetProcessHeap(), 0, window_titleW );
906 /* main desktop management function */
907 void manage_desktop( WCHAR *arg )
909 static const WCHAR messageW[] = {'M','e','s','s','a','g','e',0};
910 HDESK desktop = 0;
911 GUID guid;
912 MSG msg;
913 HWND hwnd;
914 HMODULE graphics_driver;
915 unsigned int width, height;
916 WCHAR *cmdline = NULL, *driver = NULL;
917 WCHAR *p = arg;
918 const WCHAR *name = NULL;
919 BOOL enable_shell = FALSE;
921 /* get the rest of the command line (if any) */
922 while (*p && !isspace(*p)) p++;
923 if (*p)
925 *p++ = 0;
926 while (*p && isspace(*p)) p++;
927 if (*p) cmdline = p;
930 /* parse the desktop option */
931 /* the option is of the form /desktop=name[,widthxheight[,driver]] */
932 if (*arg == '=' || *arg == ',')
934 arg++;
935 name = arg;
936 if ((p = strchrW( arg, ',' )))
938 *p++ = 0;
939 if ((driver = strchrW( p, ',' ))) *driver++ = 0;
941 if (!p || !parse_size( p, &width, &height ))
942 get_default_desktop_size( name, &width, &height );
944 else if ((name = get_default_desktop_name()))
946 if (!get_default_desktop_size( name, &width, &height )) width = height = 0;
949 if (name)
950 enable_shell = get_default_enable_shell( name );
952 if (name && width && height)
954 if (!(desktop = CreateDesktopW( name, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL )))
956 WINE_ERR( "failed to create desktop %s error %d\n", wine_dbgstr_w(name), GetLastError() );
957 ExitProcess( 1 );
959 SetThreadDesktop( desktop );
962 UuidCreate( &guid );
963 TRACE( "display guid %s\n", debugstr_guid(&guid) );
964 graphics_driver = load_graphics_driver( driver, &guid );
966 /* create the desktop window */
967 hwnd = CreateWindowExW( 0, DESKTOP_CLASS_ATOM, NULL,
968 WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 0, 0, 0, 0, 0, &guid );
970 if (hwnd)
972 /* create the HWND_MESSAGE parent */
973 CreateWindowExW( 0, messageW, NULL, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
974 0, 0, 100, 100, 0, 0, 0, NULL );
976 using_root = !desktop || !create_desktop( graphics_driver, name, width, height );
977 SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)desktop_wnd_proc );
978 SendMessageW( hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW( 0, MAKEINTRESOURCEW(OIC_WINLOGO)));
979 if (name) set_desktop_window_title( hwnd, name );
980 SetWindowPos( hwnd, 0, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN),
981 GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN),
982 SWP_SHOWWINDOW );
983 SystemParametersInfoW( SPI_SETDESKWALLPAPER, 0, NULL, FALSE );
984 ClipCursor( NULL );
985 initialize_display_settings();
986 initialize_appbar();
988 if (graphics_driver)
990 HMODULE shell32;
991 void (WINAPI *pShellDDEInit)( BOOL );
993 if (using_root) enable_shell = FALSE;
995 initialize_systray( graphics_driver, using_root, enable_shell );
996 if (!using_root) initialize_launchers( hwnd );
998 if ((shell32 = LoadLibraryA( "shell32.dll" )) &&
999 (pShellDDEInit = (void *)GetProcAddress( shell32, (LPCSTR)188)))
1001 pShellDDEInit( TRUE );
1006 /* if we have a command line, execute it */
1007 if (cmdline)
1009 STARTUPINFOW si;
1010 PROCESS_INFORMATION pi;
1012 memset( &si, 0, sizeof(si) );
1013 si.cb = sizeof(si);
1014 WINE_TRACE( "starting %s\n", wine_dbgstr_w(cmdline) );
1015 if (CreateProcessW( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ))
1017 CloseHandle( pi.hThread );
1018 CloseHandle( pi.hProcess );
1022 desktopshellbrowserwindow_init();
1023 shellwindows_init();
1025 /* run the desktop message loop */
1026 if (hwnd)
1028 WINE_TRACE( "desktop message loop starting on hwnd %p\n", hwnd );
1029 while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
1030 WINE_TRACE( "desktop message loop exiting for hwnd %p\n", hwnd );
1033 ExitProcess( 0 );
1036 /* IShellWindows implementation */
1037 static HRESULT WINAPI shellwindows_QueryInterface(IShellWindows *iface, REFIID riid, void **ppvObject)
1039 struct shellwindows *This = impl_from_IShellWindows(iface);
1041 TRACE("%s %p\n", debugstr_guid(riid), ppvObject);
1043 if (IsEqualGUID(riid, &IID_IShellWindows) ||
1044 IsEqualGUID(riid, &IID_IDispatch) ||
1045 IsEqualGUID(riid, &IID_IUnknown))
1047 *ppvObject = &This->IShellWindows_iface;
1049 else
1051 WARN("Unsupported interface %s\n", debugstr_guid(riid));
1052 *ppvObject = NULL;
1055 if (*ppvObject)
1057 IUnknown_AddRef((IUnknown*)*ppvObject);
1058 return S_OK;
1061 return E_NOINTERFACE;
1064 static ULONG WINAPI shellwindows_AddRef(IShellWindows *iface)
1066 return 2;
1069 static ULONG WINAPI shellwindows_Release(IShellWindows *iface)
1071 return 1;
1074 static HRESULT WINAPI shellwindows_GetTypeInfoCount(IShellWindows *iface, UINT *pctinfo)
1076 TRACE("%p\n", pctinfo);
1077 *pctinfo = 1;
1078 return S_OK;
1081 static HRESULT WINAPI shellwindows_GetTypeInfo(IShellWindows *iface,
1082 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1084 TRACE("%d %d %p\n", iTInfo, lcid, ppTInfo);
1085 return get_typeinfo(IShellWindows_tid, ppTInfo);
1088 static HRESULT WINAPI shellwindows_GetIDsOfNames(IShellWindows *iface,
1089 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
1090 DISPID *rgDispId)
1092 ITypeInfo *typeinfo;
1093 HRESULT hr;
1095 TRACE("%s %p %d %d %p\n", debugstr_guid(riid), rgszNames, cNames,
1096 lcid, rgDispId);
1098 if (!rgszNames || cNames == 0 || !rgDispId)
1099 return E_INVALIDARG;
1101 hr = get_typeinfo(IShellWindows_tid, &typeinfo);
1102 if (SUCCEEDED(hr))
1104 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1105 ITypeInfo_Release(typeinfo);
1108 return hr;
1111 static HRESULT WINAPI shellwindows_Invoke(IShellWindows *iface,
1112 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
1113 DISPPARAMS *pDispParams, VARIANT *pVarResult,
1114 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1116 ITypeInfo *typeinfo;
1117 HRESULT hr;
1119 TRACE("%d %s %d %08x %p %p %p %p\n", dispIdMember, debugstr_guid(riid),
1120 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1122 hr = get_typeinfo(IShellWindows_tid, &typeinfo);
1123 if (SUCCEEDED(hr))
1125 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
1126 pDispParams, pVarResult, pExcepInfo, puArgErr);
1127 ITypeInfo_Release(typeinfo);
1130 return hr;
1133 static HRESULT WINAPI shellwindows_get_Count(IShellWindows *iface, LONG *count)
1135 FIXME("%p\n", count);
1136 return E_NOTIMPL;
1139 static HRESULT WINAPI shellwindows_Item(IShellWindows *iface, VARIANT index,
1140 IDispatch **folder)
1142 FIXME("%s %p\n", debugstr_variant(&index), folder);
1143 return E_NOTIMPL;
1146 static HRESULT WINAPI shellwindows__NewEnum(IShellWindows *iface, IUnknown **ppunk)
1148 FIXME("%p\n", ppunk);
1149 return E_NOTIMPL;
1152 static HRESULT WINAPI shellwindows_Register(IShellWindows *iface,
1153 IDispatch *disp, LONG hWnd, int class, LONG *cookie)
1155 FIXME("%p 0x%x 0x%x %p\n", disp, hWnd, class, cookie);
1156 return E_NOTIMPL;
1159 static HRESULT WINAPI shellwindows_RegisterPending(IShellWindows *iface,
1160 LONG threadid, VARIANT *loc, VARIANT *root, int class, LONG *cookie)
1162 FIXME("0x%x %s %s 0x%x %p\n", threadid, debugstr_variant(loc), debugstr_variant(root),
1163 class, cookie);
1164 return E_NOTIMPL;
1167 static HRESULT WINAPI shellwindows_Revoke(IShellWindows *iface, LONG cookie)
1169 FIXME("0x%x\n", cookie);
1170 return E_NOTIMPL;
1173 static HRESULT WINAPI shellwindows_OnNavigate(IShellWindows *iface, LONG cookie, VARIANT *loc)
1175 FIXME("0x%x %s\n", cookie, debugstr_variant(loc));
1176 return E_NOTIMPL;
1179 static HRESULT WINAPI shellwindows_OnActivated(IShellWindows *iface, LONG cookie, VARIANT_BOOL active)
1181 FIXME("0x%x 0x%x\n", cookie, active);
1182 return E_NOTIMPL;
1185 static HRESULT WINAPI shellwindows_FindWindowSW(IShellWindows *iface, VARIANT *loc,
1186 VARIANT *root, int class, LONG *hwnd, int options, IDispatch **disp)
1188 TRACE("%s %s 0x%x %p 0x%x %p\n", debugstr_variant(loc), debugstr_variant(root),
1189 class, hwnd, options, disp);
1191 if (class != SWC_DESKTOP)
1193 WARN("only SWC_DESKTOP class supported.\n");
1194 return E_NOTIMPL;
1197 *hwnd = HandleToLong(GetDesktopWindow());
1198 if (options & SWFO_NEEDDISPATCH)
1200 *disp = (IDispatch*)&desktopshellbrowserwindow.IWebBrowser2_iface;
1201 IDispatch_AddRef(*disp);
1204 return S_OK;
1207 static HRESULT WINAPI shellwindows_OnCreated(IShellWindows *iface, LONG cookie, IUnknown *punk)
1209 FIXME("0x%x %p\n", cookie, punk);
1210 return E_NOTIMPL;
1213 static HRESULT WINAPI shellwindows_ProcessAttachDetach(IShellWindows *iface, VARIANT_BOOL attach)
1215 FIXME("0x%x\n", attach);
1216 return E_NOTIMPL;
1219 static const IShellWindowsVtbl shellwindowsvtbl =
1221 shellwindows_QueryInterface,
1222 shellwindows_AddRef,
1223 shellwindows_Release,
1224 shellwindows_GetTypeInfoCount,
1225 shellwindows_GetTypeInfo,
1226 shellwindows_GetIDsOfNames,
1227 shellwindows_Invoke,
1228 shellwindows_get_Count,
1229 shellwindows_Item,
1230 shellwindows__NewEnum,
1231 shellwindows_Register,
1232 shellwindows_RegisterPending,
1233 shellwindows_Revoke,
1234 shellwindows_OnNavigate,
1235 shellwindows_OnActivated,
1236 shellwindows_FindWindowSW,
1237 shellwindows_OnCreated,
1238 shellwindows_ProcessAttachDetach
1241 struct shellwindows_classfactory
1243 IClassFactory IClassFactory_iface;
1244 DWORD classreg;
1247 static inline struct shellwindows_classfactory *impl_from_IClassFactory(IClassFactory *iface)
1249 return CONTAINING_RECORD(iface, struct shellwindows_classfactory, IClassFactory_iface);
1252 static HRESULT WINAPI swclassfactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppvObject)
1254 struct shellwindows_classfactory *This = impl_from_IClassFactory(iface);
1256 TRACE("%s %p\n", debugstr_guid(riid), ppvObject);
1258 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IClassFactory))
1260 *ppvObject = &This->IClassFactory_iface;
1262 else
1264 WARN("Unsupported interface %s\n", debugstr_guid(riid));
1265 *ppvObject = NULL;
1268 if (*ppvObject)
1270 IUnknown_AddRef((IUnknown*)*ppvObject);
1271 return S_OK;
1274 return E_NOINTERFACE;
1277 static ULONG WINAPI swclassfactory_AddRef(IClassFactory *iface)
1279 return 2;
1282 static ULONG WINAPI swclassfactory_Release(IClassFactory *iface)
1284 return 1;
1287 static HRESULT WINAPI swclassfactory_CreateInstance(IClassFactory *iface,
1288 IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
1290 TRACE("%p %s %p\n", pUnkOuter, debugstr_guid(riid), ppvObject);
1291 return IShellWindows_QueryInterface(&shellwindows.IShellWindows_iface, riid, ppvObject);
1294 static HRESULT WINAPI swclassfactory_LockServer(IClassFactory *iface, BOOL lock)
1296 TRACE("%u\n", lock);
1297 return E_NOTIMPL;
1300 static const IClassFactoryVtbl swclassfactoryvtbl =
1302 swclassfactory_QueryInterface,
1303 swclassfactory_AddRef,
1304 swclassfactory_Release,
1305 swclassfactory_CreateInstance,
1306 swclassfactory_LockServer
1309 static struct shellwindows_classfactory shellwindows_classfactory = { { &swclassfactoryvtbl } };
1311 static HRESULT WINAPI webbrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid, void **ppv)
1313 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1315 *ppv = NULL;
1317 if (IsEqualGUID(&IID_IWebBrowser2, riid) ||
1318 IsEqualGUID(&IID_IWebBrowserApp, riid) ||
1319 IsEqualGUID(&IID_IWebBrowser, riid) ||
1320 IsEqualGUID(&IID_IDispatch, riid) ||
1321 IsEqualGUID(&IID_IUnknown, riid))
1323 *ppv = &This->IWebBrowser2_iface;
1325 else if (IsEqualGUID(&IID_IServiceProvider, riid))
1327 *ppv = &This->IServiceProvider_iface;
1330 if (*ppv)
1332 IUnknown_AddRef((IUnknown*)*ppv);
1333 return S_OK;
1336 FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
1337 return E_NOINTERFACE;
1340 static ULONG WINAPI webbrowser_AddRef(IWebBrowser2 *iface)
1342 return 2;
1345 static ULONG WINAPI webbrowser_Release(IWebBrowser2 *iface)
1347 return 1;
1350 /* IDispatch methods */
1351 static HRESULT WINAPI webbrowser_GetTypeInfoCount(IWebBrowser2 *iface, UINT *pctinfo)
1353 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1354 TRACE("(%p)->(%p)\n", This, pctinfo);
1355 *pctinfo = 1;
1356 return S_OK;
1359 static HRESULT WINAPI webbrowser_GetTypeInfo(IWebBrowser2 *iface, UINT iTInfo, LCID lcid,
1360 LPTYPEINFO *ppTInfo)
1362 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1363 TRACE("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
1364 return get_typeinfo(IWebBrowser2_tid, ppTInfo);
1367 static HRESULT WINAPI webbrowser_GetIDsOfNames(IWebBrowser2 *iface, REFIID riid,
1368 LPOLESTR *rgszNames, UINT cNames,
1369 LCID lcid, DISPID *rgDispId)
1371 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1372 ITypeInfo *typeinfo;
1373 HRESULT hr;
1375 TRACE("(%p)->(%s %p %d %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1376 lcid, rgDispId);
1378 if(!rgszNames || cNames == 0 || !rgDispId)
1379 return E_INVALIDARG;
1381 hr = get_typeinfo(IWebBrowser2_tid, &typeinfo);
1382 if (SUCCEEDED(hr))
1384 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1385 ITypeInfo_Release(typeinfo);
1388 return hr;
1391 static HRESULT WINAPI webbrowser_Invoke(IWebBrowser2 *iface, DISPID dispIdMember,
1392 REFIID riid, LCID lcid, WORD wFlags,
1393 DISPPARAMS *pDispParams, VARIANT *pVarResult,
1394 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1396 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1397 ITypeInfo *typeinfo;
1398 HRESULT hr;
1400 TRACE("(%p)->(%d %s %d %08x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1401 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1403 hr = get_typeinfo(IWebBrowser2_tid, &typeinfo);
1404 if (SUCCEEDED(hr))
1406 hr = ITypeInfo_Invoke(typeinfo, &This->IWebBrowser2_iface, dispIdMember, wFlags,
1407 pDispParams, pVarResult, pExcepInfo, puArgErr);
1408 ITypeInfo_Release(typeinfo);
1411 return hr;
1414 /* IWebBrowser methods */
1415 static HRESULT WINAPI webbrowser_GoBack(IWebBrowser2 *iface)
1417 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1418 FIXME("(%p): stub\n", This);
1419 return E_NOTIMPL;
1422 static HRESULT WINAPI webbrowser_GoForward(IWebBrowser2 *iface)
1424 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1425 FIXME("(%p): stub\n", This);
1426 return E_NOTIMPL;
1429 static HRESULT WINAPI webbrowser_GoHome(IWebBrowser2 *iface)
1431 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1432 FIXME("(%p): stub\n", This);
1433 return E_NOTIMPL;
1436 static HRESULT WINAPI webbrowser_GoSearch(IWebBrowser2 *iface)
1438 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1439 FIXME("(%p)\n", This);
1440 return E_NOTIMPL;
1443 static HRESULT WINAPI webbrowser_Navigate(IWebBrowser2 *iface, BSTR szUrl,
1444 VARIANT *Flags, VARIANT *TargetFrameName,
1445 VARIANT *PostData, VARIANT *Headers)
1447 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1448 FIXME("(%p)->(%s %s %s %s %s): stub\n", This, debugstr_w(szUrl), debugstr_variant(Flags),
1449 debugstr_variant(TargetFrameName), debugstr_variant(PostData),
1450 debugstr_variant(Headers));
1451 return E_NOTIMPL;
1454 static HRESULT WINAPI webbrowser_Refresh(IWebBrowser2 *iface)
1456 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1457 FIXME("(%p): stub\n", This);
1458 return E_NOTIMPL;
1461 static HRESULT WINAPI webbrowser_Refresh2(IWebBrowser2 *iface, VARIANT *Level)
1463 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1464 FIXME("(%p)->(%s): stub\n", This, debugstr_variant(Level));
1465 return E_NOTIMPL;
1468 static HRESULT WINAPI webbrowser_Stop(IWebBrowser2 *iface)
1470 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1471 FIXME("(%p): stub\n", This);
1472 return E_NOTIMPL;
1475 static HRESULT WINAPI webbrowser_get_Application(IWebBrowser2 *iface, IDispatch **ppDisp)
1477 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1479 TRACE("(%p)->(%p)\n", This, ppDisp);
1481 *ppDisp = (IDispatch*)iface;
1482 IDispatch_AddRef(*ppDisp);
1484 return S_OK;
1487 static HRESULT WINAPI webbrowser_get_Parent(IWebBrowser2 *iface, IDispatch **ppDisp)
1489 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1490 FIXME("(%p)->(%p)\n", This, ppDisp);
1491 return E_NOTIMPL;
1494 static HRESULT WINAPI webbrowser_get_Container(IWebBrowser2 *iface, IDispatch **ppDisp)
1496 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1497 FIXME("(%p)->(%p)\n", This, ppDisp);
1498 return E_NOTIMPL;
1501 static HRESULT WINAPI webbrowser_get_Document(IWebBrowser2 *iface, IDispatch **ppDisp)
1503 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1504 FIXME("(%p)->(%p)\n", This, ppDisp);
1505 return E_NOTIMPL;
1508 static HRESULT WINAPI webbrowser_get_TopLevelContainer(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
1510 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1511 FIXME("(%p)->(%p)\n", This, pBool);
1512 return E_NOTIMPL;
1515 static HRESULT WINAPI webbrowser_get_Type(IWebBrowser2 *iface, BSTR *Type)
1517 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1518 FIXME("(%p)->(%p)\n", This, Type);
1519 return E_NOTIMPL;
1522 static HRESULT WINAPI webbrowser_get_Left(IWebBrowser2 *iface, LONG *pl)
1524 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1525 FIXME("(%p)->(%p)\n", This, pl);
1526 return E_NOTIMPL;
1529 static HRESULT WINAPI webbrowser_put_Left(IWebBrowser2 *iface, LONG Left)
1531 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1532 FIXME("(%p)->(%d)\n", This, Left);
1533 return E_NOTIMPL;
1536 static HRESULT WINAPI webbrowser_get_Top(IWebBrowser2 *iface, LONG *pl)
1538 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1539 FIXME("(%p)->(%p)\n", This, pl);
1540 return E_NOTIMPL;
1543 static HRESULT WINAPI webbrowser_put_Top(IWebBrowser2 *iface, LONG Top)
1545 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1546 FIXME("(%p)->(%d)\n", This, Top);
1547 return E_NOTIMPL;
1550 static HRESULT WINAPI webbrowser_get_Width(IWebBrowser2 *iface, LONG *pl)
1552 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1553 FIXME("(%p)->(%p)\n", This, pl);
1554 return E_NOTIMPL;
1557 static HRESULT WINAPI webbrowser_put_Width(IWebBrowser2 *iface, LONG Width)
1559 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1560 FIXME("(%p)->(%d)\n", This, Width);
1561 return E_NOTIMPL;
1564 static HRESULT WINAPI webbrowser_get_Height(IWebBrowser2 *iface, LONG *pl)
1566 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1567 FIXME("(%p)->(%p)\n", This, pl);
1568 return E_NOTIMPL;
1571 static HRESULT WINAPI webbrowser_put_Height(IWebBrowser2 *iface, LONG Height)
1573 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1574 FIXME("(%p)->(%d)\n", This, Height);
1575 return E_NOTIMPL;
1578 static HRESULT WINAPI webbrowser_get_LocationName(IWebBrowser2 *iface, BSTR *LocationName)
1580 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1581 FIXME("(%p)->(%p)\n", This, LocationName);
1582 return E_NOTIMPL;
1585 static HRESULT WINAPI webbrowser_get_LocationURL(IWebBrowser2 *iface, BSTR *LocationURL)
1587 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1588 FIXME("(%p)->(%p)\n", This, LocationURL);
1589 return E_NOTIMPL;
1592 static HRESULT WINAPI webbrowser_get_Busy(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
1594 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1595 FIXME("(%p)->(%p)\n", This, pBool);
1596 return E_NOTIMPL;
1599 static HRESULT WINAPI webbrowser_Quit(IWebBrowser2 *iface)
1601 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1602 FIXME("(%p)\n", This);
1603 return E_NOTIMPL;
1606 static HRESULT WINAPI webbrowser_ClientToWindow(IWebBrowser2 *iface, int *pcx, int *pcy)
1608 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1609 FIXME("(%p)->(%p %p)\n", This, pcx, pcy);
1610 return E_NOTIMPL;
1613 static HRESULT WINAPI webbrowser_PutProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT vtValue)
1615 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1616 FIXME("(%p)->(%s %s)\n", This, debugstr_w(szProperty), debugstr_variant(&vtValue));
1617 return E_NOTIMPL;
1620 static HRESULT WINAPI webbrowser_GetProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT *pvtValue)
1622 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1623 FIXME("(%p)->(%s %s)\n", This, debugstr_w(szProperty), debugstr_variant(pvtValue));
1624 return E_NOTIMPL;
1627 static HRESULT WINAPI webbrowser_get_Name(IWebBrowser2 *iface, BSTR *Name)
1629 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1630 FIXME("(%p)->(%p)\n", This, Name);
1631 return E_NOTIMPL;
1634 static HRESULT WINAPI webbrowser_get_HWND(IWebBrowser2 *iface, SHANDLE_PTR *pHWND)
1636 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1637 FIXME("(%p)->(%p)\n", This, pHWND);
1638 return E_NOTIMPL;
1641 static HRESULT WINAPI webbrowser_get_FullName(IWebBrowser2 *iface, BSTR *FullName)
1643 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1644 FIXME("(%p)->(%p)\n", This, FullName);
1645 return E_NOTIMPL;
1648 static HRESULT WINAPI webbrowser_get_Path(IWebBrowser2 *iface, BSTR *Path)
1650 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1651 FIXME("(%p)->(%p)\n", This, Path);
1652 return E_NOTIMPL;
1655 static HRESULT WINAPI webbrowser_get_Visible(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
1657 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1658 FIXME("(%p)->(%p)\n", This, pBool);
1659 return E_NOTIMPL;
1662 static HRESULT WINAPI webbrowser_put_Visible(IWebBrowser2 *iface, VARIANT_BOOL Value)
1664 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1665 FIXME("(%p)->(%x)\n", This, Value);
1666 return E_NOTIMPL;
1669 static HRESULT WINAPI webbrowser_get_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
1671 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1672 FIXME("(%p)->(%p)\n", This, pBool);
1673 return E_NOTIMPL;
1676 static HRESULT WINAPI webbrowser_put_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
1678 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1679 FIXME("(%p)->(%x)\n", This, Value);
1680 return E_NOTIMPL;
1683 static HRESULT WINAPI webbrowser_get_StatusText(IWebBrowser2 *iface, BSTR *StatusText)
1685 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1686 FIXME("(%p)->(%p)\n", This, StatusText);
1687 return E_NOTIMPL;
1690 static HRESULT WINAPI webbrowser_put_StatusText(IWebBrowser2 *iface, BSTR StatusText)
1692 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1693 FIXME("(%p)->(%s)\n", This, debugstr_w(StatusText));
1694 return E_NOTIMPL;
1697 static HRESULT WINAPI webbrowser_get_ToolBar(IWebBrowser2 *iface, int *Value)
1699 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1700 FIXME("(%p)->(%p)\n", This, Value);
1701 return E_NOTIMPL;
1704 static HRESULT WINAPI webbrowser_put_ToolBar(IWebBrowser2 *iface, int Value)
1706 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1707 FIXME("(%p)->(%x)\n", This, Value);
1708 return E_NOTIMPL;
1711 static HRESULT WINAPI webbrowser_get_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
1713 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1714 FIXME("(%p)->(%p)\n", This, Value);
1715 return E_NOTIMPL;
1718 static HRESULT WINAPI webbrowser_put_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
1720 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1721 FIXME("(%p)->(%x)\n", This, Value);
1722 return E_NOTIMPL;
1725 static HRESULT WINAPI webbrowser_get_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL *pbFullScreen)
1727 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1728 FIXME("(%p)->(%p)\n", This, pbFullScreen);
1729 return E_NOTIMPL;
1732 static HRESULT WINAPI webbrowser_put_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL bFullScreen)
1734 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1735 FIXME("(%p)->(%x)\n", This, bFullScreen);
1736 return E_NOTIMPL;
1739 static HRESULT WINAPI webbrowser_Navigate2(IWebBrowser2 *iface, VARIANT *URL, VARIANT *Flags,
1740 VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
1742 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1743 FIXME("(%p)->(%s %s %s %s %s)\n", This, debugstr_variant(URL), debugstr_variant(Flags),
1744 debugstr_variant(TargetFrameName), debugstr_variant(PostData), debugstr_variant(Headers));
1745 return E_NOTIMPL;
1748 static HRESULT WINAPI webbrowser_QueryStatusWB(IWebBrowser2 *iface, OLECMDID cmdID, OLECMDF *pcmdf)
1750 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1751 FIXME("(%p)->(%d %p)\n", This, cmdID, pcmdf);
1752 return E_NOTIMPL;
1755 static HRESULT WINAPI webbrowser_ExecWB(IWebBrowser2 *iface, OLECMDID cmdID,
1756 OLECMDEXECOPT cmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1758 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1759 FIXME("(%p)->(%d %d %s %p)\n", This, cmdID, cmdexecopt, debugstr_variant(pvaIn), pvaOut);
1760 return E_NOTIMPL;
1763 static HRESULT WINAPI webbrowser_ShowBrowserBar(IWebBrowser2 *iface, VARIANT *pvaClsid,
1764 VARIANT *pvarShow, VARIANT *pvarSize)
1766 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1767 FIXME("(%p)->(%s %s %s)\n", This, debugstr_variant(pvaClsid), debugstr_variant(pvarShow),
1768 debugstr_variant(pvarSize));
1769 return E_NOTIMPL;
1772 static HRESULT WINAPI webbrowser_get_ReadyState(IWebBrowser2 *iface, READYSTATE *lpReadyState)
1774 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1775 FIXME("(%p)->(%p)\n", This, lpReadyState);
1776 return E_NOTIMPL;
1779 static HRESULT WINAPI webbrowser_get_Offline(IWebBrowser2 *iface, VARIANT_BOOL *pbOffline)
1781 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1782 FIXME("(%p)->(%p)\n", This, pbOffline);
1783 return E_NOTIMPL;
1786 static HRESULT WINAPI webbrowser_put_Offline(IWebBrowser2 *iface, VARIANT_BOOL bOffline)
1788 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1789 FIXME("(%p)->(%x)\n", This, bOffline);
1790 return E_NOTIMPL;
1793 static HRESULT WINAPI webbrowser_get_Silent(IWebBrowser2 *iface, VARIANT_BOOL *pbSilent)
1795 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1796 FIXME("(%p)->(%p)\n", This, pbSilent);
1797 return E_NOTIMPL;
1800 static HRESULT WINAPI webbrowser_put_Silent(IWebBrowser2 *iface, VARIANT_BOOL bSilent)
1802 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1803 FIXME("(%p)->(%x)\n", This, bSilent);
1804 return E_NOTIMPL;
1807 static HRESULT WINAPI webbrowser_get_RegisterAsBrowser(IWebBrowser2 *iface,
1808 VARIANT_BOOL *pbRegister)
1810 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1811 FIXME("(%p)->(%p)\n", This, pbRegister);
1812 return E_NOTIMPL;
1815 static HRESULT WINAPI webbrowser_put_RegisterAsBrowser(IWebBrowser2 *iface,
1816 VARIANT_BOOL bRegister)
1818 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1819 FIXME("(%p)->(%x)\n", This, bRegister);
1820 return E_NOTIMPL;
1823 static HRESULT WINAPI webbrowser_get_RegisterAsDropTarget(IWebBrowser2 *iface,
1824 VARIANT_BOOL *pbRegister)
1826 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1827 FIXME("(%p)->(%p)\n", This, pbRegister);
1828 return E_NOTIMPL;
1831 static HRESULT WINAPI webbrowser_put_RegisterAsDropTarget(IWebBrowser2 *iface,
1832 VARIANT_BOOL bRegister)
1834 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1835 FIXME("(%p)->(%x)\n", This, bRegister);
1836 return E_NOTIMPL;
1839 static HRESULT WINAPI webbrowser_get_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL *pbRegister)
1841 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1842 FIXME("(%p)->(%p)\n", This, pbRegister);
1843 return E_NOTIMPL;
1846 static HRESULT WINAPI webbrowser_put_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL bRegister)
1848 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1849 TRACE("(%p)->(%x)\n", This, bRegister);
1850 return E_NOTIMPL;
1853 static HRESULT WINAPI webbrowser_get_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
1855 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1856 FIXME("(%p)->(%p)\n", This, Value);
1857 return E_NOTIMPL;
1860 static HRESULT WINAPI webbrowser_put_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
1862 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1863 FIXME("(%p)->(%x)\n", This, Value);
1864 return E_NOTIMPL;
1867 static HRESULT WINAPI webbrowser_get_Resizable(IWebBrowser2 *iface, VARIANT_BOOL *Value)
1869 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1870 FIXME("(%p)->(%p)\n", This, Value);
1871 return E_NOTIMPL;
1874 static HRESULT WINAPI webbrowser_put_Resizable(IWebBrowser2 *iface, VARIANT_BOOL Value)
1876 struct shellbrowserwindow *This = impl_from_IWebBrowser2(iface);
1877 FIXME("(%p)->(%x)\n", This, Value);
1878 return E_NOTIMPL;
1881 static const IWebBrowser2Vtbl webbrowser2vtbl =
1883 webbrowser_QueryInterface,
1884 webbrowser_AddRef,
1885 webbrowser_Release,
1886 webbrowser_GetTypeInfoCount,
1887 webbrowser_GetTypeInfo,
1888 webbrowser_GetIDsOfNames,
1889 webbrowser_Invoke,
1890 webbrowser_GoBack,
1891 webbrowser_GoForward,
1892 webbrowser_GoHome,
1893 webbrowser_GoSearch,
1894 webbrowser_Navigate,
1895 webbrowser_Refresh,
1896 webbrowser_Refresh2,
1897 webbrowser_Stop,
1898 webbrowser_get_Application,
1899 webbrowser_get_Parent,
1900 webbrowser_get_Container,
1901 webbrowser_get_Document,
1902 webbrowser_get_TopLevelContainer,
1903 webbrowser_get_Type,
1904 webbrowser_get_Left,
1905 webbrowser_put_Left,
1906 webbrowser_get_Top,
1907 webbrowser_put_Top,
1908 webbrowser_get_Width,
1909 webbrowser_put_Width,
1910 webbrowser_get_Height,
1911 webbrowser_put_Height,
1912 webbrowser_get_LocationName,
1913 webbrowser_get_LocationURL,
1914 webbrowser_get_Busy,
1915 webbrowser_Quit,
1916 webbrowser_ClientToWindow,
1917 webbrowser_PutProperty,
1918 webbrowser_GetProperty,
1919 webbrowser_get_Name,
1920 webbrowser_get_HWND,
1921 webbrowser_get_FullName,
1922 webbrowser_get_Path,
1923 webbrowser_get_Visible,
1924 webbrowser_put_Visible,
1925 webbrowser_get_StatusBar,
1926 webbrowser_put_StatusBar,
1927 webbrowser_get_StatusText,
1928 webbrowser_put_StatusText,
1929 webbrowser_get_ToolBar,
1930 webbrowser_put_ToolBar,
1931 webbrowser_get_MenuBar,
1932 webbrowser_put_MenuBar,
1933 webbrowser_get_FullScreen,
1934 webbrowser_put_FullScreen,
1935 webbrowser_Navigate2,
1936 webbrowser_QueryStatusWB,
1937 webbrowser_ExecWB,
1938 webbrowser_ShowBrowserBar,
1939 webbrowser_get_ReadyState,
1940 webbrowser_get_Offline,
1941 webbrowser_put_Offline,
1942 webbrowser_get_Silent,
1943 webbrowser_put_Silent,
1944 webbrowser_get_RegisterAsBrowser,
1945 webbrowser_put_RegisterAsBrowser,
1946 webbrowser_get_RegisterAsDropTarget,
1947 webbrowser_put_RegisterAsDropTarget,
1948 webbrowser_get_TheaterMode,
1949 webbrowser_put_TheaterMode,
1950 webbrowser_get_AddressBar,
1951 webbrowser_put_AddressBar,
1952 webbrowser_get_Resizable,
1953 webbrowser_put_Resizable
1956 static HRESULT WINAPI serviceprovider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
1958 struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
1959 return IWebBrowser2_QueryInterface(&This->IWebBrowser2_iface, riid, ppv);
1962 static ULONG WINAPI serviceprovider_AddRef(IServiceProvider *iface)
1964 struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
1965 return IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
1968 static ULONG WINAPI serviceprovider_Release(IServiceProvider *iface)
1970 struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
1971 return IWebBrowser2_Release(&This->IWebBrowser2_iface);
1974 static HRESULT WINAPI serviceprovider_QueryService(IServiceProvider *iface, REFGUID service,
1975 REFIID riid, void **ppv)
1977 struct shellbrowserwindow *This = impl_from_IServiceProvider(iface);
1979 TRACE("%s %s %p\n", debugstr_guid(service), debugstr_guid(riid), ppv);
1981 if (IsEqualGUID(service, &SID_STopLevelBrowser))
1982 return IShellBrowser_QueryInterface(&This->IShellBrowser_iface, riid, ppv);
1984 WARN("unknown service id %s\n", debugstr_guid(service));
1985 return E_NOTIMPL;
1988 static const IServiceProviderVtbl serviceprovidervtbl =
1990 serviceprovider_QueryInterface,
1991 serviceprovider_AddRef,
1992 serviceprovider_Release,
1993 serviceprovider_QueryService
1996 /* IShellBrowser */
1997 static HRESULT WINAPI shellbrowser_QueryInterface(IShellBrowser *iface, REFIID riid, void **ppv)
1999 TRACE("%s %p\n", debugstr_guid(riid), ppv);
2001 *ppv = NULL;
2003 if (IsEqualGUID(&IID_IShellBrowser, riid) ||
2004 IsEqualGUID(&IID_IOleWindow, riid) ||
2005 IsEqualGUID(&IID_IUnknown, riid))
2007 *ppv = iface;
2010 if (*ppv)
2012 IUnknown_AddRef((IUnknown*)*ppv);
2013 return S_OK;
2016 return E_NOINTERFACE;
2019 static ULONG WINAPI shellbrowser_AddRef(IShellBrowser *iface)
2021 struct shellbrowserwindow *This = impl_from_IShellBrowser(iface);
2022 return IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
2025 static ULONG WINAPI shellbrowser_Release(IShellBrowser *iface)
2027 struct shellbrowserwindow *This = impl_from_IShellBrowser(iface);
2028 return IWebBrowser2_Release(&This->IWebBrowser2_iface);
2031 static HRESULT WINAPI shellbrowser_GetWindow(IShellBrowser *iface, HWND *phwnd)
2033 FIXME("%p\n", phwnd);
2034 return E_NOTIMPL;
2037 static HRESULT WINAPI shellbrowser_ContextSensitiveHelp(IShellBrowser *iface, BOOL mode)
2039 FIXME("%d\n", mode);
2040 return E_NOTIMPL;
2043 static HRESULT WINAPI shellbrowser_InsertMenusSB(IShellBrowser *iface, HMENU hmenuShared,
2044 OLEMENUGROUPWIDTHS *menuwidths)
2046 FIXME("%p %p\n", hmenuShared, menuwidths);
2047 return E_NOTIMPL;
2050 static HRESULT WINAPI shellbrowser_SetMenuSB(IShellBrowser *iface, HMENU hmenuShared,
2051 HOLEMENU holemenuReserved, HWND hwndActiveObject)
2053 FIXME("%p %p %p\n", hmenuShared, holemenuReserved, hwndActiveObject);
2054 return E_NOTIMPL;
2057 static HRESULT WINAPI shellbrowser_RemoveMenusSB(IShellBrowser *iface, HMENU hmenuShared)
2059 FIXME("%p\n", hmenuShared);
2060 return E_NOTIMPL;
2063 static HRESULT WINAPI shellbrowser_SetStatusTextSB(IShellBrowser *iface, LPCOLESTR text)
2065 FIXME("%s\n", debugstr_w(text));
2066 return E_NOTIMPL;
2069 static HRESULT WINAPI shellbrowser_EnableModelessSB(IShellBrowser *iface, BOOL enable)
2071 FIXME("%d\n", enable);
2072 return E_NOTIMPL;
2075 static HRESULT WINAPI shellbrowser_TranslateAcceleratorSB(IShellBrowser *iface, MSG *pmsg, WORD wID)
2077 FIXME("%p 0x%x\n", pmsg, wID);
2078 return E_NOTIMPL;
2081 static HRESULT WINAPI shellbrowser_BrowseObject(IShellBrowser *iface, LPCITEMIDLIST pidl, UINT flags)
2083 FIXME("%p %x\n", pidl, flags);
2084 return E_NOTIMPL;
2087 static HRESULT WINAPI shellbrowser_GetViewStateStream(IShellBrowser *iface, DWORD mode, IStream **stream)
2089 FIXME("0x%x %p\n", mode, stream);
2090 return E_NOTIMPL;
2093 static HRESULT WINAPI shellbrowser_GetControlWindow(IShellBrowser *iface, UINT id, HWND *phwnd)
2095 FIXME("%d %p\n", id, phwnd);
2096 return E_NOTIMPL;
2099 static HRESULT WINAPI shellbrowser_SendControlMsg(IShellBrowser *iface, UINT id, UINT uMsg,
2100 WPARAM wParam, LPARAM lParam, LRESULT *pret)
2102 FIXME("%d %d %lx %lx %p\n", id, uMsg, wParam, lParam, pret);
2103 return E_NOTIMPL;
2106 static HRESULT WINAPI shellbrowser_QueryActiveShellView(IShellBrowser *iface, IShellView **view)
2108 TRACE("%p\n", view);
2110 *view = desktopshellbrowserwindow.view;
2111 IShellView_AddRef(*view);
2112 return S_OK;
2115 static HRESULT WINAPI shellbrowser_OnViewWindowActive(IShellBrowser *iface, IShellView *view)
2117 FIXME("%p\n", view);
2118 return E_NOTIMPL;
2121 static HRESULT WINAPI shellbrowser_SetToolbarItems(IShellBrowser *iface, LPTBBUTTONSB buttons,
2122 UINT count, UINT flags)
2124 FIXME("%p %d 0x%x\n", buttons, count, flags);
2125 return E_NOTIMPL;
2128 static const IShellBrowserVtbl shellbrowservtbl = {
2129 shellbrowser_QueryInterface,
2130 shellbrowser_AddRef,
2131 shellbrowser_Release,
2132 shellbrowser_GetWindow,
2133 shellbrowser_ContextSensitiveHelp,
2134 shellbrowser_InsertMenusSB,
2135 shellbrowser_SetMenuSB,
2136 shellbrowser_RemoveMenusSB,
2137 shellbrowser_SetStatusTextSB,
2138 shellbrowser_EnableModelessSB,
2139 shellbrowser_TranslateAcceleratorSB,
2140 shellbrowser_BrowseObject,
2141 shellbrowser_GetViewStateStream,
2142 shellbrowser_GetControlWindow,
2143 shellbrowser_SendControlMsg,
2144 shellbrowser_QueryActiveShellView,
2145 shellbrowser_OnViewWindowActive,
2146 shellbrowser_SetToolbarItems
2149 static void desktopshellbrowserwindow_init(void)
2151 IShellFolder *folder;
2153 desktopshellbrowserwindow.IWebBrowser2_iface.lpVtbl = &webbrowser2vtbl;
2154 desktopshellbrowserwindow.IServiceProvider_iface.lpVtbl = &serviceprovidervtbl;
2155 desktopshellbrowserwindow.IShellBrowser_iface.lpVtbl = &shellbrowservtbl;
2157 if (FAILED(SHGetDesktopFolder(&folder)))
2158 return;
2160 IShellFolder_CreateViewObject(folder, NULL, &IID_IShellView, (void**)&desktopshellbrowserwindow.view);
2163 static void shellwindows_init(void)
2165 HRESULT hr;
2167 CoInitialize(NULL);
2169 shellwindows.IShellWindows_iface.lpVtbl = &shellwindowsvtbl;
2171 hr = CoRegisterClassObject(&CLSID_ShellWindows,
2172 (IUnknown*)&shellwindows_classfactory.IClassFactory_iface,
2173 CLSCTX_LOCAL_SERVER,
2174 REGCLS_MULTIPLEUSE,
2175 &shellwindows_classfactory.classreg);
2177 if (FAILED(hr))
2178 WARN("Failed to register ShellWindows object: %08x\n", hr);