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  // shellfs.h
24  //
25  // Martin Fuchs, 23.07.2003
26  //
27 
28 
29  /// shell file/directory entry
30 struct ShellEntry : public Entry
31 {
32 	ShellEntry(Entry* parent, LPITEMIDLIST shell_path) : Entry(parent, ET_SHELL), _pidl(shell_path) {}
33 	ShellEntry(Entry* parent, const ShellPath& shell_path) : Entry(parent, ET_SHELL), _pidl(shell_path) {}
34 
35 	virtual bool		get_path(PTSTR path, size_t path_count) const;
36 	virtual ShellPath	create_absolute_pidl() const;
37 	virtual HRESULT		GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
38 	virtual BOOL		launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
39 	virtual HRESULT		do_context_menu(HWND hwnd, const POINT& pptScreen, CtxMenuInterfaces& cm_ifs);
40 	virtual ShellFolder	get_shell_folder() const;
41 
42 	IShellFolder*		get_parent_folder() const;
43 
44 	ShellPath	_pidl;	// parent relative PIDL
45 
46 protected:
47 	ShellEntry(LPITEMIDLIST shell_path) : Entry(ET_SHELL), _pidl(shell_path) {}
48 	ShellEntry(const ShellPath& shell_path) : Entry(ET_SHELL), _pidl(shell_path) {}
49 };
50 
51 
52  /// shell folder entry
53 struct ShellDirectory : public ShellEntry, public Directory
54 {
55 	ShellDirectory(ShellFolder& root_folder, const ShellPath& shell_path, HWND hwnd)
56 	 :	ShellEntry(shell_path),
57 		_folder(root_folder, shell_path),
58 		_hwnd(hwnd)
59 	{
60 		CONTEXT("ShellDirectory::ShellDirectory()");
61 
62 		lstrcpy(_data.cFileName, root_folder.get_name(shell_path, SHGDN_FORADDRESSBAR));
63 		_data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
64 		_shell_attribs = SFGAO_FOLDER;
65 
66 		ShellFolder subfolder(root_folder, shell_path);
67 		IShellFolder* pFolder = subfolder;
68 		pFolder->AddRef();
69 		_path = pFolder;
70 	}
71 
72 	explicit ShellDirectory(ShellDirectory* parent, LPITEMIDLIST shell_path, HWND hwnd)
73 	 :	ShellEntry(parent, shell_path),
74 		_folder(parent->_folder, shell_path),
75 		_hwnd(hwnd)
76 	{
77 		/* not neccessary - the caller will fill the info
78 		lstrcpy(_data.cFileName, _folder.get_name(shell_path));
79 		_data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
80 		_shell_attribs = SFGAO_FOLDER; */
81 
82 		_folder->AddRef();
83 		_path = _folder;
84 	}
85 
86 	ShellDirectory(const ShellDirectory& other)
87 	 :	ShellEntry(other),
88 		Directory(other),
89 		_folder(other._folder),
90 		_hwnd(other._hwnd)
91 	{
92 		IShellFolder* pFolder = (IShellFolder*)_path;
93 		pFolder->AddRef();
94 	}
95 
96 	~ShellDirectory()
97 	{
98 		IShellFolder* pFolder = (IShellFolder*)_path;
99 		_path = NULL;
100 		pFolder->Release();
101 	}
102 
103 	virtual void read_directory(int scan_flags=0);
104 	virtual const void* get_next_path_component(const void*) const;
105 	virtual Entry* find_entry(const void*);
106 
107 	virtual bool get_path(PTSTR path, size_t path_count) const;
108 	virtual ShellFolder	get_shell_folder() const;
109 
110 	int	extract_icons(ICONCACHE_FLAGS flags);
111 
112 	ShellFolder _folder;
113 	HWND	_hwnd;
114 
115 protected:
116 	bool	fill_w32fdata_shell(LPCITEMIDLIST pidl, SFGAOF attribs, WIN32_FIND_DATA*, BY_HANDLE_FILE_INFORMATION*, bool do_access=true);
117 };
118 
119 
120 inline IShellFolder* ShellEntry::get_parent_folder() const
121 {
122 	if (_up)
123 		return static_cast<ShellDirectory*>(_up)->_folder;
124 	else
125 		return GetDesktopFolder();
126 }
127