ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

shellbrowser.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.