work around GCC's wide string constant bug to fix tree list image loading
[reactos.git] / reactos / subsys / system / explorer / shell / shellbrowser.h
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
32 /// information structure to hold current shell folder information
33 struct ShellPathInfo
34 {
35 ShellPathInfo(int mode=0) : _open_mode(mode) {}
36
37 ShellPathInfo(const ShellChildWndInfo& info)
38 : _shell_path(info._shell_path),
39 _root_shell_path(info._root_shell_path),
40 _open_mode(info._open_mode)
41 {
42 }
43
44 ShellPath _shell_path;
45 ShellPath _root_shell_path;
46
47 int _open_mode; //OPEN_WINDOW_MODE
48 };
49
50
51 struct BrowserCallback
52 {
53 virtual ~BrowserCallback() {}
54 virtual void entry_selected(Entry* entry) = 0;
55 };
56
57
58 /// Implementation of IShellBrowserImpl interface in explorer child windows
59 struct ShellBrowser : public IShellBrowserImpl
60 #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
61 , public IComSrvBase<IShellFolderViewCB, ShellBrowser>, public SimpleComObject
62 #endif
63 {
64 ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info,
65 HIMAGELIST himl, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs);
66 virtual ~ShellBrowser();
67
68 //IOleWindow
69 virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND* lphwnd)
70 {
71 *lphwnd = _hwnd;
72 return S_OK;
73 }
74
75 //IShellBrowser
76 virtual HRESULT STDMETHODCALLTYPE QueryActiveShellView(IShellView** ppshv)
77 {
78 _pShellView->AddRef();
79 *ppshv = _pShellView;
80 return S_OK;
81 }
82
83 virtual HRESULT STDMETHODCALLTYPE GetControlWindow(UINT id, HWND* lphwnd)
84 {
85 if (!lphwnd)
86 return E_POINTER;
87
88 if (id == FCW_TREE) {
89 *lphwnd = _left_hwnd;
90 return S_OK;
91 }
92
93 HWND hwnd = (HWND)SendMessage(_hWndFrame, PM_GET_CONTROLWINDOW, id, 0);
94
95 if (hwnd) {
96 *lphwnd = hwnd;
97 return S_OK;
98 }
99
100 return E_NOTIMPL;
101 }
102
103 virtual HRESULT STDMETHODCALLTYPE SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* pret)
104 {
105 if (!pret)
106 return E_POINTER;
107
108 HWND hstatusbar = (HWND)SendMessage(_hWndFrame, PM_GET_CONTROLWINDOW, id, 0);
109
110 if (hstatusbar) {
111 *pret = ::SendMessage(hstatusbar, uMsg, wParam, lParam);
112 return S_OK;
113 }
114
115 return E_NOTIMPL;
116 }
117
118 const Root& get_root() const {return _root;}
119
120 void OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh);
121 void OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv);
122 void OnTreeItemRClick(int idCtrl, LPNMHDR pnmh);
123 void OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv);
124
125 LRESULT Init(HWND hWndFrame);
126
127 void Init(HIMAGELIST himl)
128 {
129 InitializeTree(himl);
130 InitDragDrop();
131 }
132
133 int InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder);
134
135 bool jump_to_pidl(LPCITEMIDLIST pidl);
136
137 HRESULT OnDefaultCommand(LPIDA pida);
138
139 void UpdateFolderView(IShellFolder* folder);
140 HTREEITEM select_entry(HTREEITEM hitem, Entry* entry, bool expand=true);
141
142 // for SDIMainFrame
143 void jump_to(LPCITEMIDLIST pidl);
144
145 protected:
146 HWND _hwnd;
147 HWND _left_hwnd;
148 WindowHandle& _right_hwnd;
149 ShellPathInfo& _create_info;
150 HIMAGELIST _himl;
151 HIMAGELIST _himl_old;
152 BrowserCallback* _callback;
153
154 WindowHandle _hWndFrame;
155 ShellFolder _folder;
156
157 IShellView* _pShellView; // current hosted shellview
158 TreeDropTarget* _pDropTarget;
159
160 HTREEITEM _last_sel;
161
162 Root _root;
163 ShellDirectory* _cur_dir;
164
165 CtxMenuInterfaces& _cm_ifs;
166
167 void InitializeTree(HIMAGELIST himl);
168 bool InitDragDrop();
169
170 #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
171 typedef IComSrvBase<IShellFolderViewCB, ShellBrowser> super;
172
173 // IShellFolderViewCB
174 virtual HRESULT STDMETHODCALLTYPE MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam);
175 #endif
176 };
177
178
179 #define C_DRIVE_STR TEXT("C:\\")
180
181 // work around GCC's wide string constant bug
182 #ifdef __GNUC__
183 extern const LPCTSTR C_DRIVE;
184 #else
185 #define C_DRIVE C_DRIVE_STR
186 #endif
187
188 template<typename BASE> struct ShellBrowserChildT
189 : public BASE, public BrowserCallback
190 {
191 typedef BASE super;
192
193 // constructor for SDIMainFrame
194 ShellBrowserChildT(HWND hwnd)
195 : super(hwnd)
196 {
197 _himlSmall = 0;
198 }
199
200 // constructor for MDIShellBrowserChild
201 ShellBrowserChildT(HWND hwnd, const ShellChildWndInfo& info)
202 : super(hwnd, info)
203 {
204 _himlSmall = 0;
205 }
206
207 void init_himl()
208 {
209 SHFILEINFO sfi;
210
211 _himlSmall = (HIMAGELIST)SHGetFileInfo(C_DRIVE, 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
212 // _himlLarge = (HIMAGELIST)SHGetFileInfo(C_DRIVE, 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_LARGEICON);
213 }
214
215 protected:
216 HIMAGELIST _himlSmall; // list
217 // HIMAGELIST _himlLarge; // shell image
218
219 protected:
220 auto_ptr<ShellBrowser> _shellBrowser;
221
222 LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
223 {
224 switch(nmsg) {
225 case PM_GET_SHELLBROWSER_PTR:
226 return (LRESULT)&*_shellBrowser;
227
228 case WM_GETISHELLBROWSER: // for Registry Explorer Plugin
229 return (LRESULT)static_cast<IShellBrowser*>(&*_shellBrowser);
230
231 default:
232 return super::WndProc(nmsg, wparam, lparam);
233 }
234
235 return 0;
236 }
237
238 int Notify(int id, NMHDR* pnmh)
239 {
240 if (&*_shellBrowser)
241 switch(pnmh->code) {
242 case TVN_GETDISPINFO: _shellBrowser->OnTreeGetDispInfo(id, pnmh); break;
243 case TVN_SELCHANGED: _shellBrowser->OnTreeItemSelected(id, (LPNMTREEVIEW)pnmh); break;
244 case TVN_ITEMEXPANDING: _shellBrowser->OnTreeItemExpanding(id, (LPNMTREEVIEW)pnmh); break;
245 case NM_RCLICK: _shellBrowser->OnTreeItemRClick(id, pnmh); break;
246 default: return super::Notify(id, pnmh);
247 }
248 else
249 return super::Notify(id, pnmh);
250
251 return 0;
252 }
253 };
254
255
256 #ifndef _NO_MDI
257
258 struct MDIShellBrowserChild : public ExtContextMenuHandlerT<
259 ShellBrowserChildT<ChildWindow>
260 >
261 {
262 typedef ExtContextMenuHandlerT<
263 ShellBrowserChildT<ChildWindow>
264 > super;
265
266 MDIShellBrowserChild(HWND hwnd, const ShellChildWndInfo& info);
267
268 static MDIShellBrowserChild* create(const ShellChildWndInfo& info);
269
270 LRESULT Init(LPCREATESTRUCT);
271
272 virtual String jump_to_int(LPCTSTR url);
273
274 protected:
275 ShellChildWndInfo _create_info;
276 ShellPathInfo _shellpath_info;
277
278 LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
279
280 void update_shell_browser();
281
282 // interface BrowserCallback
283 virtual void entry_selected(Entry* entry);
284 };
285
286 #endif