Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenshellbrowser.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright 2003, 2004, 2005, 2006 Martin Fuchs 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00017 */ 00018 00019 00020 // 00021 // Explorer clone 00022 // 00023 // shellbrowser.cpp 00024 // 00025 // Martin Fuchs, 23.07.2003 00026 // 00027 00028 00029 #include <precomp.h> 00030 00031 #include "../resource.h" 00032 00033 00034 // work around GCC's wide string constant bug 00035 #ifdef __GNUC__ 00036 const LPCTSTR C_DRIVE = C_DRIVE_STR; 00037 #endif 00038 00039 00040 ShellBrowser::ShellBrowser(HWND hwnd, HWND hwndFrame, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, 00041 BrowserCallback* cb, CtxMenuInterfaces& cm_ifs) 00042 #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) 00043 : super(IID_IShellFolderViewCB), 00044 #else 00045 : 00046 #endif 00047 _hwnd(hwnd), 00048 _hwndFrame(hwndFrame), 00049 _left_hwnd(left_hwnd), 00050 _right_hwnd(right_hwnd), 00051 _create_info(create_info), 00052 _callback(cb), 00053 _cm_ifs(cm_ifs) 00054 { 00055 _pShellView = NULL; 00056 _pDropTarget = NULL; 00057 _last_sel = 0; 00058 00059 _cur_dir = NULL; 00060 00061 HDC hDC = GetDC(NULL); 00062 if (hDC) 00063 { 00064 INT bpp = GetDeviceCaps(hDC, BITSPIXEL); 00065 ReleaseDC(NULL, hDC); 00066 00067 DWORD ilMask; 00068 if (bpp <= 4) 00069 ilMask = ILC_COLOR4; 00070 else if (bpp <= 8) 00071 ilMask = ILC_COLOR8; 00072 else if (bpp <= 16) 00073 ilMask = ILC_COLOR16; 00074 else if (bpp <= 24) 00075 ilMask = ILC_COLOR24; 00076 else if (bpp <= 32) 00077 ilMask = ILC_COLOR32; 00078 else 00079 ilMask = ILC_COLOR; 00080 00081 ilMask |= ILC_MASK; 00082 00083 _himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ilMask, 2, 0); 00084 ImageList_SetBkColor(_himl, GetSysColor(COLOR_WINDOW)); 00085 } 00086 } 00087 00088 ShellBrowser::~ShellBrowser() 00089 { 00090 (void)TreeView_SetImageList(_left_hwnd, _himl_old, TVSIL_NORMAL); 00091 ImageList_Destroy(_himl); 00092 00093 if (_pShellView) 00094 _pShellView->Release(); 00095 00096 if (_pDropTarget) { 00097 _pDropTarget->Release(); 00098 _pDropTarget = NULL; 00099 } 00100 00101 if (_right_hwnd) { 00102 DestroyWindow(_right_hwnd); 00103 _right_hwnd = 0; 00104 } 00105 } 00106 00107 00108 void ShellBrowser::Init() 00109 { 00110 CONTEXT("ShellBrowser::Init()"); 00111 00112 const String& root_name = GetDesktopFolder().get_name(_create_info._root_shell_path, SHGDN_FORADDRESSBAR); 00113 00114 _root._drive_type = DRIVE_UNKNOWN; 00115 lstrcpy(_root._volname, root_name); 00116 _root._fs_flags = 0; 00117 lstrcpy(_root._fs, TEXT("Desktop")); 00118 00119 _root._entry = new ShellDirectory(GetDesktopFolder(), _create_info._root_shell_path, _hwnd); 00120 00121 _root._entry->read_directory(SCAN_DONT_ACCESS|SCAN_NO_FILESYSTEM); // avoid to handle desktop root folder as file system directory 00122 00123 if (_left_hwnd) { 00124 InitializeTree(); 00125 InitDragDrop(); 00126 } 00127 00128 jump_to(_create_info._shell_path); 00129 00130 /* already filled by ShellDirectory constructor 00131 lstrcpy(_root._entry->_data.cFileName, TEXT("Desktop")); */ 00132 } 00133 00134 void ShellBrowser::jump_to(LPCITEMIDLIST pidl) 00135 { 00136 Entry* entry = NULL; 00137 00138 if (!_cur_dir) 00139 _cur_dir = static_cast<ShellDirectory*>(_root._entry); 00140 00141 //LOG(FmtString(TEXT("ShellBrowser::jump_to(): pidl=%s"), (LPCTSTR)FileSysShellPath(pidl))); 00142 00143 // We could call read_tree() here to iterate through the hierarchy and open all folders 00144 // from _create_info._root_shell_path (_cur_dir) to _create_info._shell_path (pidl). 00145 // To make it easier we just use ILFindChild() instead. 00146 if (_cur_dir) { 00147 static DynamicFct<LPITEMIDLIST(WINAPI*)(LPCITEMIDLIST, LPCITEMIDLIST)> ILFindChild(TEXT("SHELL32"), 24); 00148 00149 if (ILFindChild) { 00150 for(;;) { 00151 LPCITEMIDLIST child_pidl = (*ILFindChild)(_cur_dir->create_absolute_pidl(), pidl); 00152 if (!child_pidl || !child_pidl->mkid.cb) 00153 break; 00154 00155 _cur_dir->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); 00156 00157 entry = _cur_dir->find_entry(child_pidl); 00158 if (!entry) 00159 break; 00160 00161 _cur_dir = static_cast<ShellDirectory*>(entry); 00162 _callback->entry_selected(entry); 00163 } 00164 } else { 00165 _cur_dir->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); 00166 00167 entry = _cur_dir->find_entry(pidl); // This is not correct in the common case, but works on the desktop level. 00168 00169 if (entry) { 00170 _cur_dir = static_cast<ShellDirectory*>(entry); 00171 _callback->entry_selected(entry); 00172 } 00173 } 00174 } 00175 00176 // If not already called, now directly call UpdateFolderView() using pidl 00177 if (!entry) 00178 UpdateFolderView(ShellFolder(pidl)); 00179 } 00180 00181 00182 void ShellBrowser::InitializeTree() 00183 { 00184 CONTEXT("ShellBrowserChild::InitializeTree()"); 00185 00186 _himl_old = TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL); 00187 TreeView_SetScrollTime(_left_hwnd, 100); 00188 00189 TV_INSERTSTRUCT tvInsert; 00190 TV_ITEM& tvItem = tvInsert.item; 00191 00192 tvInsert.hParent = 0; 00193 tvInsert.hInsertAfter = TVI_LAST; 00194 00195 tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN; 00196 tvItem.lParam = (LPARAM)_root._entry; 00197 tvItem.pszText = _root._volname; //LPSTR_TEXTCALLBACK; 00198 tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK; 00199 tvItem.cChildren = 1; 00200 00201 HTREEITEM hItem = TreeView_InsertItem(_left_hwnd, &tvInsert); 00202 TreeView_SelectItem(_left_hwnd, hItem); 00203 TreeView_Expand(_left_hwnd, hItem, TVE_EXPAND); 00204 } 00205 00206 bool ShellBrowser::InitDragDrop() 00207 { 00208 CONTEXT("ShellBrowser::InitDragDrop()"); 00209 00210 _pDropTarget = new TreeDropTarget(_left_hwnd); 00211 00212 if (!_pDropTarget) 00213 return false; 00214 00215 _pDropTarget->AddRef(); 00216 00217 if (FAILED(RegisterDragDrop(_left_hwnd, _pDropTarget))) {//calls addref 00218 _pDropTarget->Release(); // free TreeDropTarget 00219 _pDropTarget = NULL; 00220 return false; 00221 } else 00222 _pDropTarget->Release(); 00223 00224 FORMATETC ftetc; 00225 00226 ftetc.dwAspect = DVASPECT_CONTENT; 00227 ftetc.lindex = -1; 00228 ftetc.tymed = TYMED_HGLOBAL; 00229 ftetc.cfFormat = CF_HDROP; 00230 00231 _pDropTarget->AddSuportedFormat(ftetc); 00232 00233 return true; 00234 } 00235 00236 00237 void ShellBrowser::OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh) 00238 { 00239 CONTEXT("ShellBrowser::OnTreeGetDispInfo()"); 00240 00241 LPNMTVDISPINFO lpdi = (LPNMTVDISPINFO)pnmh; 00242 ShellEntry* entry = (ShellEntry*)lpdi->item.lParam; 00243 00244 if (entry) { 00245 if (lpdi->item.mask & TVIF_TEXT) 00246 lpdi->item.pszText = entry->_display_name; 00247 00248 if (lpdi->item.mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) { 00249 if (lpdi->item.mask & TVIF_IMAGE) 00250 lpdi->item.iImage = get_image_idx( 00251 entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS))); 00252 00253 if (lpdi->item.mask & TVIF_SELECTEDIMAGE) 00254 lpdi->item.iSelectedImage = get_image_idx( 00255 entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS|ICF_OPEN))); 00256 } 00257 } 00258 } 00259 00260 int ShellBrowser::get_image_idx(int icon_id) 00261 { 00262 if (icon_id != ICID_NONE) { 00263 map<int,int>::const_iterator found = _image_map.find(icon_id); 00264 00265 if (found != _image_map.end()) 00266 return found->second; 00267 00268 int idx = ImageList_AddIcon(_himl, g_Globals._icon_cache.get_icon(icon_id).get_hicon()); 00269 00270 _image_map[icon_id] = idx; 00271 00272 return idx; 00273 } else 00274 return -1; 00275 } 00276 00277 void ShellBrowser::invalidate_cache() 00278 { 00279 (void)TreeView_SetImageList(_left_hwnd, _himl_old, TVSIL_NORMAL); 00280 ImageList_Destroy(_himl); 00281 00282 _himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0); 00283 ImageList_SetBkColor(_himl, GetSysColor(COLOR_WINDOW)); 00284 00285 _himl_old = TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL); 00286 00287 for(map<int,int>::const_iterator it=_image_map.begin(); it!=_image_map.end(); ++it) 00288 g_Globals._icon_cache.free_icon(it->first); 00289 00290 _image_map.clear(); 00291 } 00292 00293 00294 void ShellBrowser::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv) 00295 { 00296 CONTEXT("ShellBrowser::OnTreeItemExpanding()"); 00297 00298 if (pnmtv->action == TVE_COLLAPSE) 00299 TreeView_Expand(_left_hwnd, pnmtv->itemNew.hItem, TVE_COLLAPSE|TVE_COLLAPSERESET); 00300 else if (pnmtv->action == TVE_EXPAND) { 00301 ShellDirectory* entry = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, pnmtv->itemNew.hItem); 00302 00303 if (entry) 00304 if (!InsertSubitems(pnmtv->itemNew.hItem, entry, entry->_folder)) { 00305 entry->_shell_attribs &= ~SFGAO_HASSUBFOLDER; 00306 00307 // remove subitem "+" 00308 TV_ITEM tvItem; 00309 00310 tvItem.mask = TVIF_CHILDREN; 00311 tvItem.hItem = pnmtv->itemNew.hItem; 00312 tvItem.cChildren = 0; 00313 00314 TreeView_SetItem(_left_hwnd, &tvItem); 00315 } 00316 } 00317 } 00318 00319 int ShellBrowser::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder) 00320 { 00321 CONTEXT("ShellBrowser::InsertSubitems()"); 00322 00323 WaitCursor wait; 00324 00325 int cnt = 0; 00326 00327 SendMessage(_left_hwnd, WM_SETREDRAW, FALSE, 0); 00328 00329 try { 00330 entry->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); 00331 } catch(COMException& e) { 00332 HandleException(e, g_Globals._hMainWnd); 00333 } 00334 00335 // remove old children items 00336 HTREEITEM hchild, hnext; 00337 00338 hnext = TreeView_GetChild(_left_hwnd, hParentItem); 00339 00340 while((hchild=hnext) != 0) { 00341 hnext = TreeView_GetNextSibling(_left_hwnd, hchild); 00342 TreeView_DeleteItem(_left_hwnd, hchild); 00343 } 00344 00345 TV_ITEM tvItem; 00346 TV_INSERTSTRUCT tvInsert; 00347 00348 for(entry=entry->_down; entry; entry=entry->_next) { 00349 #ifndef _LEFT_FILES 00350 if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 00351 #endif 00352 { 00353 // ignore hidden directories 00354 if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) 00355 continue; 00356 00357 // ignore directory entries "." and ".." 00358 if (entry->_data.cFileName[0]==TEXT('.') && 00359 (entry->_data.cFileName[1]==TEXT('\0') || 00360 (entry->_data.cFileName[1]==TEXT('.') && entry->_data.cFileName[2]==TEXT('\0')))) 00361 continue; 00362 00363 ZeroMemory(&tvItem, sizeof(tvItem)); 00364 00365 tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN; 00366 tvItem.pszText = LPSTR_TEXTCALLBACK; 00367 tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK; 00368 tvItem.lParam = (LPARAM)entry; 00369 tvItem.cChildren = entry->_shell_attribs & SFGAO_HASSUBFOLDER? 1: 0; 00370 00371 if (entry->_shell_attribs & SFGAO_SHARE) { 00372 tvItem.mask |= TVIF_STATE; 00373 tvItem.stateMask |= TVIS_OVERLAYMASK; 00374 tvItem.state |= INDEXTOOVERLAYMASK(1); 00375 } 00376 00377 tvInsert.item = tvItem; 00378 tvInsert.hInsertAfter = TVI_LAST; 00379 tvInsert.hParent = hParentItem; 00380 00381 (void)TreeView_InsertItem(_left_hwnd, &tvInsert); 00382 00383 ++cnt; 00384 } 00385 } 00386 00387 SendMessage(_left_hwnd, WM_SETREDRAW, TRUE, 0); 00388 00389 return cnt; 00390 } 00391 00392 00393 void ShellBrowser::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv) 00394 { 00395 CONTEXT("ShellBrowser::OnTreeItemSelected()"); 00396 00397 Entry* entry = (Entry*)pnmtv->itemNew.lParam; 00398 00399 _last_sel = pnmtv->itemNew.hItem; 00400 00401 if (entry) 00402 _callback->entry_selected(entry); 00403 } 00404 00405 00406 void ShellBrowser::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh) 00407 { 00408 CONTEXT("ShellBrowser::OnTreeItemRClick()"); 00409 00410 TVHITTESTINFO tvhti; 00411 00412 GetCursorPos(&tvhti.pt); 00413 ScreenToClient(_left_hwnd, &tvhti.pt); 00414 00415 tvhti.flags = LVHT_NOWHERE; 00416 (void)TreeView_HitTest(_left_hwnd, &tvhti); 00417 00418 if (TVHT_ONITEM & tvhti.flags) { 00419 LPARAM itemData = TreeView_GetItemData(_left_hwnd, tvhti.hItem); 00420 00421 if (itemData) { 00422 Entry* entry = (Entry*)itemData; 00423 ClientToScreen(_left_hwnd, &tvhti.pt); 00424 00425 HRESULT hr = entry->do_context_menu(_hwnd, tvhti.pt, _cm_ifs); 00426 00427 if (SUCCEEDED(hr)) 00428 refresh(); 00429 else 00430 CHECKERROR(hr); 00431 } 00432 } 00433 } 00434 00435 00436 void ShellBrowser::UpdateFolderView(IShellFolder* folder) 00437 { 00438 CONTEXT("ShellBrowser::UpdateFolderView()"); 00439 00440 FOLDERSETTINGS fs; 00441 IShellView* pLastShellView = _pShellView; 00442 00443 _folder = folder; 00444 00445 if (pLastShellView) 00446 pLastShellView->GetCurrentInfo(&fs); 00447 else { 00448 fs.ViewMode = _create_info._open_mode&OWM_DETAILS? FVM_DETAILS: FVM_ICON; 00449 fs.fFlags = FWF_NOCLIENTEDGE|FWF_BESTFITWINDOW; 00450 } 00451 00452 #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) 00453 SFV_CREATE sfv_create; 00454 00455 sfv_create.cbSize = sizeof(SFV_CREATE); 00456 sfv_create.pshf = folder; 00457 sfv_create.psvOuter = NULL; 00458 sfv_create.psfvcb = this; 00459 00460 HRESULT hr = SHCreateShellFolderView(&sfv_create, &_pShellView); 00461 #else 00462 HRESULT hr = folder->CreateViewObject(_hwnd, IID_IShellView, (void**)&_pShellView); 00463 #endif 00464 00465 if (FAILED(hr)) { 00466 _pShellView = NULL; 00467 return; 00468 } 00469 00470 RECT rect = {CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT}; 00471 hr = _pShellView->CreateViewWindow(pLastShellView, &fs, static_cast<IShellBrowser*>(this), &rect, &_right_hwnd/*&m_hWndListView*/); 00472 00473 if (pLastShellView) { 00474 pLastShellView->GetCurrentInfo(&fs); 00475 pLastShellView->UIActivate(SVUIA_DEACTIVATE); 00476 pLastShellView->DestroyViewWindow(); 00477 pLastShellView->Release(); 00478 } 00479 00480 _pShellView->UIActivate(SVUIA_ACTIVATE_NOFOCUS); 00481 } 00482 00483 00484 #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) 00485 00487 HRESULT STDMETHODCALLTYPE ShellBrowser::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) 00488 { 00489 if (uMsg == SFVM_INITMENUPOPUP) { 00491 InsertMenu((HMENU)lParam, 0, MF_BYPOSITION, 12345, TEXT("TEST ENTRY")); 00492 return S_OK; 00493 } 00494 00495 return E_NOTIMPL; 00496 } 00497 00498 #endif 00499 00500 00501 HRESULT ShellBrowser::OnDefaultCommand(LPIDA pida) 00502 { 00503 CONTEXT("ShellBrowser::OnDefaultCommand()"); 00504 00505 if (pida->cidl >= 1) { 00506 if (_left_hwnd) { // explorer mode 00507 if (_last_sel) { 00508 ShellDirectory* parent = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, _last_sel); 00509 00510 if (parent) { 00511 try { 00512 parent->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); 00513 } catch(COMException& e) { 00514 return e.Error(); 00515 } 00516 00517 UINT firstOffset = pida->aoffset[1]; 00518 LPITEMIDLIST pidl = (LPITEMIDLIST)((LPBYTE)pida+firstOffset); 00519 00520 Entry* entry = parent->find_entry(pidl); 00521 00522 if (entry && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) 00523 if (entry->_etype == ET_SHELL) 00524 if (_last_sel && select_entry(_last_sel, entry)) 00525 return S_OK; 00526 00528 return E_NOTIMPL; 00529 } 00530 } 00531 } else { // no tree control 00532 if (MainFrameBase::OpenShellFolders(pida, _hwndFrame)) 00533 return S_OK; 00534 00535 /* create new Frame Window 00536 if (MainFrame::OpenShellFolders(pida, 0)) 00537 return S_OK; 00538 */ 00539 } 00540 } 00541 00542 return E_NOTIMPL; 00543 } 00544 00545 00546 HTREEITEM ShellBrowser::select_entry(HTREEITEM hitem, Entry* entry, bool expand) 00547 { 00548 CONTEXT("ShellBrowser::select_entry()"); 00549 00550 if (expand && !TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND)) 00551 return 0; 00552 00553 for(hitem=TreeView_GetChild(_left_hwnd,hitem); hitem; hitem=TreeView_GetNextSibling(_left_hwnd,hitem)) { 00554 if ((Entry*)TreeView_GetItemData(_left_hwnd,hitem) == entry) { 00555 if (TreeView_SelectItem(_left_hwnd, hitem)) { 00556 if (expand) 00557 TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND); 00558 00559 return hitem; 00560 } 00561 00562 break; 00563 } 00564 } 00565 00566 return 0; 00567 } 00568 00569 00570 bool ShellBrowser::jump_to_pidl(LPCITEMIDLIST pidl) 00571 { 00572 if (!_root._entry) 00573 return false; 00574 00575 // iterate through the hierarchy and open all folders to reach pidl 00576 WaitCursor wait; 00577 00578 HTREEITEM hitem = TreeView_GetRoot(_left_hwnd); 00579 Entry* entry = _root._entry; 00580 00581 for(const void*p=pidl;;) { 00582 if (!p) 00583 return true; 00584 00585 if (!entry || !hitem) 00586 break; 00587 00588 entry->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); 00589 00590 Entry* found = entry->find_entry(p); 00591 p = entry->get_next_path_component(p); 00592 00593 if (found) 00594 hitem = select_entry(hitem, found); 00595 00596 entry = found; 00597 } 00598 00599 return false; 00600 } 00601 00602 00603 bool ShellBrowser::select_folder(Entry* entry, bool expand) 00604 { 00605 CONTEXT("ShellBrowser::expand_folder()"); 00606 00607 if (!_last_sel) 00608 return false; 00609 00610 if (!TreeView_Expand(_left_hwnd, _last_sel, TVE_EXPAND)) 00611 return false; 00612 00613 for(HTREEITEM hitem=TreeView_GetChild(_left_hwnd,_last_sel); hitem; hitem=TreeView_GetNextSibling(_left_hwnd,hitem)) { 00614 if ((ShellDirectory*)TreeView_GetItemData(_left_hwnd,hitem) == entry) { 00615 if (TreeView_SelectItem(_left_hwnd, hitem)) { 00616 if (expand) 00617 if (!TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND)) 00618 return false; 00619 00620 return true; 00621 } 00622 00623 break; 00624 } 00625 } 00626 00627 return false; 00628 } 00629 00630 00631 void ShellBrowser::refresh() 00632 { 00634 } 00635 00636 00637 #ifndef _NO_MDI 00638 00639 MDIShellBrowserChild::MDIShellBrowserChild(HWND hwnd, const ShellChildWndInfo& info) 00640 : super(hwnd, info), 00641 _create_info(info), 00642 _shellpath_info(info) //@@ copies info -> no reference to _create_info ! 00643 { 00652 } 00653 00654 00655 MDIShellBrowserChild* MDIShellBrowserChild::create(const ShellChildWndInfo& info) 00656 { 00657 ChildWindow* child = ChildWindow::create(info, 00658 info._pos.rcNormalPosition, 00659 WINDOW_CREATOR_INFO(MDIShellBrowserChild,ShellChildWndInfo), 00660 CLASSNAME_CHILDWND, 00661 NULL, 00662 WS_CLIPCHILDREN | (info._pos.showCmd==SW_SHOWMAXIMIZED? WS_MAXIMIZE: 0)); 00663 00664 return static_cast<MDIShellBrowserChild*>(child); 00665 } 00666 00667 00668 LRESULT MDIShellBrowserChild::Init(LPCREATESTRUCT pcs) 00669 { 00670 CONTEXT("MDIShellBrowserChild::Init()"); 00671 00672 if (super::Init(pcs)) 00673 return 1; 00674 00675 update_shell_browser(); 00676 00677 return 0; 00678 } 00679 00680 00681 LRESULT MDIShellBrowserChild::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 00682 { 00683 switch(nmsg) { 00684 case PM_DISPATCH_COMMAND: { 00685 switch(LOWORD(wparam)) { 00686 case ID_WINDOW_NEW: {CONTEXT("MDIShellBrowserChild PM_DISPATCH_COMMAND ID_WINDOW_NEW"); 00687 MDIShellBrowserChild::create(_create_info); 00688 break;} 00689 00690 case ID_REFRESH: 00692 _shellBrowser->invalidate_cache(); 00693 break; 00694 00695 case ID_VIEW_SDI: 00696 MainFrameBase::Create(ExplorerCmd(_url, false)); 00697 break; 00698 00699 default: 00700 return super::WndProc(nmsg, wparam, lparam); 00701 } 00702 return TRUE;} 00703 00704 case WM_SYSCOLORCHANGE: 00705 /* Forward WM_SYSCOLORCHANGE to common controls */ 00706 SendMessage(_left_hwnd, WM_SYSCOLORCHANGE, 0, 0); 00707 SendMessage(_right_hwnd, WM_SYSCOLORCHANGE, 0, 0); 00708 break; 00709 00710 default: 00711 return super::WndProc(nmsg, wparam, lparam); 00712 } 00713 00714 return 0; 00715 } 00716 00717 void MDIShellBrowserChild::update_shell_browser() 00718 { 00719 int split_pos = DEFAULT_SPLIT_POS; 00720 00721 if (_shellBrowser.get()) { 00722 split_pos = _split_pos; 00723 delete _shellBrowser.release(); 00724 } 00725 00726 // create explorer treeview 00727 if (_create_info._open_mode & OWM_EXPLORE) { 00728 if (!_left_hwnd) { 00729 ClientRect rect(_hwnd); 00730 00731 _left_hwnd = CreateWindowEx(0, WC_TREEVIEW, NULL, 00732 WS_CHILD|WS_TABSTOP|WS_VISIBLE|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS,//|TVS_NOTOOLTIPS 00733 0, rect.top, split_pos-SPLIT_WIDTH/2, rect.bottom-rect.top, 00734 _hwnd, (HMENU)IDC_FILETREE, g_Globals._hInstance, 0); 00735 } 00736 } else { 00737 if (_left_hwnd) { 00738 DestroyWindow(_left_hwnd); 00739 _left_hwnd = 0; 00740 } 00741 } 00742 00743 _shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _hwndFrame, _left_hwnd, _right_hwnd, 00744 _shellpath_info, this, _cm_ifs)); 00745 00746 _shellBrowser->Init(); 00747 } 00748 00749 00750 String MDIShellBrowserChild::jump_to_int(LPCTSTR url) 00751 { 00752 String dir, fname; 00753 00754 if (!_tcsnicmp(url, TEXT("shell://"), 8)) { 00755 if (_shellBrowser->jump_to_pidl(ShellPath(url+8))) 00756 return url; 00757 } 00758 00759 if (SplitFileSysURL(url, dir, fname)) { 00760 00762 00763 if (_shellBrowser->jump_to_pidl(ShellPath(dir))) 00764 return FmtString(TEXT("file://%s"), (LPCTSTR)dir); 00765 } 00766 00767 return String(); 00768 } 00769 00770 00771 void MDIShellBrowserChild::entry_selected(Entry* entry) 00772 { 00773 if (_left_hwnd) 00774 _shellBrowser->select_folder(entry, false); 00775 00776 _shellBrowser->UpdateFolderView(entry->get_shell_folder()); 00777 00778 // set size of new created shell view windows 00779 ClientRect rt(_hwnd); 00780 resize_children(rt.right, rt.bottom); 00781 00782 // set new URL 00783 TCHAR path[MAX_PATH]; 00784 00785 if (entry->get_path(path, COUNTOF(path))) { 00786 String url; 00787 00788 if (path[0] == ':') 00789 url.printf(TEXT("shell://%s"), path); 00790 else 00791 url.printf(TEXT("file://%s"), path); 00792 00793 set_url(url); 00794 } 00795 } 00796 00797 #endif Generated on Sun May 27 2012 04:18:34 for ReactOS by
1.7.6.1
|