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