[SHELL32]
[reactos.git] / dll / win32 / shell32 / folders / CFontsFolder.cpp
1 /*
2 * Fonts folder
3 *
4 * Copyright 2008 Johannes Anderwald <johannes.anderwald@reactos.org>
5 * Copyright 2009 Andrew Hill
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include <precomp.h>
23
24 WINE_DEFAULT_DEBUG_CHANNEL (shell);
25
26 /*
27 This folder should not exist. It is just a file system folder... The \windows\fonts
28 directory contains a hidden desktop.ini with a UIHandler entry that specifies a class
29 that lives in fontext.dll. The UI handler creates a custom view for the folder, which
30 is what we normally see. However, the folder is a perfectly normal CFSFolder.
31 */
32
33 /***********************************************************************
34 * IShellFolder implementation
35 */
36
37 CFontsFolder::CFontsFolder()
38 {
39 m_pisfInner = NULL;
40 m_pisf2Inner = NULL;
41
42 pidlRoot = NULL;
43 apidl = NULL;
44 }
45
46 CFontsFolder::~CFontsFolder()
47 {
48 TRACE("-- destroying IShellFolder(%p)\n", this);
49 SHFree(pidlRoot);
50 }
51
52 static LPITEMIDLIST _ILCreateFont(void)
53 {
54 return _ILCreateGuid(PT_GUID, CLSID_FontsFolderShortcut);
55 }
56
57 HRESULT WINAPI CFontsFolder::FinalConstruct()
58 {
59 HRESULT hr;
60 CComPtr<IPersistFolder3> ppf3;
61 hr = SHCoCreateInstance(NULL, &CLSID_ShellFSFolder, NULL, IID_PPV_ARG(IShellFolder, &m_pisfInner));
62 if (FAILED(hr))
63 return hr;
64
65 hr = m_pisfInner->QueryInterface(IID_PPV_ARG(IShellFolder2, &m_pisf2Inner));
66 if (FAILED(hr))
67 return hr;
68
69 hr = m_pisfInner->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3));
70 if (FAILED(hr))
71 return hr;
72
73 PERSIST_FOLDER_TARGET_INFO info;
74 ZeroMemory(&info, sizeof(PERSIST_FOLDER_TARGET_INFO));
75 info.csidl = CSIDL_FONTS;
76 hr = ppf3->InitializeEx(NULL, _ILCreateFont(), &info);
77
78 return hr;
79 }
80
81 HRESULT WINAPI CFontsFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
82 ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes)
83 {
84 return m_pisfInner->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
85 }
86
87 HRESULT WINAPI CFontsFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
88 {
89 return m_pisfInner->EnumObjects(hwndOwner, dwFlags, ppEnumIDList);
90 }
91
92 HRESULT WINAPI CFontsFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
93 {
94 return m_pisfInner->BindToObject(pidl, pbcReserved, riid, ppvOut);
95 }
96
97 HRESULT WINAPI CFontsFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
98 {
99 return m_pisfInner->BindToStorage(pidl, pbcReserved, riid, ppvOut);
100 }
101
102 HRESULT WINAPI CFontsFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
103 {
104 return m_pisfInner->CompareIDs(lParam, pidl1, pidl2);
105 }
106
107 HRESULT WINAPI CFontsFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
108 {
109 return m_pisfInner->CreateViewObject(hwndOwner, riid, ppvOut);
110 }
111
112 HRESULT WINAPI CFontsFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut)
113 {
114 return m_pisfInner->GetAttributesOf(cidl, apidl, rgfInOut);
115 }
116
117 HRESULT WINAPI CFontsFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
118 REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
119 {
120 return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
121 }
122
123 HRESULT WINAPI CFontsFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
124 {
125 if (!_ILIsSpecialFolder(pidl))
126 return m_pisfInner->GetDisplayNameOf(pidl, dwFlags, strRet);
127
128 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
129 pdump (pidl);
130
131 if (!strRet)
132 return E_INVALIDARG;
133
134 if (!pidl->mkid.cb)
135 {
136 WCHAR wszPath[MAX_PATH];
137
138 if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
139 (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING))
140 {
141 if (!SHGetSpecialFolderPathW(NULL, wszPath, CSIDL_FONTS, FALSE))
142 return E_FAIL;
143 }
144 else if (!HCR_GetClassNameW(CLSID_FontsFolderShortcut, wszPath, MAX_PATH))
145 return E_FAIL;
146
147 strRet->pOleStr = (LPWSTR)CoTaskMemAlloc((wcslen(wszPath) + 1) * sizeof(WCHAR));
148 if (!strRet->pOleStr)
149 return E_OUTOFMEMORY;
150
151 wcscpy(strRet->pOleStr, wszPath);
152 strRet->uType = STRRET_WSTR;
153
154 return S_OK;
155 }
156 else
157 return E_INVALIDARG;
158 }
159
160 HRESULT WINAPI CFontsFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, /* simple pidl */
161 LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
162 {
163 return m_pisfInner->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
164 }
165
166 HRESULT WINAPI CFontsFolder::GetDefaultSearchGUID(GUID *pguid)
167 {
168 return m_pisf2Inner->GetDefaultSearchGUID(pguid);
169 }
170
171 HRESULT WINAPI CFontsFolder::EnumSearches(IEnumExtraSearch ** ppenum)
172 {
173 return m_pisf2Inner->EnumSearches(ppenum);
174 }
175
176 HRESULT WINAPI CFontsFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
177 {
178 return m_pisf2Inner->GetDefaultColumn(dwRes, pSort, pDisplay);
179 }
180
181 HRESULT WINAPI CFontsFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
182 {
183 return m_pisf2Inner->GetDefaultColumnState(iColumn, pcsFlags);
184 }
185
186 HRESULT WINAPI CFontsFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv)
187 {
188 return m_pisf2Inner->GetDetailsEx(pidl, pscid, pv);
189 }
190
191 HRESULT WINAPI CFontsFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd)
192 {
193 return m_pisf2Inner->GetDetailsOf(pidl, iColumn, psd);
194 }
195
196 HRESULT WINAPI CFontsFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
197 {
198 return m_pisf2Inner->MapColumnToSCID(column, pscid);
199 }
200
201 /************************************************************************
202 * CFontsFolder::GetClassID
203 */
204 HRESULT WINAPI CFontsFolder::GetClassID(CLSID *lpClassId)
205 {
206 TRACE ("(%p)\n", this);
207
208 if (!lpClassId)
209 return E_POINTER;
210
211 *lpClassId = CLSID_FontsFolderShortcut;
212
213 return S_OK;
214 }
215
216 /************************************************************************
217 * CFontsFolder::Initialize
218 *
219 * NOTES: it makes no sense to change the pidl
220 */
221 HRESULT WINAPI CFontsFolder::Initialize(LPCITEMIDLIST pidl)
222 {
223 TRACE ("(%p)->(%p)\n", this, pidl);
224
225 return E_NOTIMPL;
226 }
227
228 /**************************************************************************
229 * CFontsFolder::GetCurFolder
230 */
231 HRESULT WINAPI CFontsFolder::GetCurFolder(LPITEMIDLIST *pidl)
232 {
233 TRACE ("(%p)->(%p)\n", this, pidl);
234
235 if (!pidl)
236 return E_POINTER;
237
238 *pidl = ILClone(pidlRoot);
239
240 return S_OK;
241 }