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

ROS Explorer Source Code Documentation
generated on 02.01.2013 by doxygen

ROS Explorer Homepage