4 * Copyright 2004 CodeWeavers, Mike Hearn
5 * Copyright 2005,2006 CodeWeavers, Aric Stewart
6 * Copyright 2011 Jay Yang
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define NONAMELESSUNION
26 #include "wine/unicode.h"
27 #include "wine/debug.h"
28 #include "explorer_private.h"
35 #include <commoncontrols.h>
38 WINE_DEFAULT_DEBUG_CHANNEL(explorer
);
40 #define EXPLORER_INFO_INDEX 0
42 #define NAV_TOOLBAR_HEIGHT 30
43 #define PATHBOX_HEIGHT 24
45 #define DEFAULT_WIDTH 640
46 #define DEFAULT_HEIGHT 480
49 static const WCHAR EXPLORER_CLASS
[] = {'W','I','N','E','_','E','X','P','L','O','R','E','R','\0'};
50 static const WCHAR PATH_BOX_NAME
[] = {'\0'};
52 HINSTANCE explorer_hInstance
;
54 typedef struct parametersTAG
{
57 WCHAR selection
[MAX_PATH
];
62 IExplorerBrowser
*browser
;
63 HWND main_window
,path_box
;
66 IImageList
*icon_list
;
71 BACK_BUTTON
,FORWARD_BUTTON
,UP_BUTTON
76 IExplorerBrowserEvents IExplorerBrowserEvents_iface
;
79 } IExplorerBrowserEventsImpl
;
81 static IExplorerBrowserEventsImpl
*impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents
*iface
)
83 return CONTAINING_RECORD(iface
, IExplorerBrowserEventsImpl
, IExplorerBrowserEvents_iface
);
86 static HRESULT WINAPI
IExplorerBrowserEventsImpl_fnQueryInterface(IExplorerBrowserEvents
*iface
, REFIID riid
, void **ppvObject
)
91 static ULONG WINAPI
IExplorerBrowserEventsImpl_fnAddRef(IExplorerBrowserEvents
*iface
)
93 IExplorerBrowserEventsImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
94 return InterlockedIncrement(&This
->ref
);
97 static ULONG WINAPI
IExplorerBrowserEventsImpl_fnRelease(IExplorerBrowserEvents
*iface
)
99 IExplorerBrowserEventsImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
100 ULONG ref
= InterlockedDecrement(&This
->ref
);
102 HeapFree(GetProcessHeap(),0,This
);
106 static BOOL
create_combobox_item(IShellFolder
*folder
, LPCITEMIDLIST pidl
, IImageList
*icon_list
, COMBOBOXEXITEMW
*item
)
110 IExtractIconW
*extract_icon
;
112 WCHAR icon_file
[MAX_PATH
];
116 strret
.uType
=STRRET_WSTR
;
117 hres
= IShellFolder_GetDisplayNameOf(folder
,pidl
,SHGDN_FORADDRESSBAR
,&strret
);
120 WINE_WARN("Could not get name for pidl\n");
126 item
->pszText
= strret
.u
.pOleStr
;
129 WINE_FIXME("Unimplemented STRRET type:%u\n",strret
.uType
);
132 hres
= IShellFolder_GetUIObjectOf(folder
,NULL
,1,&pidl
,&IID_IExtractIconW
,
133 &reserved
,(void**)&extract_icon
);
136 item
->mask
|= CBEIF_IMAGE
;
137 IExtractIconW_GetIconLocation(extract_icon
,GIL_FORSHELL
,icon_file
,
138 sizeof(icon_file
)/sizeof(WCHAR
),
139 &icon_index
,&icon_flags
);
140 IExtractIconW_Extract(extract_icon
,icon_file
,icon_index
,NULL
,&icon
,20);
141 item
->iImage
= ImageList_AddIcon((HIMAGELIST
)icon_list
,icon
);
145 item
->mask
&= ~CBEIF_IMAGE
;
146 WINE_WARN("Could not get an icon for %s\n",wine_dbgstr_w(item
->pszText
));
151 static void update_path_box(explorer_info
*info
)
153 COMBOBOXEXITEMW item
;
154 COMBOBOXEXITEMW main_item
;
155 IShellFolder
*desktop
;
156 IPersistFolder2
*persist
;
157 LPITEMIDLIST desktop_pidl
;
160 ImageList_Remove((HIMAGELIST
)info
->icon_list
,-1);
161 SendMessageW(info
->path_box
,CB_RESETCONTENT
,0,0);
162 SHGetDesktopFolder(&desktop
);
163 IShellFolder_QueryInterface(desktop
,&IID_IPersistFolder2
,(void**)&persist
);
164 IPersistFolder2_GetCurFolder(persist
,&desktop_pidl
);
165 IPersistFolder2_Release(persist
);
169 item
.mask
= CBEIF_TEXT
| CBEIF_INDENT
| CBEIF_LPARAM
;
171 create_combobox_item(desktop
,desktop_pidl
,info
->icon_list
,&item
);
172 item
.lParam
= (LPARAM
)desktop_pidl
;
173 SendMessageW(info
->path_box
,CBEM_INSERTITEMW
,0,(LPARAM
)&item
);
174 if(ILIsEqual(info
->pidl
,desktop_pidl
))
177 CoTaskMemFree(item
.pszText
);
178 /*Add all direct subfolders of Desktop*/
179 if(SUCCEEDED(IShellFolder_EnumObjects(desktop
,NULL
,SHCONTF_FOLDERS
,&ids
))
182 LPITEMIDLIST curr_pidl
;
188 hres
= IEnumIDList_Next(ids
,1,&curr_pidl
,NULL
);
189 if(FAILED(hres
) || hres
== S_FALSE
)
191 if(!create_combobox_item(desktop
,curr_pidl
,info
->icon_list
,&item
))
192 WINE_WARN("Could not create a combobox item\n");
195 LPITEMIDLIST full_pidl
= ILCombine(desktop_pidl
,curr_pidl
);
196 item
.lParam
= (LPARAM
)full_pidl
;
197 SendMessageW(info
->path_box
,CBEM_INSERTITEMW
,0,(LPARAM
)&item
);
198 if(ILIsEqual(full_pidl
,info
->pidl
))
200 else if(ILIsParent(full_pidl
,info
->pidl
,FALSE
))
202 /*add all parents of the pidl passed in*/
203 LPITEMIDLIST next_pidl
= ILFindChild(full_pidl
,info
->pidl
);
204 IShellFolder
*curr_folder
= NULL
, *temp
;
205 hres
= IShellFolder_BindToObject(desktop
,curr_pidl
,NULL
,
207 (void**)&curr_folder
);
209 WINE_WARN("Could not get an IShellFolder\n");
210 while(!ILIsEmpty(next_pidl
))
212 LPITEMIDLIST first
= ILCloneFirst(next_pidl
);
213 CoTaskMemFree(item
.pszText
);
214 if(!create_combobox_item(curr_folder
,first
,
215 info
->icon_list
,&item
))
217 WINE_WARN("Could not create a combobox item\n");
221 full_pidl
= ILCombine(full_pidl
,first
);
222 item
.lParam
= (LPARAM
)full_pidl
;
223 SendMessageW(info
->path_box
,CBEM_INSERTITEMW
,0,(LPARAM
)&item
);
225 hres
= IShellFolder_BindToObject(curr_folder
,first
,NULL
,
230 WINE_WARN("Could not get an IShellFolder\n");
233 IShellFolder_Release(curr_folder
);
237 next_pidl
= ILGetNext(next_pidl
);
239 memcpy(&main_item
,&item
,sizeof(item
));
241 IShellFolder_Release(curr_folder
);
245 CoTaskMemFree(item
.pszText
);
250 WINE_WARN("Could not enumerate the desktop\n");
251 SendMessageW(info
->path_box
,CBEM_SETITEMW
,0,(LPARAM
)&main_item
);
252 CoTaskMemFree(main_item
.pszText
);
255 static HRESULT WINAPI
IExplorerBrowserEventsImpl_fnOnNavigationComplete(IExplorerBrowserEvents
*iface
, PCIDLIST_ABSOLUTE pidl
)
257 IExplorerBrowserEventsImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
258 This
->info
->pidl
= pidl
;
259 update_path_box(This
->info
);
263 static HRESULT WINAPI
IExplorerBrowserEventsImpl_fnOnNavigationFailed(IExplorerBrowserEvents
*iface
, PCIDLIST_ABSOLUTE pidl
)
268 static HRESULT WINAPI
IExplorerBrowserEventsImpl_fnOnNavigationPending(IExplorerBrowserEvents
*iface
, PCIDLIST_ABSOLUTE pidl
)
273 static HRESULT WINAPI
IExplorerBrowserEventsImpl_fnOnViewCreated(IExplorerBrowserEvents
*iface
, IShellView
*psv
)
278 static IExplorerBrowserEventsVtbl vt_IExplorerBrowserEvents
=
280 IExplorerBrowserEventsImpl_fnQueryInterface
,
281 IExplorerBrowserEventsImpl_fnAddRef
,
282 IExplorerBrowserEventsImpl_fnRelease
,
283 IExplorerBrowserEventsImpl_fnOnNavigationPending
,
284 IExplorerBrowserEventsImpl_fnOnViewCreated
,
285 IExplorerBrowserEventsImpl_fnOnNavigationComplete
,
286 IExplorerBrowserEventsImpl_fnOnNavigationFailed
289 static IExplorerBrowserEvents
*make_explorer_events(explorer_info
*info
)
291 IExplorerBrowserEventsImpl
*ret
292 = HeapAlloc(GetProcessHeap(), 0, sizeof(IExplorerBrowserEventsImpl
));
293 ret
->IExplorerBrowserEvents_iface
.lpVtbl
= &vt_IExplorerBrowserEvents
;
295 SHGetImageList(SHIL_SMALL
,&IID_IImageList
,(void**)&(ret
->info
->icon_list
));
296 SendMessageW(info
->path_box
,CBEM_SETIMAGELIST
,0,(LPARAM
)ret
->info
->icon_list
);
297 IExplorerBrowserEvents_AddRef(&ret
->IExplorerBrowserEvents_iface
);
298 return &ret
->IExplorerBrowserEvents_iface
;
301 static void make_explorer_window(IShellFolder
* startFolder
)
304 HWND rebar
,nav_toolbar
;
306 IExplorerBrowserEvents
*events
;
310 WCHAR explorer_title
[100];
311 WCHAR pathbox_label
[50];
312 TBADDBITMAP bitmap_info
;
313 TBBUTTON nav_buttons
[3];
314 int hist_offset
,view_offset
;
315 REBARBANDINFOW band_info
;
316 memset(nav_buttons
,0,sizeof(nav_buttons
));
317 LoadStringW(explorer_hInstance
,IDS_EXPLORER_TITLE
,explorer_title
,
318 sizeof(explorer_title
)/sizeof(WCHAR
));
319 LoadStringW(explorer_hInstance
,IDS_PATHBOX_LABEL
,pathbox_label
,
320 sizeof(pathbox_label
)/sizeof(WCHAR
));
321 info
= HeapAlloc(GetProcessHeap(),0,sizeof(explorer_info
));
324 WINE_ERR("Could not allocate a explorer_info struct\n");
327 hres
= CoCreateInstance(&CLSID_ExplorerBrowser
,NULL
,CLSCTX_INPROC_SERVER
,
328 &IID_IExplorerBrowser
,(LPVOID
*)&info
->browser
);
331 WINE_ERR("Could not obtain an instance of IExplorerBrowser\n");
332 HeapFree(GetProcessHeap(),0,info
);
335 info
->rebar_height
=0;
337 = CreateWindowW(EXPLORER_CLASS
,explorer_title
,WS_OVERLAPPEDWINDOW
,
338 CW_USEDEFAULT
,CW_USEDEFAULT
,DEFAULT_WIDTH
,
339 DEFAULT_HEIGHT
,NULL
,NULL
,explorer_hInstance
,NULL
);
341 fs
.ViewMode
= FVM_DETAILS
;
342 fs
.fFlags
= FWF_AUTOARRANGE
;
343 explorerRect
.left
= 0;
344 explorerRect
.top
= 0;
345 explorerRect
.right
= DEFAULT_WIDTH
;
346 explorerRect
.bottom
= DEFAULT_HEIGHT
;
348 IExplorerBrowser_Initialize(info
->browser
,info
->main_window
,&explorerRect
,&fs
);
349 IExplorerBrowser_SetOptions(info
->browser
,EBO_SHOWFRAMES
);
350 SetWindowLongPtrW(info
->main_window
,EXPLORER_INFO_INDEX
,(LONG_PTR
)info
);
353 rebar
= CreateWindowExW(WS_EX_TOOLWINDOW
,REBARCLASSNAMEW
,NULL
,
354 WS_CHILD
|WS_VISIBLE
|RBS_VARHEIGHT
|CCS_TOP
|CCS_NODIVIDER
,
355 0,0,0,0,info
->main_window
,NULL
,explorer_hInstance
,NULL
);
357 = CreateWindowExW(TBSTYLE_EX_MIXEDBUTTONS
,TOOLBARCLASSNAMEW
,NULL
,
358 WS_CHILD
|WS_VISIBLE
|TBSTYLE_FLAT
,0,0,0,0,rebar
,NULL
,
359 explorer_hInstance
,NULL
);
361 bitmap_info
.hInst
= HINST_COMMCTRL
;
362 bitmap_info
.nID
= IDB_HIST_LARGE_COLOR
;
363 hist_offset
= SendMessageW(nav_toolbar
,TB_ADDBITMAP
,0,(LPARAM
)&bitmap_info
);
364 bitmap_info
.nID
= IDB_VIEW_LARGE_COLOR
;
365 view_offset
= SendMessageW(nav_toolbar
,TB_ADDBITMAP
,0,(LPARAM
)&bitmap_info
);
367 nav_buttons
[0].iBitmap
=hist_offset
+HIST_BACK
;
368 nav_buttons
[0].idCommand
=BACK_BUTTON
;
369 nav_buttons
[0].fsState
=TBSTATE_ENABLED
;
370 nav_buttons
[0].fsStyle
=BTNS_BUTTON
|BTNS_AUTOSIZE
;
371 nav_buttons
[1].iBitmap
=hist_offset
+HIST_FORWARD
;
372 nav_buttons
[1].idCommand
=FORWARD_BUTTON
;
373 nav_buttons
[1].fsState
=TBSTATE_ENABLED
;
374 nav_buttons
[1].fsStyle
=BTNS_BUTTON
|BTNS_AUTOSIZE
;
375 nav_buttons
[2].iBitmap
=view_offset
+VIEW_PARENTFOLDER
;
376 nav_buttons
[2].idCommand
=UP_BUTTON
;
377 nav_buttons
[2].fsState
=TBSTATE_ENABLED
;
378 nav_buttons
[2].fsStyle
=BTNS_BUTTON
|BTNS_AUTOSIZE
;
379 SendMessageW(nav_toolbar
,TB_BUTTONSTRUCTSIZE
,sizeof(TBBUTTON
),0);
380 SendMessageW(nav_toolbar
,TB_ADDBUTTONSW
,sizeof(nav_buttons
)/sizeof(TBBUTTON
),(LPARAM
)nav_buttons
);
382 band_info
.cbSize
= sizeof(band_info
);
383 band_info
.fMask
= RBBIM_STYLE
|RBBIM_CHILD
|RBBIM_CHILDSIZE
|RBBIM_SIZE
;
384 band_info
.hwndChild
= nav_toolbar
;
385 band_info
.fStyle
=RBBS_GRIPPERALWAYS
|RBBS_CHILDEDGE
;
386 band_info
.cyChild
=NAV_TOOLBAR_HEIGHT
;
388 band_info
.cyMinChild
=NAV_TOOLBAR_HEIGHT
;
389 band_info
.cxMinChild
=0;
390 SendMessageW(rebar
,RB_INSERTBANDW
,-1,(LPARAM
)&band_info
);
391 info
->path_box
= CreateWindowW(WC_COMBOBOXEXW
,PATH_BOX_NAME
,
392 WS_CHILD
| WS_VISIBLE
| CBS_DROPDOWN
,
393 0,0,DEFAULT_WIDTH
,PATHBOX_HEIGHT
,rebar
,NULL
,
394 explorer_hInstance
,NULL
);
395 band_info
.cyChild
=PATHBOX_HEIGHT
;
397 band_info
.cyMinChild
=PATHBOX_HEIGHT
;
398 band_info
.cxMinChild
=0;
399 band_info
.fMask
|=RBBIM_TEXT
;
400 band_info
.lpText
=pathbox_label
;
401 band_info
.fStyle
|=RBBS_BREAK
;
402 band_info
.hwndChild
=info
->path_box
;
403 SendMessageW(rebar
,RB_INSERTBANDW
,-1,(LPARAM
)&band_info
);
404 events
= make_explorer_events(info
);
405 IExplorerBrowser_Advise(info
->browser
,events
,&cookie
);
406 IExplorerBrowser_BrowseToObject(info
->browser
,(IUnknown
*)startFolder
,
408 ShowWindow(info
->main_window
,SW_SHOWDEFAULT
);
409 UpdateWindow(info
->main_window
);
410 IExplorerBrowserEvents_Release(events
);
413 static void update_window_size(explorer_info
*info
, int height
, int width
)
417 new_rect
.top
= info
->rebar_height
;
418 new_rect
.right
= width
;
419 new_rect
.bottom
= height
;
420 IExplorerBrowser_SetRect(info
->browser
,NULL
,new_rect
);
423 static void do_exit(int code
)
429 static LRESULT
explorer_on_end_edit(explorer_info
*info
,NMCBEENDEDITW
*edit_info
)
431 LPITEMIDLIST pidl
= NULL
;
433 WINE_TRACE("iWhy=%x\n",edit_info
->iWhy
);
434 switch(edit_info
->iWhy
)
437 if(edit_info
->iNewSelection
!=CB_ERR
)
438 pidl
= (LPITEMIDLIST
)SendMessageW(edit_info
->hdr
.hwndFrom
,
440 edit_info
->iNewSelection
,0);
444 WCHAR path
[MAX_PATH
];
445 HWND edit_ctrl
= (HWND
)SendMessageW(edit_info
->hdr
.hwndFrom
,
446 CBEM_GETEDITCONTROL
,0,0);
447 *((WORD
*)path
)=MAX_PATH
;
448 SendMessageW(edit_ctrl
,EM_GETLINE
,0,(LPARAM
)path
);
449 pidl
= ILCreateFromPathW(path
);
453 /*make sure the that the path box resets*/
454 update_path_box(info
);
460 IExplorerBrowser_BrowseToIDList(info
->browser
,pidl
,SBSP_ABSOLUTE
);
461 if(edit_info
->iWhy
==CBENF_RETURN
)
466 static LRESULT
update_rebar_size(explorer_info
* info
,NMRBAUTOSIZE
*size_info
)
470 info
->rebar_height
= size_info
->rcTarget
.bottom
-size_info
->rcTarget
.top
;
471 GetWindowRect(info
->main_window
,&window_rect
);
473 new_rect
.top
= info
->rebar_height
;
474 new_rect
.right
= window_rect
.right
-window_rect
.left
;
475 new_rect
.bottom
= window_rect
.bottom
-window_rect
.top
;
476 IExplorerBrowser_SetRect(info
->browser
,NULL
,new_rect
);
480 static LRESULT
explorer_on_notify(explorer_info
* info
,NMHDR
* notification
)
482 WINE_TRACE("code=%i\n",notification
->code
);
483 switch(notification
->code
)
487 WCHAR path
[MAX_PATH
];
488 HWND edit_ctrl
= (HWND
)SendMessageW(notification
->hwndFrom
,
489 CBEM_GETEDITCONTROL
,0,0);
490 SHGetPathFromIDListW(info
->pidl
,path
);
491 SetWindowTextW(edit_ctrl
,path
);
496 NMCBEENDEDITA
*edit_info_a
= (NMCBEENDEDITA
*)notification
;
497 NMCBEENDEDITW edit_info_w
;
498 edit_info_w
.hdr
= edit_info_a
->hdr
;
499 edit_info_w
.fChanged
= edit_info_a
->fChanged
;
500 edit_info_w
.iNewSelection
= edit_info_a
->iNewSelection
;
501 MultiByteToWideChar(CP_ACP
,0,edit_info_a
->szText
,-1,
502 edit_info_w
.szText
,CBEMAXSTRLEN
);
503 edit_info_w
.iWhy
= edit_info_a
->iWhy
;
504 return explorer_on_end_edit(info
,&edit_info_w
);
507 return explorer_on_end_edit(info
,(NMCBEENDEDITW
*)notification
);
508 case CBEN_DELETEITEM
:
510 NMCOMBOBOXEXW
*entry
= (NMCOMBOBOXEXW
*)notification
;
511 if(entry
->ceItem
.lParam
)
512 ILFree((LPITEMIDLIST
)entry
->ceItem
.lParam
);
516 return update_rebar_size(info
,(NMRBAUTOSIZE
*)notification
);
523 static LRESULT CALLBACK
explorer_wnd_proc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
526 = (explorer_info
*)GetWindowLongPtrW(hwnd
,EXPLORER_INFO_INDEX
);
527 IExplorerBrowser
*browser
= NULL
;
529 WINE_TRACE("(hwnd=%p,uMsg=%u,wParam=%lx,lParam=%lx)\n",hwnd
,uMsg
,wParam
,lParam
);
531 browser
= info
->browser
;
535 IExplorerBrowser_Release(browser
);
536 HeapFree(GetProcessHeap(),0,info
);
542 return explorer_on_notify(info
,(NMHDR
*)lParam
);
544 if(HIWORD(wParam
)==BN_CLICKED
)
546 switch(LOWORD(wParam
))
549 IExplorerBrowser_BrowseToObject(browser
,NULL
,SBSP_NAVIGATEBACK
);
552 IExplorerBrowser_BrowseToObject(browser
,NULL
,SBSP_NAVIGATEFORWARD
);
555 IExplorerBrowser_BrowseToObject(browser
,NULL
,SBSP_PARENT
);
561 update_window_size(info
,HIWORD(lParam
),LOWORD(lParam
));
564 return DefWindowProcW(hwnd
,uMsg
,wParam
,lParam
);
569 static void register_explorer_window_class(void)
571 WNDCLASSEXW window_class
;
572 window_class
.cbSize
= sizeof(WNDCLASSEXW
);
573 window_class
.style
= 0;
574 window_class
.cbClsExtra
= 0;
575 window_class
.cbWndExtra
= sizeof(LONG_PTR
);
576 window_class
.lpfnWndProc
= explorer_wnd_proc
;
577 window_class
.hInstance
= explorer_hInstance
;
578 window_class
.hIcon
= NULL
;
579 window_class
.hCursor
= NULL
;
580 window_class
.hbrBackground
= (HBRUSH
)COLOR_BACKGROUND
;
581 window_class
.lpszMenuName
= NULL
;
582 window_class
.lpszClassName
= EXPLORER_CLASS
;
583 window_class
.hIconSm
= NULL
;
584 RegisterClassExW(&window_class
);
587 static IShellFolder
* get_starting_shell_folder(parameters_struct
* params
)
589 IShellFolder
* desktop
,*folder
;
590 LPITEMIDLIST root_pidl
;
593 SHGetDesktopFolder(&desktop
);
594 if (!params
->root
[0])
598 hres
= IShellFolder_ParseDisplayName(desktop
,NULL
,NULL
,
606 hres
= IShellFolder_BindToObject(desktop
,root_pidl
,NULL
,
613 IShellFolder_Release(desktop
);
617 static int copy_path_string(LPWSTR target
, LPWSTR source
)
621 while (isspaceW(*source
)) source
++;
626 while (*source
!= '\"') target
[i
++] = *source
++;
633 while (*source
&& !isspaceW(*source
)) target
[i
++] = *source
++;
640 static void copy_path_root(LPWSTR root
, LPWSTR path
)
649 while (*p
!='\\' && p
> path
)
666 * Command Line parameters are:
667 * [/n] Opens in single-paned view for each selected items. This is default
668 * [/e,] Uses Windows Explorer View
669 * [/root,object] Specifies the root level of the view
670 * [/select,object] parent folder is opened and specified object is selected
672 static void parse_command_line(LPWSTR commandline
,parameters_struct
*parameters
)
674 static const WCHAR arg_n
[] = {'/','n'};
675 static const WCHAR arg_e
[] = {'/','e',','};
676 static const WCHAR arg_root
[] = {'/','r','o','o','t',','};
677 static const WCHAR arg_select
[] = {'/','s','e','l','e','c','t',','};
678 static const WCHAR arg_desktop
[] = {'/','d','e','s','k','t','o','p'};
683 p
= strchrW(commandline
,'/');
686 if (strncmpW(p
, arg_n
, sizeof(arg_n
)/sizeof(WCHAR
))==0)
688 parameters
->explorer_mode
= FALSE
;
689 p
+= sizeof(arg_n
)/sizeof(WCHAR
);
691 else if (strncmpW(p
, arg_e
, sizeof(arg_e
)/sizeof(WCHAR
))==0)
693 parameters
->explorer_mode
= TRUE
;
694 p
+= sizeof(arg_e
)/sizeof(WCHAR
);
696 else if (strncmpW(p
, arg_root
, sizeof(arg_root
)/sizeof(WCHAR
))==0)
698 p
+= sizeof(arg_root
)/sizeof(WCHAR
);
699 p
+=copy_path_string(parameters
->root
,p
);
701 else if (strncmpW(p
, arg_select
, sizeof(arg_select
)/sizeof(WCHAR
))==0)
703 p
+= sizeof(arg_select
)/sizeof(WCHAR
);
704 p
+=copy_path_string(parameters
->selection
,p
);
705 if (!parameters
->root
[0])
706 copy_path_root(parameters
->root
,
707 parameters
->selection
);
709 else if (strncmpW(p
, arg_desktop
, sizeof(arg_desktop
)/sizeof(WCHAR
))==0)
711 p
+= sizeof(arg_desktop
)/sizeof(WCHAR
);
712 manage_desktop( p
); /* the rest of the command line is handled by desktop mode */
721 /* left over command line is generally the path to be opened */
722 copy_path_string(parameters
->root
,p2
);
726 int WINAPI
wWinMain(HINSTANCE hinstance
,
727 HINSTANCE previnstance
,
732 parameters_struct parameters
;
735 IShellFolder
*folder
;
736 INITCOMMONCONTROLSEX init_info
;
738 memset(¶meters
,0,sizeof(parameters
));
739 explorer_hInstance
= hinstance
;
740 parse_command_line(cmdline
,¶meters
);
741 hres
= OleInitialize(NULL
);
744 WINE_ERR("Could not initialize COM\n");
745 ExitProcess(EXIT_FAILURE
);
747 init_info
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
748 init_info
.dwICC
= ICC_USEREX_CLASSES
| ICC_BAR_CLASSES
| ICC_COOL_CLASSES
;
749 if(!InitCommonControlsEx(&init_info
))
751 WINE_ERR("Could not initialize Comctl\n");
752 ExitProcess(EXIT_FAILURE
);
754 register_explorer_window_class();
755 folder
= get_starting_shell_folder(¶meters
);
756 make_explorer_window(folder
);
757 IShellFolder_Release(folder
);
758 while(GetMessageW( &msg
, NULL
, 0, 0 ) != 0)
760 TranslateMessage(&msg
);
761 DispatchMessageW(&msg
);