1 /* 2 * Copyright 2003, 2004, 2005 Martin Fuchs 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 20 // 21 // Explorer clone 22 // 23 // shellbrowser.h 24 // 25 // Martin Fuchs, 23.07.2003 26 // 27 28 #include "../utility/treedroptarget.h" 29 #include "../utility/shellbrowserimpl.h" 30 31 #include <memory> 32 33 /// information structure to hold current shell folder information 34 struct ShellPathInfo 35 { 36 ShellPathInfo(int mode=0) : _open_mode(mode) {} 37 38 ShellPathInfo(const ShellChildWndInfo& info) 39 : _shell_path(info._shell_path), 40 _root_shell_path(info._root_shell_path), 41 _open_mode(info._open_mode) 42 { 43 } 44 45 ShellPath _shell_path; 46 ShellPath _root_shell_path; 47 48 int _open_mode; //OPEN_WINDOW_MODE 49 }; 50 51 52 struct BrowserCallback 53 { 54 virtual ~BrowserCallback() {} 55 virtual void entry_selected(Entry* entry) = 0; 56 }; 57 58 59 /// Implementation of IShellBrowserImpl interface in explorer child windows 60 struct ShellBrowser : public IShellBrowserImpl, 61 public IComSrvBase<IShellFolderViewCB, ShellBrowser>, public SimpleComObject 62 { 63 ShellBrowser(HWND hwnd, HWND hwndFrame, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, 64 BrowserCallback* cb, CtxMenuInterfaces& cm_ifs); 65 virtual ~ShellBrowser(); 66 67 //IOleWindow 68 virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND* lphwnd) 69 { 70 *lphwnd = _hwnd; 71 return S_OK; 72 } 73 74 //IShellBrowser 75 virtual HRESULT STDMETHODCALLTYPE QueryActiveShellView(IShellView** ppshv) 76 { 77 _pShellView->AddRef(); 78 *ppshv = _pShellView; 79 return S_OK; 80 } 81 82 virtual HRESULT STDMETHODCALLTYPE GetControlWindow(UINT id, HWND* lphwnd) 83 { 84 if (!lphwnd) 85 return E_POINTER; 86 87 if (id == FCW_TREE) { 88 *lphwnd = _left_hwnd; 89 return S_OK; 90 } 91 92 HWND hwnd = (HWND)SendMessage(_hwndFrame, PM_GET_CONTROLWINDOW, id, 0); 93 94 if (hwnd) { 95 *lphwnd = hwnd; 96 return S_OK; 97 } 98 99 return E_NOTIMPL; 100 } 101 102 virtual HRESULT STDMETHODCALLTYPE SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* pret) 103 { 104 if (!pret) 105 return E_POINTER; 106 107 HWND hstatusbar = (HWND)SendMessage(_hwndFrame, PM_GET_CONTROLWINDOW, id, 0); 108 109 if (hstatusbar) { 110 *pret = ::SendMessage(hstatusbar, uMsg, wParam, lParam); 111 return S_OK; 112 } 113 114 return E_NOTIMPL; 115 } 116 117 const Root& get_root() const {return _root;} 118 119 void OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh); 120 void OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv); 121 void OnTreeItemRClick(int idCtrl, LPNMHDR pnmh); 122 void OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv); 123 124 void Init(); 125 126 int InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder); 127 128 bool jump_to_pidl(LPCITEMIDLIST pidl); 129 130 HRESULT OnDefaultCommand(LPIDA pida); 131 132 void UpdateFolderView(IShellFolder* folder); 133 HTREEITEM select_entry(HTREEITEM hitem, Entry* entry, bool expand=true); 134 135 bool select_folder(Entry* entry, bool expand); 136 137 // for SDIMainFrame 138 void jump_to(LPCITEMIDLIST pidl); 139 140 void invalidate_cache(); 141 142 bool TranslateAccelerator(LPMSG lpmsg); 143 144 protected: 145 HWND _hwnd; 146 HWND _hwndFrame; 147 HWND _left_hwnd; 148 WindowHandle& _right_hwnd; 149 ShellPathInfo& _create_info; 150 HIMAGELIST _himl; 151 HIMAGELIST _himl_old; 152 BrowserCallback* _callback; 153 154 ShellFolder _folder; 155 156 IShellView* _pShellView; // current hosted shellview 157 TreeDropTarget* _pDropTarget; 158 159 HTREEITEM _last_sel; 160 161 Root _root; 162 ShellDirectory* _cur_dir; 163 164 CtxMenuInterfaces& _cm_ifs; 165 166 void InitializeTree(); 167 bool InitDragDrop(); 168 169 typedef IComSrvBase<IShellFolderViewCB, ShellBrowser> super; 170 171 // IShellFolderViewCB 172 virtual HRESULT STDMETHODCALLTYPE MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam); 173 174 map<int, int> _image_map; 175 176 int get_image_idx(int icon_id); 177 178 void refresh(); 179 }; 180 181 182 #define C_DRIVE_STR TEXT("C:\\") 183 184 // work around GCC's wide string constant bug 185 #ifdef __GNUC__ 186 extern const LPCTSTR C_DRIVE; 187 #else 188 #define C_DRIVE C_DRIVE_STR 189 #endif 190 191 template<typename BASE> struct ShellBrowserChildT 192 : public BASE, public BrowserCallback 193 { 194 typedef BASE super; 195 196 // constructor for SDIMainFrame 197 ShellBrowserChildT(HWND hwnd) 198 : super(hwnd) 199 { 200 } 201 202 // constructor for MDIShellBrowserChild 203 ShellBrowserChildT(HWND hwnd, const ShellChildWndInfo& info) 204 : super(hwnd, info) 205 { 206 } 207 208 protected: 209 auto_ptr<ShellBrowser> _shellBrowser; 210 211 LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 212 { 213 switch(nmsg) { 214 case PM_GET_SHELLBROWSER_PTR: 215 return (LRESULT)&*_shellBrowser; 216 217 case WM_GETISHELLBROWSER: // for Registry Explorer Plugin 218 return (LRESULT)static_cast<IShellBrowser*>(&*_shellBrowser); 219 220 default: 221 return super::WndProc(nmsg, wparam, lparam); 222 } 223 224 return 0; 225 } 226 227 int Notify(int id, NMHDR* pnmh) 228 { 229 if (_shellBrowser.get()) 230 switch(pnmh->code) { 231 case TVN_GETDISPINFO: _shellBrowser->OnTreeGetDispInfo(id, pnmh); break; 232 case TVN_SELCHANGED: _shellBrowser->OnTreeItemSelected(id, (LPNMTREEVIEW)pnmh); break; 233 case TVN_ITEMEXPANDING: _shellBrowser->OnTreeItemExpanding(id, (LPNMTREEVIEW)pnmh); break; 234 case NM_RCLICK: _shellBrowser->OnTreeItemRClick(id, pnmh); break; 235 default: return super::Notify(id, pnmh); 236 } 237 else 238 return super::Notify(id, pnmh); 239 240 return 0; 241 } 242 }; 243 244 245 #ifndef _NO_MDI 246 247 struct MDIShellBrowserChild : public ExtContextMenuHandlerT< 248 ShellBrowserChildT<ChildWindow> 249 > 250 { 251 typedef ExtContextMenuHandlerT< 252 ShellBrowserChildT<ChildWindow> 253 > super; 254 255 MDIShellBrowserChild(HWND hwnd, const ShellChildWndInfo& info); 256 257 static MDIShellBrowserChild* create(const ShellChildWndInfo& info); 258 259 LRESULT Init(LPCREATESTRUCT); 260 261 virtual String jump_to_int(LPCTSTR url); 262 263 protected: 264 ShellChildWndInfo _create_info; 265 ShellPathInfo _shellpath_info; 266 267 LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); 268 269 void update_shell_browser(); 270 271 // interface BrowserCallback 272 virtual void entry_selected(Entry* entry); 273 }; 274 275 #endif 276