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
33 #include "wine/debug.h"
34 #include "explorer_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(explorer
);
38 #define DESKTOP_CLASS_ATOM ((LPCWSTR)MAKEINTATOM(32769))
39 #define DESKTOP_ALL_ACCESS 0x01ff
41 static const WCHAR default_driver
[] = {'m','a','c',',','x','1','1',0};
43 static BOOL using_root
= TRUE
;
52 static WCHAR
*desktop_folder
;
53 static WCHAR
*desktop_folder_public
;
55 static int icon_cx
, icon_cy
, icon_offset_cx
, icon_offset_cy
;
56 static int title_cx
, title_cy
, title_offset_cx
, title_offset_cy
;
57 static int desktop_width
, launcher_size
, launchers_per_row
;
59 static struct launcher
**launchers
;
60 static unsigned int nb_launchers
, nb_allocated
;
62 static REFIID tid_ids
[] =
75 static ITypeLib
*typelib
;
76 static ITypeInfo
*typeinfos
[LAST_tid
];
78 static HRESULT
load_typelib(void)
83 hres
= LoadRegTypeLib(&LIBID_SHDocVw
, 1, 0, LOCALE_SYSTEM_DEFAULT
, &tl
);
86 ERR("LoadRegTypeLib failed: %08lx\n", hres
);
90 if (InterlockedCompareExchangePointer((void**)&typelib
, tl
, NULL
))
95 static HRESULT
get_typeinfo(tid_t tid
, ITypeInfo
**typeinfo
)
100 hres
= load_typelib();
105 if (!typeinfos
[tid
]) {
108 hres
= ITypeLib_GetTypeInfoOfGuid(typelib
, tid_ids
[tid
], &ti
);
110 ERR("GetTypeInfoOfGuid(%s) failed: %08lx\n", debugstr_guid(tid_ids
[tid
]), hres
);
114 if (InterlockedCompareExchangePointer((void**)(typeinfos
+tid
), ti
, NULL
))
115 ITypeInfo_Release(ti
);
118 *typeinfo
= typeinfos
[tid
];
119 ITypeInfo_AddRef(*typeinfo
);
123 static BOOL
array_reserve(void **elements
, unsigned int *capacity
, unsigned int count
, unsigned int size
)
125 unsigned int new_capacity
, max_capacity
;
128 if (count
<= *capacity
)
131 max_capacity
= ~(SIZE_T
)0 / size
;
132 if (count
> max_capacity
)
135 new_capacity
= max(4, *capacity
);
136 while (new_capacity
< count
&& new_capacity
<= max_capacity
/ 2)
138 if (new_capacity
< count
)
139 new_capacity
= max_capacity
;
141 if (!(new_elements
= realloc(*elements
, new_capacity
* size
)))
144 *elements
= new_elements
;
145 *capacity
= new_capacity
;
150 static LONG cookie_counter
;
161 IShellWindows IShellWindows_iface
;
164 unsigned int count
, max
;
165 struct window
*windows
;
168 /* This is not limited to desktop itself, every file browser window that
169 explorer creates supports that. Desktop instance is special in some
170 aspects, for example navigation is not possible, you can't show/hide it,
171 or bring up a menu. CLSID_ShellBrowserWindow class could be used to
172 create instances like that, and they should be registered with
173 IShellWindows as well. */
174 struct shellbrowserwindow
176 IWebBrowser2 IWebBrowser2_iface
;
177 IServiceProvider IServiceProvider_iface
;
178 IShellBrowser IShellBrowser_iface
;
182 static struct shellwindows shellwindows
;
183 static struct shellbrowserwindow desktopshellbrowserwindow
;
185 static inline struct shellwindows
*impl_from_IShellWindows(IShellWindows
*iface
)
187 return CONTAINING_RECORD(iface
, struct shellwindows
, IShellWindows_iface
);
190 static inline struct shellbrowserwindow
*impl_from_IWebBrowser2(IWebBrowser2
*iface
)
192 return CONTAINING_RECORD(iface
, struct shellbrowserwindow
, IWebBrowser2_iface
);
195 static inline struct shellbrowserwindow
*impl_from_IServiceProvider(IServiceProvider
*iface
)
197 return CONTAINING_RECORD(iface
, struct shellbrowserwindow
, IServiceProvider_iface
);
200 static inline struct shellbrowserwindow
*impl_from_IShellBrowser(IShellBrowser
*iface
)
202 return CONTAINING_RECORD(iface
, struct shellbrowserwindow
, IShellBrowser_iface
);
205 static void shellwindows_init(void);
206 static void desktopshellbrowserwindow_init(void);
208 static RECT
get_icon_rect( unsigned int index
)
211 unsigned int row
= index
/ launchers_per_row
;
212 unsigned int col
= index
% launchers_per_row
;
214 rect
.left
= col
* launcher_size
+ icon_offset_cx
;
215 rect
.right
= rect
.left
+ icon_cx
;
216 rect
.top
= row
* launcher_size
+ icon_offset_cy
;
217 rect
.bottom
= rect
.top
+ icon_cy
;
221 static RECT
get_title_rect( unsigned int index
)
224 unsigned int row
= index
/ launchers_per_row
;
225 unsigned int col
= index
% launchers_per_row
;
227 rect
.left
= col
* launcher_size
+ title_offset_cx
;
228 rect
.right
= rect
.left
+ title_cx
;
229 rect
.top
= row
* launcher_size
+ title_offset_cy
;
230 rect
.bottom
= rect
.top
+ title_cy
;
234 static const struct launcher
*launcher_from_point( int x
, int y
)
239 if (!nb_launchers
) return NULL
;
240 index
= x
/ launcher_size
+ (y
/ launcher_size
) * launchers_per_row
;
241 if (index
>= nb_launchers
) return NULL
;
243 icon
= get_icon_rect( index
);
244 title
= get_title_rect( index
);
245 if ((x
< icon
.left
|| x
> icon
.right
|| y
< icon
.top
|| y
> icon
.bottom
) &&
246 (x
< title
.left
|| x
> title
.right
|| y
< title
.top
|| y
> title
.bottom
)) return NULL
;
247 return launchers
[index
];
250 static void draw_launchers( HDC hdc
, RECT update_rect
)
252 COLORREF color
= SetTextColor( hdc
, RGB(255,255,255) ); /* FIXME: depends on background color */
253 int mode
= SetBkMode( hdc
, TRANSPARENT
);
258 SystemParametersInfoW( SPI_GETICONTITLELOGFONT
, sizeof(lf
), &lf
, 0 );
259 font
= SelectObject( hdc
, CreateFontIndirectW( &lf
) );
261 for (i
= 0; i
< nb_launchers
; i
++)
263 RECT dummy
, icon
= get_icon_rect( i
), title
= get_title_rect( i
);
265 if (IntersectRect( &dummy
, &icon
, &update_rect
))
266 DrawIconEx( hdc
, icon
.left
, icon
.top
, launchers
[i
]->icon
, icon_cx
, icon_cy
,
267 0, 0, DI_DEFAULTSIZE
|DI_NORMAL
);
269 if (IntersectRect( &dummy
, &title
, &update_rect
))
270 DrawTextW( hdc
, launchers
[i
]->title
, -1, &title
,
271 DT_CENTER
|DT_WORDBREAK
|DT_EDITCONTROL
|DT_END_ELLIPSIS
);
274 font
= SelectObject( hdc
, font
);
275 DeleteObject( font
);
276 SetTextColor( hdc
, color
);
277 SetBkMode( hdc
, mode
);
280 static WCHAR
*append_path( const WCHAR
*path
, const WCHAR
*filename
, int len_filename
)
282 int len_path
= lstrlenW( path
);
285 if (len_filename
== -1) len_filename
= lstrlenW( filename
);
286 if (!(ret
= malloc( (len_path
+ len_filename
+ 2) * sizeof(WCHAR
) ))) return NULL
;
287 memcpy( ret
, path
, len_path
* sizeof(WCHAR
) );
288 ret
[len_path
] = '\\';
289 memcpy( ret
+ len_path
+ 1, filename
, len_filename
* sizeof(WCHAR
) );
290 ret
[len_path
+ 1 + len_filename
] = 0;
294 static IShellLinkW
*load_shelllink( const WCHAR
*path
)
300 hr
= CoCreateInstance( &CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IShellLinkW
,
302 if (FAILED( hr
)) return NULL
;
304 hr
= IShellLinkW_QueryInterface( link
, &IID_IPersistFile
, (void **)&file
);
307 IShellLinkW_Release( link
);
310 hr
= IPersistFile_Load( file
, path
, 0 );
311 IPersistFile_Release( file
);
314 IShellLinkW_Release( link
);
320 static HICON
extract_icon( IShellLinkW
*link
)
322 WCHAR tmp_path
[MAX_PATH
], icon_path
[MAX_PATH
], target_path
[MAX_PATH
];
327 IShellLinkW_GetIconLocation( link
, tmp_path
, MAX_PATH
, &index
);
328 ExpandEnvironmentStringsW( tmp_path
, icon_path
, MAX_PATH
);
330 if (icon_path
[0]) ExtractIconExW( icon_path
, index
, &icon
, NULL
, 1 );
334 IShellLinkW_GetPath( link
, tmp_path
, MAX_PATH
, NULL
, SLGP_RAWPATH
);
335 ExpandEnvironmentStringsW( tmp_path
, target_path
, MAX_PATH
);
336 ExtractIconExW( target_path
, index
, &icon
, NULL
, 1 );
341 static WCHAR
*build_title( const WCHAR
*filename
, int len
)
346 if (len
== -1) len
= lstrlenW( filename
);
347 for (p
= filename
+ len
- 1; p
>= filename
; p
--)
355 if (!(ret
= malloc( (len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
356 memcpy( ret
, filename
, len
* sizeof(WCHAR
) );
361 static BOOL
add_launcher( const WCHAR
*folder
, const WCHAR
*filename
, int len_filename
)
363 struct launcher
*launcher
;
366 if (nb_launchers
== nb_allocated
)
368 unsigned int count
= nb_allocated
* 2;
369 struct launcher
**tmp
= realloc( launchers
, count
* sizeof(*tmp
) );
370 if (!tmp
) return FALSE
;
372 nb_allocated
= count
;
375 if (!(launcher
= malloc( sizeof(*launcher
) ))) return FALSE
;
376 if (!(launcher
->path
= append_path( folder
, filename
, len_filename
))) goto error
;
377 if (!(link
= load_shelllink( launcher
->path
))) goto error
;
379 launcher
->icon
= extract_icon( link
);
380 launcher
->title
= build_title( filename
, len_filename
);
381 IShellLinkW_Release( link
);
382 if (launcher
->icon
&& launcher
->title
)
384 launchers
[nb_launchers
++] = launcher
;
387 free( launcher
->title
);
388 DestroyIcon( launcher
->icon
);
391 free( launcher
->path
);
396 static void free_launcher( struct launcher
*launcher
)
398 DestroyIcon( launcher
->icon
);
399 free( launcher
->path
);
400 free( launcher
->title
);
404 static BOOL
remove_launcher( const WCHAR
*folder
, const WCHAR
*filename
, int len_filename
)
410 if (!(path
= append_path( folder
, filename
, len_filename
))) return FALSE
;
411 for (i
= 0; i
< nb_launchers
; i
++)
413 if (!wcsicmp( launchers
[i
]->path
, path
))
415 free_launcher( launchers
[i
] );
417 memmove( &launchers
[i
], &launchers
[i
+ 1], sizeof(launchers
[i
]) * (nb_launchers
- i
) );
426 static BOOL
get_icon_text_metrics( HWND hwnd
, TEXTMETRICW
*tm
)
434 SystemParametersInfoW( SPI_GETICONTITLELOGFONT
, sizeof(lf
), &lf
, 0 );
435 hfont
= SelectObject( hdc
, CreateFontIndirectW( &lf
) );
436 ret
= GetTextMetricsW( hdc
, tm
);
437 hfont
= SelectObject( hdc
, hfont
);
438 DeleteObject( hfont
);
439 ReleaseDC( hwnd
, hdc
);
443 static BOOL
process_changes( const WCHAR
*folder
, char *buf
)
445 FILE_NOTIFY_INFORMATION
*info
= (FILE_NOTIFY_INFORMATION
*)buf
;
450 switch (info
->Action
)
452 case FILE_ACTION_ADDED
:
453 case FILE_ACTION_RENAMED_NEW_NAME
:
454 if (add_launcher( folder
, info
->FileName
, info
->FileNameLength
/ sizeof(WCHAR
) ))
458 case FILE_ACTION_REMOVED
:
459 case FILE_ACTION_RENAMED_OLD_NAME
:
460 if (remove_launcher( folder
, info
->FileName
, info
->FileNameLength
/ sizeof(WCHAR
) ))
465 WARN( "unexpected action %lu\n", info
->Action
);
468 if (!info
->NextEntryOffset
) break;
469 info
= (FILE_NOTIFY_INFORMATION
*)((char *)info
+ info
->NextEntryOffset
);
474 static DWORD CALLBACK
watch_desktop_folders( LPVOID param
)
477 HRESULT init
= CoInitialize( NULL
);
478 HANDLE dir0
, dir1
, events
[2];
479 OVERLAPPED ovl0
, ovl1
;
480 char *buf0
= NULL
, *buf1
= NULL
;
481 DWORD count
, size
= 4096, error
= ERROR_OUTOFMEMORY
;
484 dir0
= CreateFileW( desktop_folder
, FILE_LIST_DIRECTORY
|SYNCHRONIZE
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
485 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
|FILE_FLAG_OVERLAPPED
, NULL
);
486 if (dir0
== INVALID_HANDLE_VALUE
) return GetLastError();
487 dir1
= CreateFileW( desktop_folder_public
, FILE_LIST_DIRECTORY
|SYNCHRONIZE
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
488 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
|FILE_FLAG_OVERLAPPED
, NULL
);
489 if (dir1
== INVALID_HANDLE_VALUE
)
492 return GetLastError();
494 if (!(ovl0
.hEvent
= events
[0] = CreateEventW( NULL
, FALSE
, FALSE
, NULL
))) goto error
;
495 if (!(ovl1
.hEvent
= events
[1] = CreateEventW( NULL
, FALSE
, FALSE
, NULL
))) goto error
;
496 if (!(buf0
= malloc( size
))) goto error
;
497 if (!(buf1
= malloc( size
))) goto error
;
501 ret
= ReadDirectoryChangesW( dir0
, buf0
, size
, FALSE
, FILE_NOTIFY_CHANGE_FILE_NAME
, NULL
, &ovl0
, NULL
);
504 error
= GetLastError();
507 ret
= ReadDirectoryChangesW( dir1
, buf1
, size
, FALSE
, FILE_NOTIFY_CHANGE_FILE_NAME
, NULL
, &ovl1
, NULL
);
510 error
= GetLastError();
515 switch ((error
= WaitForMultipleObjects( 2, events
, FALSE
, INFINITE
)))
518 if (!GetOverlappedResult( dir0
, &ovl0
, &count
, FALSE
) || !count
) break;
519 if (process_changes( desktop_folder
, buf0
)) redraw
= TRUE
;
522 case WAIT_OBJECT_0
+ 1:
523 if (!GetOverlappedResult( dir1
, &ovl1
, &count
, FALSE
) || !count
) break;
524 if (process_changes( desktop_folder_public
, buf1
)) redraw
= TRUE
;
530 if (redraw
) InvalidateRect( hwnd
, NULL
, TRUE
);
536 CloseHandle( events
[0] );
537 CloseHandle( events
[1] );
540 if (SUCCEEDED( init
)) CoUninitialize();
544 static void add_folder( const WCHAR
*folder
)
546 static const WCHAR lnkW
[] = L
"\\*.lnk";
547 int len
= lstrlenW( folder
) + lstrlenW( lnkW
);
548 WIN32_FIND_DATAW data
;
552 if (!(glob
= malloc( (len
+ 1) * sizeof(WCHAR
) ))) return;
553 lstrcpyW( glob
, folder
);
554 lstrcatW( glob
, lnkW
);
556 if ((handle
= FindFirstFileW( glob
, &data
)) != INVALID_HANDLE_VALUE
)
558 do { add_launcher( folder
, data
.cFileName
, -1 ); } while (FindNextFileW( handle
, &data
));
564 #define BORDER_SIZE 4
565 #define PADDING_SIZE 4
566 #define TITLE_CHARS 14
568 static void initialize_launchers( HWND hwnd
)
574 if (!(get_icon_text_metrics( hwnd
, &tm
))) return;
576 icon_cx
= GetSystemMetrics( SM_CXICON
);
577 icon_cy
= GetSystemMetrics( SM_CYICON
);
578 icon_size
= max( icon_cx
, icon_cy
);
579 title_cy
= tm
.tmHeight
* 2;
580 title_cx
= max( tm
.tmAveCharWidth
* TITLE_CHARS
, icon_size
+ PADDING_SIZE
+ title_cy
);
581 launcher_size
= BORDER_SIZE
+ title_cx
+ BORDER_SIZE
;
582 icon_offset_cx
= (launcher_size
- icon_cx
) / 2;
583 icon_offset_cy
= BORDER_SIZE
+ (icon_size
- icon_cy
) / 2;
584 title_offset_cx
= BORDER_SIZE
;
585 title_offset_cy
= BORDER_SIZE
+ icon_size
+ PADDING_SIZE
;
586 desktop_width
= GetSystemMetrics( SM_CXSCREEN
);
587 launchers_per_row
= desktop_width
/ launcher_size
;
588 if (!launchers_per_row
) launchers_per_row
= 1;
590 hr
= SHGetKnownFolderPath( &FOLDERID_Desktop
, KF_FLAG_CREATE
, NULL
, &desktop_folder
);
593 ERR( "Could not get user desktop folder\n" );
596 hr
= SHGetKnownFolderPath( &FOLDERID_PublicDesktop
, KF_FLAG_CREATE
, NULL
, &desktop_folder_public
);
599 ERR( "Could not get public desktop folder\n" );
600 CoTaskMemFree( desktop_folder
);
603 if ((launchers
= malloc( 2 * sizeof(launchers
[0]) )))
607 init
= CoInitialize( NULL
);
608 add_folder( desktop_folder
);
609 add_folder( desktop_folder_public
);
610 if (SUCCEEDED( init
)) CoUninitialize();
612 CreateThread( NULL
, 0, watch_desktop_folders
, hwnd
, 0, NULL
);
616 static void wait_named_mutex( const WCHAR
*name
)
620 mutex
= CreateMutexW( NULL
, TRUE
, name
);
621 if (GetLastError() == ERROR_ALREADY_EXISTS
)
623 TRACE( "waiting for mutex %s\n", debugstr_w( name
));
624 WaitForSingleObject( mutex
, INFINITE
);
628 /**************************************************************************
629 * wait_clipboard_mutex
631 * Make sure that there's only one clipboard thread per window station.
633 static BOOL
wait_clipboard_mutex(void)
635 static const WCHAR prefix
[] = L
"__wine_clipboard_";
636 WCHAR buffer
[MAX_PATH
+ ARRAY_SIZE( prefix
)];
638 memcpy( buffer
, prefix
, sizeof(prefix
) );
639 if (!GetUserObjectInformationW( GetProcessWindowStation(), UOI_NAME
,
640 buffer
+ ARRAY_SIZE( prefix
) - 1,
641 sizeof(buffer
) - sizeof(prefix
), NULL
))
643 ERR( "failed to get winstation name\n" );
646 wait_named_mutex( buffer
);
651 /**************************************************************************
654 * Window procedure for the clipboard manager.
656 static LRESULT CALLBACK
clipboard_wndproc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
661 case WM_CLIPBOARDUPDATE
:
662 case WM_RENDERFORMAT
:
664 case WM_DESTROYCLIPBOARD
:
666 return NtUserMessageCall( hwnd
, msg
, wp
, lp
, 0, NtUserClipboardWindowProc
, FALSE
);
669 return DefWindowProcW( hwnd
, msg
, wp
, lp
);
673 /**************************************************************************
676 * Thread running inside the desktop process to manage the clipboard
678 static DWORD WINAPI
clipboard_thread( void *arg
)
680 static const WCHAR clipboard_classname
[] = L
"__wine_clipboard_manager";
685 if (!wait_clipboard_mutex()) return 0;
687 memset( &class, 0, sizeof(class) );
688 class.lpfnWndProc
= clipboard_wndproc
;
689 class.lpszClassName
= clipboard_classname
;
691 if (!(atom
= RegisterClassW( &class )) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS
)
693 ERR( "could not register clipboard window class err %lu\n", GetLastError() );
696 if (!CreateWindowW( clipboard_classname
, NULL
, 0, 0, 0, 0, 0, HWND_MESSAGE
, 0, 0, NULL
))
698 TRACE( "failed to create clipboard window err %lu\n", GetLastError() );
699 UnregisterClassW( MAKEINTRESOURCEW(atom
), NULL
);
703 while (GetMessageW( &msg
, 0, 0, 0 )) DispatchMessageW( &msg
);
707 static HANDLE fullscreen_process
;
709 static LRESULT WINAPI
display_settings_restorer_wndproc( HWND hwnd
, UINT message
, WPARAM wp
, LPARAM lp
)
711 TRACE( "got msg %04x wp %Ix lp %Ix\n", message
, wp
, lp
);
716 TRACE( "fullscreen process id %Iu.\n", lp
);
718 if (fullscreen_process
)
720 CloseHandle( fullscreen_process
);
721 fullscreen_process
= NULL
;
725 fullscreen_process
= OpenProcess( SYNCHRONIZE
, FALSE
, lp
);
730 return DefWindowProcW( hwnd
, message
, wp
, lp
);
733 static DWORD WINAPI
display_settings_restorer_thread( void *param
)
735 static const WCHAR
*display_settings_restorer_classname
= L
"__wine_display_settings_restorer";
740 SetThreadDescription( GetCurrentThread(), L
"wine_explorer_display_settings_restorer" );
742 wait_named_mutex( L
"__wine_display_settings_restorer_mutex" );
744 memset( &class, 0, sizeof(class) );
745 class.lpfnWndProc
= display_settings_restorer_wndproc
;
746 class.lpszClassName
= display_settings_restorer_classname
;
748 if (!RegisterClassW( &class ) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS
)
750 ERR( "could not register display settings restorer window class err %lu\n", GetLastError() );
753 if (!CreateWindowW( display_settings_restorer_classname
, NULL
, 0, 0, 0, 0, 0, HWND_MESSAGE
, 0, 0, NULL
))
755 WARN( "failed to create display settings restorer window err %lu\n", GetLastError() );
756 UnregisterClassW( display_settings_restorer_classname
, NULL
);
762 if (PeekMessageW( &msg
, NULL
, 0, 0, PM_REMOVE
))
764 if (msg
.message
== WM_QUIT
)
766 DispatchMessageW( &msg
);
770 wait_result
= MsgWaitForMultipleObjects( fullscreen_process
? 1 : 0, &fullscreen_process
,
771 FALSE
, INFINITE
, QS_ALLINPUT
);
772 if (wait_result
== WAIT_FAILED
)
774 if (!fullscreen_process
|| wait_result
!= WAIT_OBJECT_0
)
777 TRACE( "restoring display settings on process exit\n" );
779 ChangeDisplaySettingsExW( NULL
, NULL
, NULL
, 0, NULL
);
781 CloseHandle( fullscreen_process
);
782 fullscreen_process
= NULL
;
788 static WNDPROC desktop_orig_wndproc
;
790 /* window procedure for the desktop window */
791 static LRESULT WINAPI
desktop_wnd_proc( HWND hwnd
, UINT message
, WPARAM wp
, LPARAM lp
)
793 TRACE( "got msg %04x wp %Ix lp %Ix\n", message
, wp
, lp
);
811 return (LRESULT
)SetCursor( LoadCursorA( 0, (LPSTR
)IDC_ARROW
) );
817 if (!using_root
) PaintDesktop( (HDC
)wp
);
820 case WM_SETTINGCHANGE
:
821 if (wp
== SPI_SETDESKWALLPAPER
)
822 SystemParametersInfoW( SPI_SETDESKWALLPAPER
, 0, NULL
, FALSE
);
825 case WM_PARENTNOTIFY
:
826 handle_parent_notify( (HWND
)lp
, wp
);
829 case WM_LBUTTONDBLCLK
:
832 const struct launcher
*launcher
= launcher_from_point( (short)LOWORD(lp
), (short)HIWORD(lp
) );
833 if (launcher
) ShellExecuteW( NULL
, L
"open", launcher
->path
, NULL
, NULL
, 0 );
840 BeginPaint( hwnd
, &ps
);
843 if (ps
.fErase
) PaintDesktop( ps
.hdc
);
844 draw_launchers( ps
.hdc
, ps
.rcPaint
);
846 EndPaint( hwnd
, &ps
);
851 return desktop_orig_wndproc( hwnd
, message
, wp
, lp
);
854 /* parse the desktop size specification */
855 static BOOL
parse_size( const WCHAR
*size
, unsigned int *width
, unsigned int *height
)
859 *width
= wcstoul( size
, &end
, 10 );
860 if (end
== size
) return FALSE
;
861 if (*end
!= 'x') return FALSE
;
863 *height
= wcstoul( size
, &end
, 10 );
867 /* retrieve the desktop name to use if not specified on the command line */
868 static const WCHAR
*get_default_desktop_name(void)
870 static WCHAR buffer
[MAX_PATH
];
871 DWORD size
= sizeof(buffer
);
872 HDESK desk
= GetThreadDesktop( GetCurrentThreadId() );
876 if (desk
&& GetUserObjectInformationW( desk
, UOI_NAME
, buffer
, ARRAY_SIZE( buffer
), NULL
))
878 if (wcsicmp( buffer
, L
"Default" )) return buffer
;
881 /* @@ Wine registry key: HKCU\Software\Wine\Explorer */
882 if (!RegOpenKeyW( HKEY_CURRENT_USER
, L
"Software\\Wine\\Explorer", &hkey
))
884 if (!RegQueryValueExW( hkey
, L
"Desktop", 0, NULL
, (LPBYTE
)buffer
, &size
) && *buffer
) ret
= buffer
;
890 /* retrieve the default desktop size from the registry */
891 static BOOL
get_default_desktop_size( const WCHAR
*name
, unsigned int *width
, unsigned int *height
)
895 DWORD size
= sizeof(buffer
);
901 /* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
902 if (!RegOpenKeyW( HKEY_CURRENT_USER
, L
"Software\\Wine\\Explorer\\Desktops", &hkey
))
904 if (!RegQueryValueExW( hkey
, name
, 0, NULL
, (LPBYTE
)buffer
, &size
))
907 if (!parse_size( buffer
, width
, height
)) *width
= *height
= 0;
914 static BOOL
get_default_enable_shell( const WCHAR
*name
)
919 DWORD size
= sizeof(result
);
921 /* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
922 if (!RegOpenKeyW( HKEY_CURRENT_USER
, L
"Software\\Wine\\Explorer\\Desktops", &hkey
))
924 if (!RegGetValueW( hkey
, name
, L
"EnableShell", RRF_RT_REG_DWORD
, NULL
, &result
, &size
))
928 /* Default off, except for the magic desktop name "shell" */
929 if (!found
) result
= (lstrcmpiW( name
, L
"shell" ) == 0);
933 static BOOL
get_default_show_systray( const WCHAR
*name
)
938 DWORD size
= sizeof(result
);
940 /* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
941 if (name
&& !RegOpenKeyW( HKEY_CURRENT_USER
, L
"Software\\Wine\\Explorer\\Desktops", &hkey
))
943 if (!RegGetValueW( hkey
, name
, L
"ShowSystray", RRF_RT_REG_DWORD
, NULL
, &result
, &size
))
948 /* Try again with a global Explorer setting */
949 /* @@ Wine registry key: HKCU\Software\Wine\Explorer */
950 if (!found
&& !RegOpenKeyW( HKEY_CURRENT_USER
, L
"Software\\Wine\\Explorer", &hkey
))
952 if (!RegGetValueW( hkey
, NULL
, L
"ShowSystray", RRF_RT_REG_DWORD
, NULL
, &result
, &size
))
958 if (!found
) result
= TRUE
;
962 static void load_graphics_driver( const WCHAR
*driver
, GUID
*guid
)
964 static const WCHAR device_keyW
[] = L
"System\\CurrentControlSet\\Control\\Video\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\0000";
966 WCHAR buffer
[MAX_PATH
], libname
[32], *name
, *next
;
967 WCHAR key
[ARRAY_SIZE( device_keyW
) + 39];
968 BOOL null_driver
= FALSE
;
975 lstrcpyW( buffer
, default_driver
);
977 /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
978 if (!RegOpenKeyW( HKEY_CURRENT_USER
, L
"Software\\Wine\\Drivers", &hkey
))
980 DWORD count
= sizeof(buffer
);
981 RegQueryValueExW( hkey
, L
"Graphics", 0, NULL
, (LPBYTE
)buffer
, &count
);
985 else lstrcpynW( buffer
, driver
, ARRAY_SIZE( buffer
));
990 next
= wcschr( name
, ',' );
991 if (next
) *next
++ = 0;
993 if (!wcscmp( name
, L
"null" ))
995 memset( guid
, 0, sizeof(*guid
) );
996 TRACE( "display %s using null driver\n", debugstr_guid(guid
) );
997 wcscpy( libname
, L
"null" );
1002 swprintf( libname
, ARRAY_SIZE( libname
), L
"wine%s.drv", name
);
1003 if ((module
= LoadLibraryW( libname
)) != 0) break;
1004 switch (GetLastError())
1006 case ERROR_MOD_NOT_FOUND
:
1007 strcpy( error
, "The graphics driver is missing. Check your build!" );
1009 case ERROR_DLL_INIT_FAILED
:
1010 strcpy( error
, "Make sure that your X server is running and that $DISPLAY is set correctly." );
1013 sprintf( error
, "Unknown error (%lu).", GetLastError() );
1019 TRACE( "display %s driver %s\n", debugstr_guid(guid
), debugstr_w(libname
) );
1021 swprintf( key
, ARRAY_SIZE(key
), device_keyW
, guid
->Data1
, guid
->Data2
, guid
->Data3
,
1022 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
1023 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7] );
1025 if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE
, key
, 0, NULL
,
1026 REG_OPTION_VOLATILE
, KEY_SET_VALUE
, NULL
, &hkey
, NULL
))
1028 if (module
|| null_driver
)
1029 RegSetValueExW( hkey
, L
"GraphicsDriver", 0, REG_SZ
,
1030 (BYTE
*)libname
, (lstrlenW(libname
) + 1) * sizeof(WCHAR
) );
1032 RegSetValueExA( hkey
, "DriverError", 0, REG_SZ
, (BYTE
*)error
, strlen(error
) + 1 );
1033 RegCloseKey( hkey
);
1037 static const char *debugstr_devmodew( const DEVMODEW
*devmode
)
1039 char position
[32] = {0};
1041 if (devmode
->dmFields
& DM_POSITION
)
1043 snprintf( position
, sizeof(position
), " at (%d,%d)",
1044 (int)devmode
->dmPosition
.x
, (int)devmode
->dmPosition
.y
);
1047 return wine_dbg_sprintf( "%ux%u %ubits %uHz rotated %u degrees%s",
1048 (unsigned int)devmode
->dmPelsWidth
,
1049 (unsigned int)devmode
->dmPelsHeight
,
1050 (unsigned int)devmode
->dmBitsPerPel
,
1051 (unsigned int)devmode
->dmDisplayFrequency
,
1052 (unsigned int)devmode
->dmDisplayOrientation
* 90,
1056 static void initialize_display_settings( unsigned int width
, unsigned int height
)
1058 DISPLAY_DEVICEW device
= {.cb
= sizeof(DISPLAY_DEVICEW
)};
1059 DWORD i
= 0, flags
= CDS_GLOBAL
| CDS_UPDATEREGISTRY
;
1062 /* Store current display mode in the registry */
1063 while (EnumDisplayDevicesW( NULL
, i
++, &device
, 0 ))
1065 DEVMODEW devmode
= {.dmSize
= sizeof(DEVMODEW
)};
1067 if (!EnumDisplaySettingsExW( device
.DeviceName
, ENUM_CURRENT_SETTINGS
, &devmode
, 0))
1069 ERR( "Failed to query current display settings for %s.\n", debugstr_w( device
.DeviceName
) );
1073 TRACE( "Device %s current display mode %s.\n", debugstr_w( device
.DeviceName
), debugstr_devmodew( &devmode
) );
1075 if (ChangeDisplaySettingsExW( device
.DeviceName
, &devmode
, 0, flags
| CDS_NORESET
, 0 ))
1076 ERR( "Failed to initialize registry display settings for %s.\n", debugstr_w( device
.DeviceName
) );
1083 .dmSize
= sizeof(DEVMODEW
),
1084 .dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
,
1085 .dmPelsWidth
= width
,
1086 .dmPelsHeight
= height
,
1089 /* in virtual desktop mode, set the primary display settings to match desktop size */
1090 if (ChangeDisplaySettingsExW( NULL
, &devmode
, 0, flags
, NULL
))
1091 ERR( "Failed to set primary display settings.\n" );
1094 thread
= CreateThread( NULL
, 0, display_settings_restorer_thread
, NULL
, 0, NULL
);
1095 if (thread
) CloseHandle( thread
);
1098 static void set_desktop_window_title( HWND hwnd
, const WCHAR
*name
)
1100 static const WCHAR desktop_nameW
[] = L
"Wine desktop";
1101 static const WCHAR desktop_name_separatorW
[] = L
" - ";
1102 WCHAR
*window_titleW
= NULL
;
1103 int window_title_len
;
1107 SetWindowTextW( hwnd
, desktop_nameW
);
1111 window_title_len
= lstrlenW(name
) * sizeof(WCHAR
)
1112 + sizeof(desktop_name_separatorW
)
1113 + sizeof(desktop_nameW
);
1114 window_titleW
= malloc( window_title_len
);
1117 SetWindowTextW( hwnd
, desktop_nameW
);
1121 lstrcpyW( window_titleW
, name
);
1122 lstrcatW( window_titleW
, desktop_name_separatorW
);
1123 lstrcatW( window_titleW
, desktop_nameW
);
1125 SetWindowTextW( hwnd
, window_titleW
);
1126 free( window_titleW
);
1129 static inline BOOL
is_whitespace(WCHAR c
)
1131 return c
== ' ' || c
== '\t';
1134 /* main desktop management function */
1135 void manage_desktop( WCHAR
*arg
)
1141 unsigned int width
, height
;
1142 WCHAR
*cmdline
= NULL
, *driver
= NULL
;
1144 const WCHAR
*name
= NULL
;
1145 BOOL enable_shell
= FALSE
, show_systray
= TRUE
;
1146 void (WINAPI
*pShellDDEInit
)( BOOL
) = NULL
;
1151 /* get the rest of the command line (if any) */
1152 while (*p
&& !is_whitespace(*p
)) p
++;
1156 while (*p
&& is_whitespace(*p
)) p
++;
1157 if (*p
) cmdline
= p
;
1160 /* parse the desktop option */
1161 /* the option is of the form /desktop=name[,widthxheight[,driver]] */
1162 if ((arg
[0] == '=' || arg
[0] == ',') && arg
[1] && arg
[1] != ',')
1166 if ((p
= wcschr( arg
, ',' )))
1169 if ((driver
= wcschr( p
, ',' ))) *driver
++ = 0;
1171 if (!p
|| !parse_size( p
, &width
, &height
))
1172 get_default_desktop_size( name
, &width
, &height
);
1174 else if ((name
= get_default_desktop_name()))
1176 if (!get_default_desktop_size( name
, &width
, &height
)) width
= height
= 0;
1179 if (name
) enable_shell
= get_default_enable_shell( name
);
1180 show_systray
= get_default_show_systray( name
);
1182 UuidCreate( &guid
);
1183 TRACE( "display guid %s\n", debugstr_guid(&guid
) );
1184 load_graphics_driver( driver
, &guid
);
1186 if (name
&& width
&& height
)
1188 DEVMODEW devmode
= {.dmPelsWidth
= width
, .dmPelsHeight
= height
};
1189 /* magic: desktop "root" means use the root window */
1190 if ((using_root
= !wcsicmp( name
, L
"root" ))) desktop
= CreateDesktopW( name
, NULL
, NULL
, DF_WINE_ROOT_DESKTOP
, DESKTOP_ALL_ACCESS
, NULL
);
1191 else desktop
= CreateDesktopW( name
, NULL
, &devmode
, DF_WINE_VIRTUAL_DESKTOP
, DESKTOP_ALL_ACCESS
, NULL
);
1194 ERR( "failed to create desktop %s error %ld\n", debugstr_w(name
), GetLastError() );
1197 SetThreadDesktop( desktop
);
1200 /* create the desktop window */
1201 hwnd
= CreateWindowExW( 0, DESKTOP_CLASS_ATOM
, NULL
,
1202 WS_POPUP
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
, 0, 0, 0, 0, 0, 0, 0, &guid
);
1206 /* create the HWND_MESSAGE parent */
1207 CreateWindowExW( 0, L
"Message", NULL
, WS_POPUP
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
1208 0, 0, 100, 100, 0, 0, 0, NULL
);
1210 desktop_orig_wndproc
= (WNDPROC
)SetWindowLongPtrW( hwnd
, GWLP_WNDPROC
,
1211 (LONG_PTR
)desktop_wnd_proc
);
1212 SendMessageW( hwnd
, WM_SETICON
, ICON_BIG
, (LPARAM
)LoadIconW( 0, MAKEINTRESOURCEW(OIC_WINLOGO
)));
1213 if (name
) set_desktop_window_title( hwnd
, name
);
1214 SetWindowPos( hwnd
, 0, GetSystemMetrics(SM_XVIRTUALSCREEN
), GetSystemMetrics(SM_YVIRTUALSCREEN
),
1215 GetSystemMetrics(SM_CXVIRTUALSCREEN
), GetSystemMetrics(SM_CYVIRTUALSCREEN
),
1217 thread
= CreateThread( NULL
, 0, clipboard_thread
, NULL
, 0, &id
);
1218 if (thread
) CloseHandle( thread
);
1219 SystemParametersInfoW( SPI_SETDESKWALLPAPER
, 0, NULL
, FALSE
);
1221 initialize_display_settings( width
, height
);
1222 initialize_appbar();
1224 if (using_root
) enable_shell
= FALSE
;
1226 initialize_systray( using_root
, enable_shell
, show_systray
);
1227 if (!using_root
) initialize_launchers( hwnd
);
1229 if ((shell32
= LoadLibraryW( L
"shell32.dll" )) &&
1230 (pShellDDEInit
= (void *)GetProcAddress( shell32
, (LPCSTR
)188)))
1232 pShellDDEInit( TRUE
);
1236 /* if we have a command line, execute it */
1240 PROCESS_INFORMATION pi
;
1242 memset( &si
, 0, sizeof(si
) );
1244 TRACE( "starting %s\n", debugstr_w(cmdline
) );
1245 if (CreateProcessW( NULL
, cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
))
1247 CloseHandle( pi
.hThread
);
1248 CloseHandle( pi
.hProcess
);
1252 desktopshellbrowserwindow_init();
1253 shellwindows_init();
1255 /* run the desktop message loop */
1258 TRACE( "desktop message loop starting on hwnd %p\n", hwnd
);
1259 while (GetMessageW( &msg
, 0, 0, 0 )) DispatchMessageW( &msg
);
1260 TRACE( "desktop message loop exiting for hwnd %p\n", hwnd
);
1263 if (pShellDDEInit
) pShellDDEInit( FALSE
);
1268 /* IShellWindows implementation */
1269 static HRESULT WINAPI
shellwindows_QueryInterface(IShellWindows
*iface
, REFIID riid
, void **ppvObject
)
1271 struct shellwindows
*This
= impl_from_IShellWindows(iface
);
1273 TRACE("%s %p\n", debugstr_guid(riid
), ppvObject
);
1275 if (IsEqualGUID(riid
, &IID_IShellWindows
) ||
1276 IsEqualGUID(riid
, &IID_IDispatch
) ||
1277 IsEqualGUID(riid
, &IID_IUnknown
))
1279 *ppvObject
= &This
->IShellWindows_iface
;
1283 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
1289 IUnknown_AddRef((IUnknown
*)*ppvObject
);
1293 return E_NOINTERFACE
;
1296 static ULONG WINAPI
shellwindows_AddRef(IShellWindows
*iface
)
1301 static ULONG WINAPI
shellwindows_Release(IShellWindows
*iface
)
1306 static HRESULT WINAPI
shellwindows_GetTypeInfoCount(IShellWindows
*iface
, UINT
*pctinfo
)
1308 TRACE("%p\n", pctinfo
);
1313 static HRESULT WINAPI
shellwindows_GetTypeInfo(IShellWindows
*iface
,
1314 UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1316 TRACE("%d %ld %p\n", iTInfo
, lcid
, ppTInfo
);
1317 return get_typeinfo(IShellWindows_tid
, ppTInfo
);
1320 static HRESULT WINAPI
shellwindows_GetIDsOfNames(IShellWindows
*iface
,
1321 REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
,
1324 ITypeInfo
*typeinfo
;
1327 TRACE("%s %p %d %ld %p\n", debugstr_guid(riid
), rgszNames
, cNames
,
1330 if (!rgszNames
|| cNames
== 0 || !rgDispId
)
1331 return E_INVALIDARG
;
1333 hr
= get_typeinfo(IShellWindows_tid
, &typeinfo
);
1336 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1337 ITypeInfo_Release(typeinfo
);
1343 static HRESULT WINAPI
shellwindows_Invoke(IShellWindows
*iface
,
1344 DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
,
1345 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1346 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1348 ITypeInfo
*typeinfo
;
1351 TRACE("%ld %s %ld %08x %p %p %p %p\n", dispIdMember
, debugstr_guid(riid
),
1352 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1354 hr
= get_typeinfo(IShellWindows_tid
, &typeinfo
);
1357 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
1358 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1359 ITypeInfo_Release(typeinfo
);
1365 static HRESULT WINAPI
shellwindows_get_Count(IShellWindows
*iface
, LONG
*count
)
1367 FIXME("%p\n", count
);
1371 static HRESULT WINAPI
shellwindows_Item(IShellWindows
*iface
, VARIANT index
,
1374 FIXME("%s %p\n", debugstr_variant(&index
), folder
);
1378 static HRESULT WINAPI
shellwindows__NewEnum(IShellWindows
*iface
, IUnknown
**ppunk
)
1380 FIXME("%p\n", ppunk
);
1384 static HRESULT WINAPI
shellwindows_Register(IShellWindows
*iface
,
1385 IDispatch
*disp
, LONG hwnd
, int class, LONG
*cookie
)
1387 struct shellwindows
*sw
= impl_from_IShellWindows(iface
);
1388 struct window
*window
;
1390 TRACE("iface %p, disp %p, hwnd %#lx, class %u, cookie %p.\n", iface
, disp
, hwnd
, class, cookie
);
1396 FIXME("Ignoring IDispatch %p.\n", disp
);
1398 EnterCriticalSection(&sw
->cs
);
1400 if (!array_reserve((void **)&sw
->windows
, &sw
->max
, sw
->count
+ 1, sizeof(*sw
->windows
)))
1402 LeaveCriticalSection(&sw
->cs
);
1403 return E_OUTOFMEMORY
;
1406 window
= &sw
->windows
[sw
->count
++];
1407 window
->hwnd
= hwnd
;
1408 window
->class = class;
1409 *cookie
= window
->cookie
= ++cookie_counter
;
1410 window
->pidl
= NULL
;
1412 LeaveCriticalSection(&sw
->cs
);
1416 static HRESULT WINAPI
shellwindows_RegisterPending(IShellWindows
*iface
,
1417 LONG threadid
, VARIANT
*loc
, VARIANT
*root
, int class, LONG
*cookie
)
1419 FIXME("0x%lx %s %s 0x%x %p\n", threadid
, debugstr_variant(loc
), debugstr_variant(root
),
1424 static HRESULT WINAPI
shellwindows_Revoke(IShellWindows
*iface
, LONG cookie
)
1426 struct shellwindows
*sw
= impl_from_IShellWindows(iface
);
1429 TRACE("iface %p, cookie %lu.\n", iface
, cookie
);
1431 EnterCriticalSection(&sw
->cs
);
1433 for (i
= 0; i
< sw
->count
; ++i
)
1435 if (sw
->windows
[i
].cookie
== cookie
)
1438 memmove(&sw
->windows
[i
], &sw
->windows
[i
+ 1], (sw
->count
- i
) * sizeof(*sw
->windows
));
1439 LeaveCriticalSection(&sw
->cs
);
1444 LeaveCriticalSection(&sw
->cs
);
1448 static HRESULT WINAPI
shellwindows_OnNavigate(IShellWindows
*iface
, LONG cookie
, VARIANT
*location
)
1450 struct shellwindows
*sw
= impl_from_IShellWindows(iface
);
1453 TRACE("iface %p, cookie %lu, location %s.\n", iface
, cookie
, debugstr_variant(location
));
1455 if (V_VT(location
) != (VT_ARRAY
| VT_UI1
))
1457 FIXME("Unexpected variant type %s.\n", debugstr_vt(V_VT(location
)));
1461 EnterCriticalSection(&sw
->cs
);
1463 for (i
= 0; i
< sw
->count
; ++i
)
1465 if (sw
->windows
[i
].cookie
== cookie
)
1467 size_t len
= V_ARRAY(location
)->rgsabound
[0].cElements
;
1468 if (!(sw
->windows
[i
].pidl
= realloc(sw
->windows
[i
].pidl
, len
)))
1470 LeaveCriticalSection(&sw
->cs
);
1471 return E_OUTOFMEMORY
;
1473 memcpy(sw
->windows
[i
].pidl
, V_ARRAY(location
)->pvData
, len
);
1475 LeaveCriticalSection(&sw
->cs
);
1480 LeaveCriticalSection(&sw
->cs
);
1481 return E_INVALIDARG
;
1484 static HRESULT WINAPI
shellwindows_OnActivated(IShellWindows
*iface
, LONG cookie
, VARIANT_BOOL active
)
1486 FIXME("0x%lx 0x%x\n", cookie
, active
);
1490 static HRESULT WINAPI
shellwindows_FindWindowSW(IShellWindows
*iface
, VARIANT
*location
,
1491 VARIANT
*root
, int class, LONG
*hwnd
, int options
, IDispatch
**disp
)
1493 struct shellwindows
*sw
= impl_from_IShellWindows(iface
);
1496 TRACE("iface %p, location %p, root %p, class %#x, hwnd %p, options %#x, disp %p.\n",
1497 iface
, location
, root
, class, hwnd
, options
, disp
);
1499 if (class == SWC_DESKTOP
)
1501 *hwnd
= (LONG
)(LONG_PTR
)GetDesktopWindow();
1502 if (options
& SWFO_NEEDDISPATCH
)
1504 *disp
= (IDispatch
*)&desktopshellbrowserwindow
.IWebBrowser2_iface
;
1505 IDispatch_AddRef(*disp
);
1511 FIXME("Ignoring options %#x.\n", options
);
1513 if (V_VT(location
) != (VT_ARRAY
| VT_UI1
))
1515 FIXME("Unexpected variant type %s.\n", debugstr_vt(V_VT(location
)));
1519 EnterCriticalSection(&sw
->cs
);
1521 for (i
= 0; i
< sw
->count
; ++i
)
1523 if (sw
->windows
[i
].class == class && ILIsEqual(V_ARRAY(location
)->pvData
, sw
->windows
[i
].pidl
))
1525 *hwnd
= sw
->windows
[i
].hwnd
;
1526 LeaveCriticalSection(&sw
->cs
);
1531 LeaveCriticalSection(&sw
->cs
);
1535 static HRESULT WINAPI
shellwindows_OnCreated(IShellWindows
*iface
, LONG cookie
, IUnknown
*punk
)
1537 FIXME("0x%lx %p\n", cookie
, punk
);
1541 static HRESULT WINAPI
shellwindows_ProcessAttachDetach(IShellWindows
*iface
, VARIANT_BOOL attach
)
1543 FIXME("0x%x\n", attach
);
1547 static const IShellWindowsVtbl shellwindowsvtbl
=
1549 shellwindows_QueryInterface
,
1550 shellwindows_AddRef
,
1551 shellwindows_Release
,
1552 shellwindows_GetTypeInfoCount
,
1553 shellwindows_GetTypeInfo
,
1554 shellwindows_GetIDsOfNames
,
1555 shellwindows_Invoke
,
1556 shellwindows_get_Count
,
1558 shellwindows__NewEnum
,
1559 shellwindows_Register
,
1560 shellwindows_RegisterPending
,
1561 shellwindows_Revoke
,
1562 shellwindows_OnNavigate
,
1563 shellwindows_OnActivated
,
1564 shellwindows_FindWindowSW
,
1565 shellwindows_OnCreated
,
1566 shellwindows_ProcessAttachDetach
1569 struct shellwindows_classfactory
1571 IClassFactory IClassFactory_iface
;
1575 static inline struct shellwindows_classfactory
*impl_from_IClassFactory(IClassFactory
*iface
)
1577 return CONTAINING_RECORD(iface
, struct shellwindows_classfactory
, IClassFactory_iface
);
1580 static HRESULT WINAPI
swclassfactory_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppvObject
)
1582 struct shellwindows_classfactory
*This
= impl_from_IClassFactory(iface
);
1584 TRACE("%s %p\n", debugstr_guid(riid
), ppvObject
);
1586 if (IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IClassFactory
))
1588 *ppvObject
= &This
->IClassFactory_iface
;
1592 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
1598 IUnknown_AddRef((IUnknown
*)*ppvObject
);
1602 return E_NOINTERFACE
;
1605 static ULONG WINAPI
swclassfactory_AddRef(IClassFactory
*iface
)
1610 static ULONG WINAPI
swclassfactory_Release(IClassFactory
*iface
)
1615 static HRESULT WINAPI
swclassfactory_CreateInstance(IClassFactory
*iface
,
1616 IUnknown
*pUnkOuter
, REFIID riid
, void **ppvObject
)
1618 TRACE("%p %s %p\n", pUnkOuter
, debugstr_guid(riid
), ppvObject
);
1619 return IShellWindows_QueryInterface(&shellwindows
.IShellWindows_iface
, riid
, ppvObject
);
1622 static HRESULT WINAPI
swclassfactory_LockServer(IClassFactory
*iface
, BOOL lock
)
1624 TRACE("%u\n", lock
);
1628 static const IClassFactoryVtbl swclassfactoryvtbl
=
1630 swclassfactory_QueryInterface
,
1631 swclassfactory_AddRef
,
1632 swclassfactory_Release
,
1633 swclassfactory_CreateInstance
,
1634 swclassfactory_LockServer
1637 static struct shellwindows_classfactory shellwindows_classfactory
= { { &swclassfactoryvtbl
} };
1639 static HRESULT WINAPI
webbrowser_QueryInterface(IWebBrowser2
*iface
, REFIID riid
, void **ppv
)
1641 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1645 if (IsEqualGUID(&IID_IWebBrowser2
, riid
) ||
1646 IsEqualGUID(&IID_IWebBrowserApp
, riid
) ||
1647 IsEqualGUID(&IID_IWebBrowser
, riid
) ||
1648 IsEqualGUID(&IID_IDispatch
, riid
) ||
1649 IsEqualGUID(&IID_IUnknown
, riid
))
1651 *ppv
= &This
->IWebBrowser2_iface
;
1653 else if (IsEqualGUID(&IID_IServiceProvider
, riid
))
1655 *ppv
= &This
->IServiceProvider_iface
;
1660 IUnknown_AddRef((IUnknown
*)*ppv
);
1664 FIXME("(%p)->(%s %p) interface not supported\n", This
, debugstr_guid(riid
), ppv
);
1665 return E_NOINTERFACE
;
1668 static ULONG WINAPI
webbrowser_AddRef(IWebBrowser2
*iface
)
1673 static ULONG WINAPI
webbrowser_Release(IWebBrowser2
*iface
)
1678 /* IDispatch methods */
1679 static HRESULT WINAPI
webbrowser_GetTypeInfoCount(IWebBrowser2
*iface
, UINT
*pctinfo
)
1681 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1682 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1687 static HRESULT WINAPI
webbrowser_GetTypeInfo(IWebBrowser2
*iface
, UINT iTInfo
, LCID lcid
,
1688 LPTYPEINFO
*ppTInfo
)
1690 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1691 TRACE("(%p)->(%d %ld %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1692 return get_typeinfo(IWebBrowser2_tid
, ppTInfo
);
1695 static HRESULT WINAPI
webbrowser_GetIDsOfNames(IWebBrowser2
*iface
, REFIID riid
,
1696 LPOLESTR
*rgszNames
, UINT cNames
,
1697 LCID lcid
, DISPID
*rgDispId
)
1699 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1700 ITypeInfo
*typeinfo
;
1703 TRACE("(%p)->(%s %p %d %ld %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
1706 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
1707 return E_INVALIDARG
;
1709 hr
= get_typeinfo(IWebBrowser2_tid
, &typeinfo
);
1712 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1713 ITypeInfo_Release(typeinfo
);
1719 static HRESULT WINAPI
webbrowser_Invoke(IWebBrowser2
*iface
, DISPID dispIdMember
,
1720 REFIID riid
, LCID lcid
, WORD wFlags
,
1721 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1722 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1724 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1725 ITypeInfo
*typeinfo
;
1728 TRACE("(%p)->(%ld %s %ld %08x %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1729 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1731 hr
= get_typeinfo(IWebBrowser2_tid
, &typeinfo
);
1734 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IWebBrowser2_iface
, dispIdMember
, wFlags
,
1735 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1736 ITypeInfo_Release(typeinfo
);
1742 /* IWebBrowser methods */
1743 static HRESULT WINAPI
webbrowser_GoBack(IWebBrowser2
*iface
)
1745 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1746 FIXME("(%p): stub\n", This
);
1750 static HRESULT WINAPI
webbrowser_GoForward(IWebBrowser2
*iface
)
1752 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1753 FIXME("(%p): stub\n", This
);
1757 static HRESULT WINAPI
webbrowser_GoHome(IWebBrowser2
*iface
)
1759 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1760 FIXME("(%p): stub\n", This
);
1764 static HRESULT WINAPI
webbrowser_GoSearch(IWebBrowser2
*iface
)
1766 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1767 FIXME("(%p)\n", This
);
1771 static HRESULT WINAPI
webbrowser_Navigate(IWebBrowser2
*iface
, BSTR szUrl
,
1772 VARIANT
*Flags
, VARIANT
*TargetFrameName
,
1773 VARIANT
*PostData
, VARIANT
*Headers
)
1775 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1776 FIXME("(%p)->(%s %s %s %s %s): stub\n", This
, debugstr_w(szUrl
), debugstr_variant(Flags
),
1777 debugstr_variant(TargetFrameName
), debugstr_variant(PostData
),
1778 debugstr_variant(Headers
));
1782 static HRESULT WINAPI
webbrowser_Refresh(IWebBrowser2
*iface
)
1784 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1785 FIXME("(%p): stub\n", This
);
1789 static HRESULT WINAPI
webbrowser_Refresh2(IWebBrowser2
*iface
, VARIANT
*Level
)
1791 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1792 FIXME("(%p)->(%s): stub\n", This
, debugstr_variant(Level
));
1796 static HRESULT WINAPI
webbrowser_Stop(IWebBrowser2
*iface
)
1798 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1799 FIXME("(%p): stub\n", This
);
1803 static HRESULT WINAPI
webbrowser_get_Application(IWebBrowser2
*iface
, IDispatch
**ppDisp
)
1805 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1807 TRACE("(%p)->(%p)\n", This
, ppDisp
);
1809 *ppDisp
= (IDispatch
*)iface
;
1810 IDispatch_AddRef(*ppDisp
);
1815 static HRESULT WINAPI
webbrowser_get_Parent(IWebBrowser2
*iface
, IDispatch
**ppDisp
)
1817 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1818 FIXME("(%p)->(%p)\n", This
, ppDisp
);
1822 static HRESULT WINAPI
webbrowser_get_Container(IWebBrowser2
*iface
, IDispatch
**ppDisp
)
1824 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1825 FIXME("(%p)->(%p)\n", This
, ppDisp
);
1829 static HRESULT WINAPI
webbrowser_get_Document(IWebBrowser2
*iface
, IDispatch
**ppDisp
)
1831 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1832 FIXME("(%p)->(%p)\n", This
, ppDisp
);
1836 static HRESULT WINAPI
webbrowser_get_TopLevelContainer(IWebBrowser2
*iface
, VARIANT_BOOL
*pBool
)
1838 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1839 FIXME("(%p)->(%p)\n", This
, pBool
);
1843 static HRESULT WINAPI
webbrowser_get_Type(IWebBrowser2
*iface
, BSTR
*Type
)
1845 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1846 FIXME("(%p)->(%p)\n", This
, Type
);
1850 static HRESULT WINAPI
webbrowser_get_Left(IWebBrowser2
*iface
, LONG
*pl
)
1852 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1853 FIXME("(%p)->(%p)\n", This
, pl
);
1857 static HRESULT WINAPI
webbrowser_put_Left(IWebBrowser2
*iface
, LONG Left
)
1859 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1860 FIXME("(%p)->(%ld)\n", This
, Left
);
1864 static HRESULT WINAPI
webbrowser_get_Top(IWebBrowser2
*iface
, LONG
*pl
)
1866 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1867 FIXME("(%p)->(%p)\n", This
, pl
);
1871 static HRESULT WINAPI
webbrowser_put_Top(IWebBrowser2
*iface
, LONG Top
)
1873 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1874 FIXME("(%p)->(%ld)\n", This
, Top
);
1878 static HRESULT WINAPI
webbrowser_get_Width(IWebBrowser2
*iface
, LONG
*pl
)
1880 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1881 FIXME("(%p)->(%p)\n", This
, pl
);
1885 static HRESULT WINAPI
webbrowser_put_Width(IWebBrowser2
*iface
, LONG Width
)
1887 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1888 FIXME("(%p)->(%ld)\n", This
, Width
);
1892 static HRESULT WINAPI
webbrowser_get_Height(IWebBrowser2
*iface
, LONG
*pl
)
1894 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1895 FIXME("(%p)->(%p)\n", This
, pl
);
1899 static HRESULT WINAPI
webbrowser_put_Height(IWebBrowser2
*iface
, LONG Height
)
1901 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1902 FIXME("(%p)->(%ld)\n", This
, Height
);
1906 static HRESULT WINAPI
webbrowser_get_LocationName(IWebBrowser2
*iface
, BSTR
*LocationName
)
1908 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1909 FIXME("(%p)->(%p)\n", This
, LocationName
);
1913 static HRESULT WINAPI
webbrowser_get_LocationURL(IWebBrowser2
*iface
, BSTR
*LocationURL
)
1915 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1916 FIXME("(%p)->(%p)\n", This
, LocationURL
);
1920 static HRESULT WINAPI
webbrowser_get_Busy(IWebBrowser2
*iface
, VARIANT_BOOL
*pBool
)
1922 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1923 FIXME("(%p)->(%p)\n", This
, pBool
);
1927 static HRESULT WINAPI
webbrowser_Quit(IWebBrowser2
*iface
)
1929 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1930 FIXME("(%p)\n", This
);
1934 static HRESULT WINAPI
webbrowser_ClientToWindow(IWebBrowser2
*iface
, int *pcx
, int *pcy
)
1936 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1937 FIXME("(%p)->(%p %p)\n", This
, pcx
, pcy
);
1941 static HRESULT WINAPI
webbrowser_PutProperty(IWebBrowser2
*iface
, BSTR szProperty
, VARIANT vtValue
)
1943 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1944 FIXME("(%p)->(%s %s)\n", This
, debugstr_w(szProperty
), debugstr_variant(&vtValue
));
1948 static HRESULT WINAPI
webbrowser_GetProperty(IWebBrowser2
*iface
, BSTR szProperty
, VARIANT
*pvtValue
)
1950 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1951 FIXME("(%p)->(%s %s)\n", This
, debugstr_w(szProperty
), debugstr_variant(pvtValue
));
1955 static HRESULT WINAPI
webbrowser_get_Name(IWebBrowser2
*iface
, BSTR
*Name
)
1957 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1958 FIXME("(%p)->(%p)\n", This
, Name
);
1962 static HRESULT WINAPI
webbrowser_get_HWND(IWebBrowser2
*iface
, SHANDLE_PTR
*pHWND
)
1964 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1965 FIXME("(%p)->(%p)\n", This
, pHWND
);
1969 static HRESULT WINAPI
webbrowser_get_FullName(IWebBrowser2
*iface
, BSTR
*FullName
)
1971 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1972 FIXME("(%p)->(%p)\n", This
, FullName
);
1976 static HRESULT WINAPI
webbrowser_get_Path(IWebBrowser2
*iface
, BSTR
*Path
)
1978 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1979 FIXME("(%p)->(%p)\n", This
, Path
);
1983 static HRESULT WINAPI
webbrowser_get_Visible(IWebBrowser2
*iface
, VARIANT_BOOL
*pBool
)
1985 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1986 FIXME("(%p)->(%p)\n", This
, pBool
);
1990 static HRESULT WINAPI
webbrowser_put_Visible(IWebBrowser2
*iface
, VARIANT_BOOL Value
)
1992 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
1993 FIXME("(%p)->(%x)\n", This
, Value
);
1997 static HRESULT WINAPI
webbrowser_get_StatusBar(IWebBrowser2
*iface
, VARIANT_BOOL
*pBool
)
1999 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2000 FIXME("(%p)->(%p)\n", This
, pBool
);
2004 static HRESULT WINAPI
webbrowser_put_StatusBar(IWebBrowser2
*iface
, VARIANT_BOOL Value
)
2006 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2007 FIXME("(%p)->(%x)\n", This
, Value
);
2011 static HRESULT WINAPI
webbrowser_get_StatusText(IWebBrowser2
*iface
, BSTR
*StatusText
)
2013 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2014 FIXME("(%p)->(%p)\n", This
, StatusText
);
2018 static HRESULT WINAPI
webbrowser_put_StatusText(IWebBrowser2
*iface
, BSTR StatusText
)
2020 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2021 FIXME("(%p)->(%s)\n", This
, debugstr_w(StatusText
));
2025 static HRESULT WINAPI
webbrowser_get_ToolBar(IWebBrowser2
*iface
, int *Value
)
2027 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2028 FIXME("(%p)->(%p)\n", This
, Value
);
2032 static HRESULT WINAPI
webbrowser_put_ToolBar(IWebBrowser2
*iface
, int Value
)
2034 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2035 FIXME("(%p)->(%x)\n", This
, Value
);
2039 static HRESULT WINAPI
webbrowser_get_MenuBar(IWebBrowser2
*iface
, VARIANT_BOOL
*Value
)
2041 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2042 FIXME("(%p)->(%p)\n", This
, Value
);
2046 static HRESULT WINAPI
webbrowser_put_MenuBar(IWebBrowser2
*iface
, VARIANT_BOOL Value
)
2048 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2049 FIXME("(%p)->(%x)\n", This
, Value
);
2053 static HRESULT WINAPI
webbrowser_get_FullScreen(IWebBrowser2
*iface
, VARIANT_BOOL
*pbFullScreen
)
2055 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2056 FIXME("(%p)->(%p)\n", This
, pbFullScreen
);
2060 static HRESULT WINAPI
webbrowser_put_FullScreen(IWebBrowser2
*iface
, VARIANT_BOOL bFullScreen
)
2062 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2063 FIXME("(%p)->(%x)\n", This
, bFullScreen
);
2067 static HRESULT WINAPI
webbrowser_Navigate2(IWebBrowser2
*iface
, VARIANT
*URL
, VARIANT
*Flags
,
2068 VARIANT
*TargetFrameName
, VARIANT
*PostData
, VARIANT
*Headers
)
2070 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2071 FIXME("(%p)->(%s %s %s %s %s)\n", This
, debugstr_variant(URL
), debugstr_variant(Flags
),
2072 debugstr_variant(TargetFrameName
), debugstr_variant(PostData
), debugstr_variant(Headers
));
2076 static HRESULT WINAPI
webbrowser_QueryStatusWB(IWebBrowser2
*iface
, OLECMDID cmdID
, OLECMDF
*pcmdf
)
2078 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2079 FIXME("(%p)->(%d %p)\n", This
, cmdID
, pcmdf
);
2083 static HRESULT WINAPI
webbrowser_ExecWB(IWebBrowser2
*iface
, OLECMDID cmdID
,
2084 OLECMDEXECOPT cmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2086 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2087 FIXME("(%p)->(%d %d %s %p)\n", This
, cmdID
, cmdexecopt
, debugstr_variant(pvaIn
), pvaOut
);
2091 static HRESULT WINAPI
webbrowser_ShowBrowserBar(IWebBrowser2
*iface
, VARIANT
*pvaClsid
,
2092 VARIANT
*pvarShow
, VARIANT
*pvarSize
)
2094 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2095 FIXME("(%p)->(%s %s %s)\n", This
, debugstr_variant(pvaClsid
), debugstr_variant(pvarShow
),
2096 debugstr_variant(pvarSize
));
2100 static HRESULT WINAPI
webbrowser_get_ReadyState(IWebBrowser2
*iface
, READYSTATE
*lpReadyState
)
2102 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2103 FIXME("(%p)->(%p)\n", This
, lpReadyState
);
2107 static HRESULT WINAPI
webbrowser_get_Offline(IWebBrowser2
*iface
, VARIANT_BOOL
*pbOffline
)
2109 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2110 FIXME("(%p)->(%p)\n", This
, pbOffline
);
2114 static HRESULT WINAPI
webbrowser_put_Offline(IWebBrowser2
*iface
, VARIANT_BOOL bOffline
)
2116 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2117 FIXME("(%p)->(%x)\n", This
, bOffline
);
2121 static HRESULT WINAPI
webbrowser_get_Silent(IWebBrowser2
*iface
, VARIANT_BOOL
*pbSilent
)
2123 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2124 FIXME("(%p)->(%p)\n", This
, pbSilent
);
2128 static HRESULT WINAPI
webbrowser_put_Silent(IWebBrowser2
*iface
, VARIANT_BOOL bSilent
)
2130 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2131 FIXME("(%p)->(%x)\n", This
, bSilent
);
2135 static HRESULT WINAPI
webbrowser_get_RegisterAsBrowser(IWebBrowser2
*iface
,
2136 VARIANT_BOOL
*pbRegister
)
2138 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2139 FIXME("(%p)->(%p)\n", This
, pbRegister
);
2143 static HRESULT WINAPI
webbrowser_put_RegisterAsBrowser(IWebBrowser2
*iface
,
2144 VARIANT_BOOL bRegister
)
2146 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2147 FIXME("(%p)->(%x)\n", This
, bRegister
);
2151 static HRESULT WINAPI
webbrowser_get_RegisterAsDropTarget(IWebBrowser2
*iface
,
2152 VARIANT_BOOL
*pbRegister
)
2154 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2155 FIXME("(%p)->(%p)\n", This
, pbRegister
);
2159 static HRESULT WINAPI
webbrowser_put_RegisterAsDropTarget(IWebBrowser2
*iface
,
2160 VARIANT_BOOL bRegister
)
2162 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2163 FIXME("(%p)->(%x)\n", This
, bRegister
);
2167 static HRESULT WINAPI
webbrowser_get_TheaterMode(IWebBrowser2
*iface
, VARIANT_BOOL
*pbRegister
)
2169 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2170 FIXME("(%p)->(%p)\n", This
, pbRegister
);
2174 static HRESULT WINAPI
webbrowser_put_TheaterMode(IWebBrowser2
*iface
, VARIANT_BOOL bRegister
)
2176 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2177 TRACE("(%p)->(%x)\n", This
, bRegister
);
2181 static HRESULT WINAPI
webbrowser_get_AddressBar(IWebBrowser2
*iface
, VARIANT_BOOL
*Value
)
2183 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2184 FIXME("(%p)->(%p)\n", This
, Value
);
2188 static HRESULT WINAPI
webbrowser_put_AddressBar(IWebBrowser2
*iface
, VARIANT_BOOL Value
)
2190 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2191 FIXME("(%p)->(%x)\n", This
, Value
);
2195 static HRESULT WINAPI
webbrowser_get_Resizable(IWebBrowser2
*iface
, VARIANT_BOOL
*Value
)
2197 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2198 FIXME("(%p)->(%p)\n", This
, Value
);
2202 static HRESULT WINAPI
webbrowser_put_Resizable(IWebBrowser2
*iface
, VARIANT_BOOL Value
)
2204 struct shellbrowserwindow
*This
= impl_from_IWebBrowser2(iface
);
2205 FIXME("(%p)->(%x)\n", This
, Value
);
2209 static const IWebBrowser2Vtbl webbrowser2vtbl
=
2211 webbrowser_QueryInterface
,
2214 webbrowser_GetTypeInfoCount
,
2215 webbrowser_GetTypeInfo
,
2216 webbrowser_GetIDsOfNames
,
2219 webbrowser_GoForward
,
2221 webbrowser_GoSearch
,
2222 webbrowser_Navigate
,
2224 webbrowser_Refresh2
,
2226 webbrowser_get_Application
,
2227 webbrowser_get_Parent
,
2228 webbrowser_get_Container
,
2229 webbrowser_get_Document
,
2230 webbrowser_get_TopLevelContainer
,
2231 webbrowser_get_Type
,
2232 webbrowser_get_Left
,
2233 webbrowser_put_Left
,
2236 webbrowser_get_Width
,
2237 webbrowser_put_Width
,
2238 webbrowser_get_Height
,
2239 webbrowser_put_Height
,
2240 webbrowser_get_LocationName
,
2241 webbrowser_get_LocationURL
,
2242 webbrowser_get_Busy
,
2244 webbrowser_ClientToWindow
,
2245 webbrowser_PutProperty
,
2246 webbrowser_GetProperty
,
2247 webbrowser_get_Name
,
2248 webbrowser_get_HWND
,
2249 webbrowser_get_FullName
,
2250 webbrowser_get_Path
,
2251 webbrowser_get_Visible
,
2252 webbrowser_put_Visible
,
2253 webbrowser_get_StatusBar
,
2254 webbrowser_put_StatusBar
,
2255 webbrowser_get_StatusText
,
2256 webbrowser_put_StatusText
,
2257 webbrowser_get_ToolBar
,
2258 webbrowser_put_ToolBar
,
2259 webbrowser_get_MenuBar
,
2260 webbrowser_put_MenuBar
,
2261 webbrowser_get_FullScreen
,
2262 webbrowser_put_FullScreen
,
2263 webbrowser_Navigate2
,
2264 webbrowser_QueryStatusWB
,
2266 webbrowser_ShowBrowserBar
,
2267 webbrowser_get_ReadyState
,
2268 webbrowser_get_Offline
,
2269 webbrowser_put_Offline
,
2270 webbrowser_get_Silent
,
2271 webbrowser_put_Silent
,
2272 webbrowser_get_RegisterAsBrowser
,
2273 webbrowser_put_RegisterAsBrowser
,
2274 webbrowser_get_RegisterAsDropTarget
,
2275 webbrowser_put_RegisterAsDropTarget
,
2276 webbrowser_get_TheaterMode
,
2277 webbrowser_put_TheaterMode
,
2278 webbrowser_get_AddressBar
,
2279 webbrowser_put_AddressBar
,
2280 webbrowser_get_Resizable
,
2281 webbrowser_put_Resizable
2284 static HRESULT WINAPI
serviceprovider_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **ppv
)
2286 struct shellbrowserwindow
*This
= impl_from_IServiceProvider(iface
);
2287 return IWebBrowser2_QueryInterface(&This
->IWebBrowser2_iface
, riid
, ppv
);
2290 static ULONG WINAPI
serviceprovider_AddRef(IServiceProvider
*iface
)
2292 struct shellbrowserwindow
*This
= impl_from_IServiceProvider(iface
);
2293 return IWebBrowser2_AddRef(&This
->IWebBrowser2_iface
);
2296 static ULONG WINAPI
serviceprovider_Release(IServiceProvider
*iface
)
2298 struct shellbrowserwindow
*This
= impl_from_IServiceProvider(iface
);
2299 return IWebBrowser2_Release(&This
->IWebBrowser2_iface
);
2302 static HRESULT WINAPI
serviceprovider_QueryService(IServiceProvider
*iface
, REFGUID service
,
2303 REFIID riid
, void **ppv
)
2305 struct shellbrowserwindow
*This
= impl_from_IServiceProvider(iface
);
2307 TRACE("%s %s %p\n", debugstr_guid(service
), debugstr_guid(riid
), ppv
);
2309 if (IsEqualGUID(service
, &SID_STopLevelBrowser
))
2310 return IShellBrowser_QueryInterface(&This
->IShellBrowser_iface
, riid
, ppv
);
2312 WARN("unknown service id %s\n", debugstr_guid(service
));
2316 static const IServiceProviderVtbl serviceprovidervtbl
=
2318 serviceprovider_QueryInterface
,
2319 serviceprovider_AddRef
,
2320 serviceprovider_Release
,
2321 serviceprovider_QueryService
2325 static HRESULT WINAPI
shellbrowser_QueryInterface(IShellBrowser
*iface
, REFIID riid
, void **ppv
)
2327 TRACE("%s %p\n", debugstr_guid(riid
), ppv
);
2331 if (IsEqualGUID(&IID_IShellBrowser
, riid
) ||
2332 IsEqualGUID(&IID_IOleWindow
, riid
) ||
2333 IsEqualGUID(&IID_IUnknown
, riid
))
2340 IUnknown_AddRef((IUnknown
*)*ppv
);
2344 return E_NOINTERFACE
;
2347 static ULONG WINAPI
shellbrowser_AddRef(IShellBrowser
*iface
)
2349 struct shellbrowserwindow
*This
= impl_from_IShellBrowser(iface
);
2350 return IWebBrowser2_AddRef(&This
->IWebBrowser2_iface
);
2353 static ULONG WINAPI
shellbrowser_Release(IShellBrowser
*iface
)
2355 struct shellbrowserwindow
*This
= impl_from_IShellBrowser(iface
);
2356 return IWebBrowser2_Release(&This
->IWebBrowser2_iface
);
2359 static HRESULT WINAPI
shellbrowser_GetWindow(IShellBrowser
*iface
, HWND
*phwnd
)
2361 FIXME("%p\n", phwnd
);
2365 static HRESULT WINAPI
shellbrowser_ContextSensitiveHelp(IShellBrowser
*iface
, BOOL mode
)
2367 FIXME("%d\n", mode
);
2371 static HRESULT WINAPI
shellbrowser_InsertMenusSB(IShellBrowser
*iface
, HMENU hmenuShared
,
2372 OLEMENUGROUPWIDTHS
*menuwidths
)
2374 FIXME("%p %p\n", hmenuShared
, menuwidths
);
2378 static HRESULT WINAPI
shellbrowser_SetMenuSB(IShellBrowser
*iface
, HMENU hmenuShared
,
2379 HOLEMENU holemenuReserved
, HWND hwndActiveObject
)
2381 FIXME("%p %p %p\n", hmenuShared
, holemenuReserved
, hwndActiveObject
);
2385 static HRESULT WINAPI
shellbrowser_RemoveMenusSB(IShellBrowser
*iface
, HMENU hmenuShared
)
2387 FIXME("%p\n", hmenuShared
);
2391 static HRESULT WINAPI
shellbrowser_SetStatusTextSB(IShellBrowser
*iface
, LPCOLESTR text
)
2393 FIXME("%s\n", debugstr_w(text
));
2397 static HRESULT WINAPI
shellbrowser_EnableModelessSB(IShellBrowser
*iface
, BOOL enable
)
2399 FIXME("%d\n", enable
);
2403 static HRESULT WINAPI
shellbrowser_TranslateAcceleratorSB(IShellBrowser
*iface
, MSG
*pmsg
, WORD wID
)
2405 FIXME("%p 0x%x\n", pmsg
, wID
);
2409 static HRESULT WINAPI
shellbrowser_BrowseObject(IShellBrowser
*iface
, LPCITEMIDLIST pidl
, UINT flags
)
2411 FIXME("%p %x\n", pidl
, flags
);
2415 static HRESULT WINAPI
shellbrowser_GetViewStateStream(IShellBrowser
*iface
, DWORD mode
, IStream
**stream
)
2417 FIXME("0x%lx %p\n", mode
, stream
);
2421 static HRESULT WINAPI
shellbrowser_GetControlWindow(IShellBrowser
*iface
, UINT id
, HWND
*phwnd
)
2423 FIXME("%d %p\n", id
, phwnd
);
2427 static HRESULT WINAPI
shellbrowser_SendControlMsg(IShellBrowser
*iface
, UINT id
, UINT uMsg
,
2428 WPARAM wParam
, LPARAM lParam
, LRESULT
*pret
)
2430 FIXME("%d %d %Ix %Ix %p\n", id
, uMsg
, wParam
, lParam
, pret
);
2434 static HRESULT WINAPI
shellbrowser_QueryActiveShellView(IShellBrowser
*iface
, IShellView
**view
)
2436 TRACE("%p\n", view
);
2438 *view
= desktopshellbrowserwindow
.view
;
2439 IShellView_AddRef(*view
);
2443 static HRESULT WINAPI
shellbrowser_OnViewWindowActive(IShellBrowser
*iface
, IShellView
*view
)
2445 FIXME("%p\n", view
);
2449 static HRESULT WINAPI
shellbrowser_SetToolbarItems(IShellBrowser
*iface
, LPTBBUTTONSB buttons
,
2450 UINT count
, UINT flags
)
2452 FIXME("%p %d 0x%x\n", buttons
, count
, flags
);
2456 static const IShellBrowserVtbl shellbrowservtbl
= {
2457 shellbrowser_QueryInterface
,
2458 shellbrowser_AddRef
,
2459 shellbrowser_Release
,
2460 shellbrowser_GetWindow
,
2461 shellbrowser_ContextSensitiveHelp
,
2462 shellbrowser_InsertMenusSB
,
2463 shellbrowser_SetMenuSB
,
2464 shellbrowser_RemoveMenusSB
,
2465 shellbrowser_SetStatusTextSB
,
2466 shellbrowser_EnableModelessSB
,
2467 shellbrowser_TranslateAcceleratorSB
,
2468 shellbrowser_BrowseObject
,
2469 shellbrowser_GetViewStateStream
,
2470 shellbrowser_GetControlWindow
,
2471 shellbrowser_SendControlMsg
,
2472 shellbrowser_QueryActiveShellView
,
2473 shellbrowser_OnViewWindowActive
,
2474 shellbrowser_SetToolbarItems
2477 static void desktopshellbrowserwindow_init(void)
2479 IShellFolder
*folder
;
2481 desktopshellbrowserwindow
.IWebBrowser2_iface
.lpVtbl
= &webbrowser2vtbl
;
2482 desktopshellbrowserwindow
.IServiceProvider_iface
.lpVtbl
= &serviceprovidervtbl
;
2483 desktopshellbrowserwindow
.IShellBrowser_iface
.lpVtbl
= &shellbrowservtbl
;
2485 if (FAILED(SHGetDesktopFolder(&folder
)))
2488 IShellFolder_CreateViewObject(folder
, NULL
, &IID_IShellView
, (void**)&desktopshellbrowserwindow
.view
);
2491 static void shellwindows_init(void)
2497 shellwindows
.IShellWindows_iface
.lpVtbl
= &shellwindowsvtbl
;
2498 InitializeCriticalSectionEx(&shellwindows
.cs
, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
);
2499 shellwindows
.cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": shellwindows.cs");
2501 hr
= CoRegisterClassObject(&CLSID_ShellWindows
,
2502 (IUnknown
*)&shellwindows_classfactory
.IClassFactory_iface
,
2503 CLSCTX_LOCAL_SERVER
,
2505 &shellwindows_classfactory
.classreg
);
2508 WARN("Failed to register ShellWindows object: %08lx\n", hr
);