Create a branch for audio work
[reactos.git] / base / shell / explorer / shell / shellbrowser.cpp
1 /*
2 * Copyright 2003, 2004, 2005, 2006 Martin Fuchs
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19
20 //
21 // Explorer clone
22 //
23 // shellbrowser.cpp
24 //
25 // Martin Fuchs, 23.07.2003
26 //
27
28
29 #include <precomp.h>
30
31 #include "../resource.h"
32
33
34 // work around GCC's wide string constant bug
35 #ifdef __GNUC__
36 const LPCTSTR C_DRIVE = C_DRIVE_STR;
37 #endif
38
39
40 ShellBrowser::ShellBrowser(HWND hwnd, HWND hwndFrame, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info,
41 BrowserCallback* cb, CtxMenuInterfaces& cm_ifs)
42 #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
43 : super(IID_IShellFolderViewCB),
44 #else
45 :
46 #endif
47 _hwnd(hwnd),
48 _hwndFrame(hwndFrame),
49 _left_hwnd(left_hwnd),
50 _right_hwnd(right_hwnd),
51 _create_info(create_info),
52 _callback(cb),
53 _cm_ifs(cm_ifs)
54 {
55 _pShellView = NULL;
56 _pDropTarget = NULL;
57 _last_sel = 0;
58
59 _cur_dir = NULL;
60
61 HDC hDC = GetDC(NULL);
62 if (hDC)
63 {
64 INT bpp = GetDeviceCaps(hDC, BITSPIXEL);
65 ReleaseDC(NULL, hDC);
66
67 DWORD ilMask;
68 if (bpp <= 4)
69 ilMask = ILC_COLOR4;
70 else if (bpp <= 8)
71 ilMask = ILC_COLOR8;
72 else if (bpp <= 16)
73 ilMask = ILC_COLOR16;
74 else if (bpp <= 24)
75 ilMask = ILC_COLOR24;
76 else if (bpp <= 32)
77 ilMask = ILC_COLOR32;
78 else
79 ilMask = ILC_COLOR;
80
81 ilMask |= ILC_MASK;
82
83 _himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ilMask, 2, 0);
84 ImageList_SetBkColor(_himl, GetSysColor(COLOR_WINDOW));
85 }
86 }
87
88 ShellBrowser::~ShellBrowser()
89 {
90 (void)TreeView_SetImageList(_left_hwnd, _himl_old, TVSIL_NORMAL);
91 ImageList_Destroy(_himl);
92
93 if (_pShellView)
94 _pShellView->Release();
95
96 if (_pDropTarget) {
97 _pDropTarget->Release();
98 _pDropTarget = NULL;
99 }
100
101 if (_right_hwnd) {
102 DestroyWindow(_right_hwnd);
103 _right_hwnd = 0;
104 }
105 }
106
107
108 void ShellBrowser::Init()
109 {
110 CONTEXT("ShellBrowser::Init()");
111
112 const String& root_name = GetDesktopFolder().get_name(_create_info._root_shell_path, SHGDN_FORADDRESSBAR);
113
114 _root._drive_type = DRIVE_UNKNOWN;
115 lstrcpy(_root._volname, root_name);
116 _root._fs_flags = 0;
117 lstrcpy(_root._fs, TEXT("Desktop"));
118
119 _root._entry = new ShellDirectory(GetDesktopFolder(), _create_info._root_shell_path, _hwnd);
120
121 _root._entry->read_directory(SCAN_DONT_ACCESS|SCAN_NO_FILESYSTEM); // avoid to handle desktop root folder as file system directory
122
123 if (_left_hwnd) {
124 InitializeTree();
125 InitDragDrop();
126 }
127
128 jump_to(_create_info._shell_path);
129
130 /* already filled by ShellDirectory constructor
131 lstrcpy(_root._entry->_data.cFileName, TEXT("Desktop")); */
132 }
133
134 void ShellBrowser::jump_to(LPCITEMIDLIST pidl)
135 {
136 Entry* entry = NULL;
137
138 if (!_cur_dir)
139 _cur_dir = static_cast<ShellDirectory*>(_root._entry);
140
141 //LOG(FmtString(TEXT("ShellBrowser::jump_to(): pidl=%s"), (LPCTSTR)FileSysShellPath(pidl)));
142
143 // We could call read_tree() here to iterate through the hierarchy and open all folders
144 // from _create_info._root_shell_path (_cur_dir) to _create_info._shell_path (pidl).
145 // To make it easier we just use ILFindChild() instead.
146 if (_cur_dir) {
147 static DynamicFct<LPITEMIDLIST(WINAPI*)(LPCITEMIDLIST, LPCITEMIDLIST)> ILFindChild(TEXT("SHELL32"), 24);
148
149 if (ILFindChild) {
150 for(;;) {
151 LPCITEMIDLIST child_pidl = (*ILFindChild)(_cur_dir->create_absolute_pidl(), pidl);
152 if (!child_pidl || !child_pidl->mkid.cb)
153 break;
154
155 _cur_dir->smart_scan(SORT_NAME, SCAN_DONT_ACCESS);
156
157 entry = _cur_dir->find_entry(child_pidl);
158 if (!entry)
159 break;
160
161 _cur_dir = static_cast<ShellDirectory*>(entry);
162 _callback->entry_selected(entry);
163 }
164 } else {
165 _cur_dir->smart_scan(SORT_NAME, SCAN_DONT_ACCESS);
166
167 entry = _cur_dir->find_entry(pidl); // This is not correct in the common case, but works on the desktop level.
168
169 if (entry) {
170 _cur_dir = static_cast<ShellDirectory*>(entry);
171 _callback->entry_selected(entry);
172 }
173 }
174 }
175
176 // If not already called, now directly call UpdateFolderView() using pidl
177 if (!entry)
178 UpdateFolderView(ShellFolder(pidl));
179 }
180
181
182 void ShellBrowser::InitializeTree()
183 {
184 CONTEXT("ShellBrowserChild::InitializeTree()");
185
186 _himl_old = TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL);
187 TreeView_SetScrollTime(_left_hwnd, 100);
188
189 TV_INSERTSTRUCT tvInsert;
190 TV_ITEM& tvItem = tvInsert.item;
191
192 tvInsert.hParent = 0;
193 tvInsert.hInsertAfter = TVI_LAST;
194
195 tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
196 tvItem.lParam = (LPARAM)_root._entry;
197 tvItem.pszText = _root._volname; //LPSTR_TEXTCALLBACK;
198 tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK;
199 tvItem.cChildren = 1;
200
201 HTREEITEM hItem = TreeView_InsertItem(_left_hwnd, &tvInsert);
202 TreeView_SelectItem(_left_hwnd, hItem);
203 TreeView_Expand(_left_hwnd, hItem, TVE_EXPAND);
204 }
205
206 bool ShellBrowser::InitDragDrop()
207 {
208 CONTEXT("ShellBrowser::InitDragDrop()");
209
210 _pDropTarget = new TreeDropTarget(_left_hwnd);
211
212 if (!_pDropTarget)
213 return false;
214
215 _pDropTarget->AddRef();
216
217 if (FAILED(RegisterDragDrop(_left_hwnd, _pDropTarget))) {//calls addref
218 _pDropTarget->Release(); // free TreeDropTarget
219 _pDropTarget = NULL;
220 return false;
221 } else
222 _pDropTarget->Release();
223
224 FORMATETC ftetc;
225
226 ftetc.dwAspect = DVASPECT_CONTENT;
227 ftetc.lindex = -1;
228 ftetc.tymed = TYMED_HGLOBAL;
229 ftetc.cfFormat = CF_HDROP;
230
231 _pDropTarget->AddSuportedFormat(ftetc);
232
233 return true;
234 }
235
236
237 void ShellBrowser::OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh)
238 {
239 CONTEXT("ShellBrowser::OnTreeGetDispInfo()");
240
241 LPNMTVDISPINFO lpdi = (LPNMTVDISPINFO)pnmh;
242 ShellEntry* entry = (ShellEntry*)lpdi->item.lParam;
243
244 if (entry) {
245 if (lpdi->item.mask & TVIF_TEXT)
246 lpdi->item.pszText = entry->_display_name;
247
248 if (lpdi->item.mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) {
249 if (lpdi->item.mask & TVIF_IMAGE)
250 lpdi->item.iImage = get_image_idx(
251 entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS)));
252
253 if (lpdi->item.mask & TVIF_SELECTEDIMAGE)
254 lpdi->item.iSelectedImage = get_image_idx(
255 entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS|ICF_OPEN)));
256 }
257 }
258 }
259
260 int ShellBrowser::get_image_idx(int icon_id)
261 {
262 if (icon_id != ICID_NONE) {
263 map<int,int>::const_iterator found = _image_map.find(icon_id);
264
265 if (found != _image_map.end())
266 return found->second;
267
268 int idx = ImageList_AddIcon(_himl, g_Globals._icon_cache.get_icon(icon_id).get_hicon());
269
270 _image_map[icon_id] = idx;
271
272 return idx;
273 } else
274 return -1;
275 }
276
277 void ShellBrowser::invalidate_cache()
278 {
279 (void)TreeView_SetImageList(_left_hwnd, _himl_old, TVSIL_NORMAL);
280 ImageList_Destroy(_himl);
281
282 _himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0);
283 ImageList_SetBkColor(_himl, GetSysColor(COLOR_WINDOW));
284
285 _himl_old = TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL);
286
287 for(map<int,int>::const_iterator it=_image_map.begin(); it!=_image_map.end(); ++it)
288 g_Globals._icon_cache.free_icon(it->first);
289
290 _image_map.clear();
291 }
292
293
294 void ShellBrowser::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv)
295 {
296 CONTEXT("ShellBrowser::OnTreeItemExpanding()");
297
298 if (pnmtv->action == TVE_COLLAPSE)
299 TreeView_Expand(_left_hwnd, pnmtv->itemNew.hItem, TVE_COLLAPSE|TVE_COLLAPSERESET);
300 else if (pnmtv->action == TVE_EXPAND) {
301 ShellDirectory* entry = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, pnmtv->itemNew.hItem);
302
303 if (entry)
304 if (!InsertSubitems(pnmtv->itemNew.hItem, entry, entry->_folder)) {
305 entry->_shell_attribs &= ~SFGAO_HASSUBFOLDER;
306
307 // remove subitem "+"
308 TV_ITEM tvItem;
309
310 tvItem.mask = TVIF_CHILDREN;
311 tvItem.hItem = pnmtv->itemNew.hItem;
312 tvItem.cChildren = 0;
313
314 TreeView_SetItem(_left_hwnd, &tvItem);
315 }
316 }
317 }
318
319 int ShellBrowser::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder)
320 {
321 CONTEXT("ShellBrowser::InsertSubitems()");
322
323 WaitCursor wait;
324
325 int cnt = 0;
326
327 SendMessage(_left_hwnd, WM_SETREDRAW, FALSE, 0);
328
329 try {
330 entry->smart_scan(SORT_NAME, SCAN_DONT_ACCESS);
331 } catch(COMException& e) {
332 HandleException(e, g_Globals._hMainWnd);
333 }
334
335 // remove old children items
336 HTREEITEM hchild, hnext;
337
338 hnext = TreeView_GetChild(_left_hwnd, hParentItem);
339
340 while((hchild=hnext) != 0) {
341 hnext = TreeView_GetNextSibling(_left_hwnd, hchild);
342 TreeView_DeleteItem(_left_hwnd, hchild);
343 }
344
345 TV_ITEM tvItem;
346 TV_INSERTSTRUCT tvInsert;
347
348 for(entry=entry->_down; entry; entry=entry->_next) {
349 #ifndef _LEFT_FILES
350 if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
351 #endif
352 {
353 // ignore hidden directories
354 if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
355 continue;
356
357 // ignore directory entries "." and ".."
358 if (entry->_data.cFileName[0]==TEXT('.') &&
359 (entry->_data.cFileName[1]==TEXT('\0') ||
360 (entry->_data.cFileName[1]==TEXT('.') && entry->_data.cFileName[2]==TEXT('\0'))))
361 continue;
362
363 ZeroMemory(&tvItem, sizeof(tvItem));
364
365 tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
366 tvItem.pszText = LPSTR_TEXTCALLBACK;
367 tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK;
368 tvItem.lParam = (LPARAM)entry;
369 tvItem.cChildren = entry->_shell_attribs & SFGAO_HASSUBFOLDER? 1: 0;
370
371 if (entry->_shell_attribs & SFGAO_SHARE) {
372 tvItem.mask |= TVIF_STATE;
373 tvItem.stateMask |= TVIS_OVERLAYMASK;
374 tvItem.state |= INDEXTOOVERLAYMASK(1);
375 }
376
377 tvInsert.item = tvItem;
378 tvInsert.hInsertAfter = TVI_LAST;
379 tvInsert.hParent = hParentItem;
380
381 (void)TreeView_InsertItem(_left_hwnd, &tvInsert);
382
383 ++cnt;
384 }
385 }
386
387 SendMessage(_left_hwnd, WM_SETREDRAW, TRUE, 0);
388
389 return cnt;
390 }
391
392
393 void ShellBrowser::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv)
394 {
395 CONTEXT("ShellBrowser::OnTreeItemSelected()");
396
397 Entry* entry = (Entry*)pnmtv->itemNew.lParam;
398
399 _last_sel = pnmtv->itemNew.hItem;
400
401 if (entry)
402 _callback->entry_selected(entry);
403 }
404
405
406 void ShellBrowser::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh)
407 {
408 CONTEXT("ShellBrowser::OnTreeItemRClick()");
409
410 TVHITTESTINFO tvhti;
411
412 GetCursorPos(&tvhti.pt);
413 ScreenToClient(_left_hwnd, &tvhti.pt);
414
415 tvhti.flags = LVHT_NOWHERE;
416 (void)TreeView_HitTest(_left_hwnd, &tvhti);
417
418 if (TVHT_ONITEM & tvhti.flags) {
419 LPARAM itemData = TreeView_GetItemData(_left_hwnd, tvhti.hItem);
420
421 if (itemData) {
422 Entry* entry = (Entry*)itemData;
423 ClientToScreen(_left_hwnd, &tvhti.pt);
424
425 HRESULT hr = entry->do_context_menu(_hwnd, tvhti.pt, _cm_ifs);
426
427 if (SUCCEEDED(hr))
428 refresh();
429 else
430 CHECKERROR(hr);
431 }
432 }
433 }
434
435
436 void ShellBrowser::UpdateFolderView(IShellFolder* folder)
437 {
438 CONTEXT("ShellBrowser::UpdateFolderView()");
439
440 FOLDERSETTINGS fs;
441 IShellView* pLastShellView = _pShellView;
442
443 _folder = folder;
444
445 if (pLastShellView)
446 pLastShellView->GetCurrentInfo(&fs);
447 else {
448 fs.ViewMode = _create_info._open_mode&OWM_DETAILS? FVM_DETAILS: FVM_ICON;
449 fs.fFlags = FWF_NOCLIENTEDGE|FWF_BESTFITWINDOW;
450 }
451
452 #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
453 SFV_CREATE sfv_create;
454
455 sfv_create.cbSize = sizeof(SFV_CREATE);
456 sfv_create.pshf = folder;
457 sfv_create.psvOuter = NULL;
458 sfv_create.psfvcb = this;
459
460 HRESULT hr = SHCreateShellFolderView(&sfv_create, &_pShellView);
461 #else
462 HRESULT hr = folder->CreateViewObject(_hwnd, IID_IShellView, (void**)&_pShellView);
463 #endif
464
465 if (FAILED(hr)) {
466 _pShellView = NULL;
467 return;
468 }
469
470 RECT rect = {CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT};
471 hr = _pShellView->CreateViewWindow(pLastShellView, &fs, static_cast<IShellBrowser*>(this), &rect, &_right_hwnd/*&m_hWndListView*/);
472
473 if (pLastShellView) {
474 pLastShellView->GetCurrentInfo(&fs);
475 pLastShellView->UIActivate(SVUIA_DEACTIVATE);
476 pLastShellView->DestroyViewWindow();
477 pLastShellView->Release();
478 }
479
480 _pShellView->UIActivate(SVUIA_ACTIVATE_NOFOCUS);
481 }
482
483
484 #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
485
486 /// shell view callback
487 HRESULT STDMETHODCALLTYPE ShellBrowser::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
488 {
489 if (uMsg == SFVM_INITMENUPOPUP) {
490 ///@todo never reached
491 InsertMenu((HMENU)lParam, 0, MF_BYPOSITION, 12345, TEXT("TEST ENTRY"));
492 return S_OK;
493 }
494
495 return E_NOTIMPL;
496 }
497
498 #endif
499
500
501 HRESULT ShellBrowser::OnDefaultCommand(LPIDA pida)
502 {
503 CONTEXT("ShellBrowser::OnDefaultCommand()");
504
505 if (pida->cidl >= 1) {
506 if (_left_hwnd) { // explorer mode
507 if (_last_sel) {
508 ShellDirectory* parent = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, _last_sel);
509
510 if (parent) {
511 try {
512 parent->smart_scan(SORT_NAME, SCAN_DONT_ACCESS);
513 } catch(COMException& e) {
514 return e.Error();
515 }
516
517 UINT firstOffset = pida->aoffset[1];
518 LPITEMIDLIST pidl = (LPITEMIDLIST)((LPBYTE)pida+firstOffset);
519
520 Entry* entry = parent->find_entry(pidl);
521
522 if (entry && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
523 if (entry->_etype == ET_SHELL)
524 if (_last_sel && select_entry(_last_sel, entry))
525 return S_OK;
526
527 ///@todo look for hidden or new subfolders and refresh/add new entry instead of opening a new window
528 return E_NOTIMPL;
529 }
530 }
531 } else { // no tree control
532 if (MainFrameBase::OpenShellFolders(pida, _hwndFrame))
533 return S_OK;
534
535 /* create new Frame Window
536 if (MainFrame::OpenShellFolders(pida, 0))
537 return S_OK;
538 */
539 }
540 }
541
542 return E_NOTIMPL;
543 }
544
545
546 HTREEITEM ShellBrowser::select_entry(HTREEITEM hitem, Entry* entry, bool expand)
547 {
548 CONTEXT("ShellBrowser::select_entry()");
549
550 if (expand && !TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND))
551 return 0;
552
553 for(hitem=TreeView_GetChild(_left_hwnd,hitem); hitem; hitem=TreeView_GetNextSibling(_left_hwnd,hitem)) {
554 if ((Entry*)TreeView_GetItemData(_left_hwnd,hitem) == entry) {
555 if (TreeView_SelectItem(_left_hwnd, hitem)) {
556 if (expand)
557 TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND);
558
559 return hitem;
560 }
561
562 break;
563 }
564 }
565
566 return 0;
567 }
568
569
570 bool ShellBrowser::jump_to_pidl(LPCITEMIDLIST pidl)
571 {
572 if (!_root._entry)
573 return false;
574
575 // iterate through the hierarchy and open all folders to reach pidl
576 WaitCursor wait;
577
578 HTREEITEM hitem = TreeView_GetRoot(_left_hwnd);
579 Entry* entry = _root._entry;
580
581 for(const void*p=pidl;;) {
582 if (!p)
583 return true;
584
585 if (!entry || !hitem)
586 break;
587
588 entry->smart_scan(SORT_NAME, SCAN_DONT_ACCESS);
589
590 Entry* found = entry->find_entry(p);
591 p = entry->get_next_path_component(p);
592
593 if (found)
594 hitem = select_entry(hitem, found);
595
596 entry = found;
597 }
598
599 return false;
600 }
601
602
603 bool ShellBrowser::select_folder(Entry* entry, bool expand)
604 {
605 CONTEXT("ShellBrowser::expand_folder()");
606
607 if (!_last_sel)
608 return false;
609
610 if (!TreeView_Expand(_left_hwnd, _last_sel, TVE_EXPAND))
611 return false;
612
613 for(HTREEITEM hitem=TreeView_GetChild(_left_hwnd,_last_sel); hitem; hitem=TreeView_GetNextSibling(_left_hwnd,hitem)) {
614 if ((ShellDirectory*)TreeView_GetItemData(_left_hwnd,hitem) == entry) {
615 if (TreeView_SelectItem(_left_hwnd, hitem)) {
616 if (expand)
617 if (!TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND))
618 return false;
619
620 return true;
621 }
622
623 break;
624 }
625 }
626
627 return false;
628 }
629
630
631 void ShellBrowser::refresh()
632 {
633 ///@todo
634 }
635
636
637 #ifndef _NO_MDI
638
639 MDIShellBrowserChild::MDIShellBrowserChild(HWND hwnd, const ShellChildWndInfo& info)
640 : super(hwnd, info),
641 _create_info(info),
642 _shellpath_info(info) //@@ copies info -> no reference to _create_info !
643 {
644 /**todo Conversion of shell path into path string -> store into URL history
645 const String& path = GetDesktopFolder().get_name(info._shell_path, SHGDN_FORADDRESSBAR);
646 const String& parsingpath = GetDesktopFolder().get_name(info._shell_path, SHGDN_FORPARSING);
647
648 // store path into history
649 if (info._path && *info._path)
650 _url_history.push(info._path);
651 */
652 }
653
654
655 MDIShellBrowserChild* MDIShellBrowserChild::create(const ShellChildWndInfo& info)
656 {
657 ChildWindow* child = ChildWindow::create(info, info._pos.rcNormalPosition,
658 WINDOW_CREATOR_INFO(MDIShellBrowserChild,ShellChildWndInfo), CLASSNAME_CHILDWND, NULL, info._pos.showCmd==SW_SHOWMAXIMIZED? WS_MAXIMIZE: 0);
659
660 return static_cast<MDIShellBrowserChild*>(child);
661 }
662
663
664 LRESULT MDIShellBrowserChild::Init(LPCREATESTRUCT pcs)
665 {
666 CONTEXT("MDIShellBrowserChild::Init()");
667
668 if (super::Init(pcs))
669 return 1;
670
671 update_shell_browser();
672
673 return 0;
674 }
675
676
677 LRESULT MDIShellBrowserChild::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
678 {
679 switch(nmsg) {
680 case PM_DISPATCH_COMMAND: {
681 switch(LOWORD(wparam)) {
682 case ID_WINDOW_NEW: {CONTEXT("MDIShellBrowserChild PM_DISPATCH_COMMAND ID_WINDOW_NEW");
683 MDIShellBrowserChild::create(_create_info);
684 break;}
685
686 case ID_REFRESH:
687 ///@todo refresh shell child
688 _shellBrowser->invalidate_cache();
689 break;
690
691 case ID_VIEW_SDI:
692 MainFrameBase::Create(ExplorerCmd(_url, false));
693 break;
694
695 default:
696 return super::WndProc(nmsg, wparam, lparam);
697 }
698 return TRUE;}
699
700 default:
701 return super::WndProc(nmsg, wparam, lparam);
702 }
703
704 return 0;
705 }
706
707 void MDIShellBrowserChild::update_shell_browser()
708 {
709 int split_pos = DEFAULT_SPLIT_POS;
710
711 if (_shellBrowser.get()) {
712 split_pos = _split_pos;
713 delete _shellBrowser.release();
714 }
715
716 // create explorer treeview
717 if (_create_info._open_mode & OWM_EXPLORE) {
718 if (!_left_hwnd) {
719 ClientRect rect(_hwnd);
720
721 _left_hwnd = CreateWindowEx(0, WC_TREEVIEW, NULL,
722 WS_CHILD|WS_TABSTOP|WS_VISIBLE|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS,//|TVS_NOTOOLTIPS
723 0, rect.top, split_pos-SPLIT_WIDTH/2, rect.bottom-rect.top,
724 _hwnd, (HMENU)IDC_FILETREE, g_Globals._hInstance, 0);
725 }
726 } else {
727 if (_left_hwnd) {
728 DestroyWindow(_left_hwnd);
729 _left_hwnd = 0;
730 }
731 }
732
733 _shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _hwndFrame, _left_hwnd, _right_hwnd,
734 _shellpath_info, this, _cm_ifs));
735
736 _shellBrowser->Init();
737 }
738
739
740 String MDIShellBrowserChild::jump_to_int(LPCTSTR url)
741 {
742 String dir, fname;
743
744 if (!_tcsnicmp(url, TEXT("shell://"), 8)) {
745 if (_shellBrowser->jump_to_pidl(ShellPath(url+8)))
746 return url;
747 }
748
749 if (SplitFileSysURL(url, dir, fname)) {
750
751 ///@todo use fname
752
753 if (_shellBrowser->jump_to_pidl(ShellPath(dir)))
754 return FmtString(TEXT("file://%s"), (LPCTSTR)dir);
755 }
756
757 return String();
758 }
759
760
761 void MDIShellBrowserChild::entry_selected(Entry* entry)
762 {
763 if (_left_hwnd)
764 _shellBrowser->select_folder(entry, false);
765
766 _shellBrowser->UpdateFolderView(entry->get_shell_folder());
767
768 // set size of new created shell view windows
769 ClientRect rt(_hwnd);
770 resize_children(rt.right, rt.bottom);
771
772 // set new URL
773 TCHAR path[MAX_PATH];
774
775 if (entry->get_path(path, COUNTOF(path))) {
776 String url;
777
778 if (path[0] == ':')
779 url.printf(TEXT("shell://%s"), path);
780 else
781 url.printf(TEXT("file://%s"), path);
782
783 set_url(url);
784 }
785 }
786
787 #endif