Enable the display of a true type bitmap for true type fonts.
[wine] / dlls / shell32 / folders.c
1 /*
2  *      Copyright 1997  Marcus Meissner
3  *      Copyright 1998  Juergen Schmied
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include <stdlib.h>
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "objbase.h"
28 #include "undocshell.h"
29 #include "shlguid.h"
30
31 #include "wine/debug.h"
32 #include "winerror.h"
33
34 #include "pidl.h"
35 #include "shell32_main.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(shell);
38
39 /***********************************************************************
40 *   IExtractIconW implementation
41 */
42 typedef struct
43 {
44         ICOM_VFIELD(IExtractIconW);
45         DWORD   ref;
46         ICOM_VTABLE(IPersistFile)*      lpvtblPersistFile;
47         ICOM_VTABLE(IExtractIconA)*     lpvtblExtractIconA;
48         LPITEMIDLIST    pidl;
49 } IExtractIconWImpl;
50
51 static struct ICOM_VTABLE(IExtractIconA) eiavt;
52 static struct ICOM_VTABLE(IExtractIconW) eivt;
53 static struct ICOM_VTABLE(IPersistFile) pfvt;
54
55 #define _IPersistFile_Offset ((int)(&(((IExtractIconWImpl*)0)->lpvtblPersistFile)))
56 #define _ICOM_THIS_From_IPersistFile(class, name) class* This = (class*)(((char*)name)-_IPersistFile_Offset);
57
58 #define _IExtractIconA_Offset ((int)(&(((IExtractIconWImpl*)0)->lpvtblExtractIconA)))
59 #define _ICOM_THIS_From_IExtractIconA(class, name) class* This = (class*)(((char*)name)-_IExtractIconA_Offset);
60
61 /**************************************************************************
62 *  IExtractIconW_Constructor
63 */
64 IExtractIconW* IExtractIconW_Constructor(LPCITEMIDLIST pidl)
65 {
66         IExtractIconWImpl* ei;
67         
68         TRACE("%p\n", pidl);
69
70         ei = (IExtractIconWImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IExtractIconWImpl));
71         ei->ref=1;
72         ei->lpVtbl = &eivt;
73         ei->lpvtblPersistFile = &pfvt;
74         ei->lpvtblExtractIconA = &eiavt;
75         ei->pidl=ILClone(pidl);
76
77         pdump(pidl);
78
79         TRACE("(%p)\n", ei);
80         return (IExtractIconW *)ei;
81 }
82 /**************************************************************************
83  *  IExtractIconW_QueryInterface
84  */
85 static HRESULT WINAPI IExtractIconW_fnQueryInterface(IExtractIconW *iface, REFIID riid, LPVOID *ppvObj)
86 {
87         ICOM_THIS(IExtractIconWImpl, iface);
88
89         TRACE("(%p)->(\n\tIID:\t%s,%p)\n", This, debugstr_guid(riid), ppvObj);
90
91         *ppvObj = NULL;
92
93         if (IsEqualIID(riid, &IID_IUnknown))                            /*IUnknown*/
94         {
95           *ppvObj = This;
96         }
97         else if (IsEqualIID(riid, &IID_IPersistFile))   /*IExtractIcon*/
98         {
99           *ppvObj = (IPersistFile*)&(This->lpvtblPersistFile);
100         }
101         else if (IsEqualIID(riid, &IID_IExtractIconA))  /*IExtractIcon*/
102         {
103           *ppvObj = (IExtractIconA*)&(This->lpvtblExtractIconA);
104         }
105         else if (IsEqualIID(riid, &IID_IExtractIconW))  /*IExtractIcon*/
106         {
107           *ppvObj = (IExtractIconW*)This;
108         }
109
110         if(*ppvObj)
111         {
112           IExtractIconW_AddRef((IExtractIconW*) *ppvObj);
113           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
114           return S_OK;
115         }
116         TRACE("-- Interface: E_NOINTERFACE\n");
117         return E_NOINTERFACE;
118 }
119
120 /**************************************************************************
121 *  IExtractIconW_AddRef
122 */
123 static ULONG WINAPI IExtractIconW_fnAddRef(IExtractIconW * iface)
124 {
125         ICOM_THIS(IExtractIconWImpl, iface);
126
127         TRACE("(%p)->(count=%lu)\n",This, This->ref );
128
129         return ++(This->ref);
130 }
131 /**************************************************************************
132 *  IExtractIconW_Release
133 */
134 static ULONG WINAPI IExtractIconW_fnRelease(IExtractIconW * iface)
135 {
136         ICOM_THIS(IExtractIconWImpl, iface);
137
138         TRACE("(%p)->()\n",This);
139
140         if (!--(This->ref))
141         {
142           TRACE(" destroying IExtractIcon(%p)\n",This);
143           SHFree(This->pidl);
144           HeapFree(GetProcessHeap(),0,This);
145           return 0;
146         }
147         return This->ref;
148 }
149
150 static WCHAR swShell32Name[] = {'s','h','e','l','l','3','2','.','d','l','l',0};
151
152 /**************************************************************************
153 *  IExtractIconW_GetIconLocation
154 *
155 * mapping filetype to icon
156 */
157 static HRESULT WINAPI IExtractIconW_fnGetIconLocation(
158         IExtractIconW * iface,
159         UINT uFlags,            /* GIL_ flags */
160         LPWSTR szIconFile,
161         UINT cchMax,
162         int * piIndex,
163         UINT * pwFlags)         /* returned GIL_ flags */
164 {
165         ICOM_THIS(IExtractIconWImpl, iface);
166
167         char    sTemp[MAX_PATH];
168         DWORD   dwNr;
169         GUID const * riid;
170         LPITEMIDLIST    pSimplePidl = ILFindLastID(This->pidl);
171
172         TRACE("(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags);
173
174         if (pwFlags)
175           *pwFlags = 0;
176
177         if (_ILIsDesktop(pSimplePidl))
178         {
179           lstrcpynW(szIconFile, swShell32Name, cchMax);
180           *piIndex = 34;
181         }
182
183         /* my computer and other shell extensions */
184         else if ((riid = _ILGetGUIDPointer(pSimplePidl)))
185         {
186           char xriid[50];
187
188           sprintf(xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
189                   riid->Data1, riid->Data2, riid->Data3,
190                   riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
191                   riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]);
192
193           if (HCR_GetDefaultIconA(xriid, sTemp, MAX_PATH, &dwNr))
194           {
195             MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax);
196             *piIndex = dwNr;
197           }
198           else
199           {
200             lstrcpynW(szIconFile, swShell32Name, cchMax);
201             *piIndex = 15;
202           }
203         }
204
205         else if (_ILIsDrive (pSimplePidl))
206         {
207           if (HCR_GetDefaultIconA("Drive", sTemp, MAX_PATH, &dwNr))
208           {
209             MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax);
210             *piIndex = dwNr;
211           }
212           else
213           {
214             lstrcpynW(szIconFile, swShell32Name, cchMax);
215             *piIndex = 8;
216           }
217         }
218         else if (_ILIsFolder (pSimplePidl))
219         {
220           if (HCR_GetDefaultIconA("Folder", sTemp, MAX_PATH, &dwNr))
221           {
222             MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax);
223           }
224           else
225           {
226             lstrcpynW(szIconFile, swShell32Name, cchMax);
227             dwNr = 3;
228           }
229           *piIndex = (uFlags & GIL_OPENICON) ? dwNr + 1 : dwNr;
230         }
231         else    /* object is file */
232         {
233           if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH)
234               && HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE)
235               && HCR_GetDefaultIconA(sTemp, sTemp, MAX_PATH, &dwNr))
236           {
237             if (!lstrcmpA("%1", sTemp))         /* icon is in the file */
238             {
239               SHGetPathFromIDListW(This->pidl, szIconFile);
240               *piIndex = 0;
241             }
242             else
243             {
244               MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax);
245               *piIndex = dwNr;
246             }
247           }
248           else                                  /* default icon */
249           {
250             lstrcpynW(szIconFile, swShell32Name, cchMax);
251             *piIndex = 0;
252           }
253         }
254
255         TRACE("-- %s %x\n", debugstr_w(szIconFile), *piIndex);
256         return NOERROR;
257 }
258 /**************************************************************************
259 *  IExtractIconW_Extract
260 */
261 static HRESULT WINAPI IExtractIconW_fnExtract(IExtractIconW * iface, LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
262 {
263         ICOM_THIS(IExtractIconWImpl, iface);
264
265         FIXME("(%p) (file=%p index=%u %p %p size=%u) semi-stub\n", This, debugstr_w(pszFile), nIconIndex, phiconLarge, phiconSmall, nIconSize);
266
267         if (phiconLarge)
268           *phiconLarge = ImageList_GetIcon(ShellBigIconList, nIconIndex, ILD_TRANSPARENT);
269
270         if (phiconSmall)
271           *phiconSmall = ImageList_GetIcon(ShellSmallIconList, nIconIndex, ILD_TRANSPARENT);
272
273         return S_OK;
274 }
275
276 static struct ICOM_VTABLE(IExtractIconW) eivt =
277 {
278         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
279         IExtractIconW_fnQueryInterface,
280         IExtractIconW_fnAddRef,
281         IExtractIconW_fnRelease,
282         IExtractIconW_fnGetIconLocation,
283         IExtractIconW_fnExtract
284 };
285
286 /**************************************************************************
287 *  IExtractIconA_Constructor
288 */
289 IExtractIconA* IExtractIconA_Constructor(LPCITEMIDLIST pidl)
290 {
291         ICOM_THIS(IExtractIconWImpl, IExtractIconW_Constructor(pidl));
292         IExtractIconA *eia = (IExtractIconA *)&This->lpvtblExtractIconA;
293         
294         TRACE("(%p)->(%p)\n", This, eia);
295         return eia;
296 }
297 /**************************************************************************
298  *  IExtractIconA_QueryInterface
299  */
300 static HRESULT WINAPI IExtractIconA_fnQueryInterface(IExtractIconA * iface, REFIID riid, LPVOID *ppvObj)
301 {
302         _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
303
304         return IExtractIconW_QueryInterface(This, riid, ppvObj);
305 }
306
307 /**************************************************************************
308 *  IExtractIconA_AddRef
309 */
310 static ULONG WINAPI IExtractIconA_fnAddRef(IExtractIconA * iface)
311 {
312         _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
313
314         return IExtractIconW_AddRef(This);
315 }
316 /**************************************************************************
317 *  IExtractIconA_Release
318 */
319 static ULONG WINAPI IExtractIconA_fnRelease(IExtractIconA * iface)
320 {
321         _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
322
323         return IExtractIconW_AddRef(This);
324 }
325 /**************************************************************************
326 *  IExtractIconA_GetIconLocation
327 *
328 * mapping filetype to icon
329 */
330 static HRESULT WINAPI IExtractIconA_fnGetIconLocation(
331         IExtractIconA * iface,
332         UINT uFlags,
333         LPSTR szIconFile,
334         UINT cchMax,
335         int * piIndex,
336         UINT * pwFlags)
337 {
338         HRESULT ret;
339         LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, cchMax * sizeof(WCHAR));
340         _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
341         
342         TRACE("(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags);
343
344         ret = IExtractIconW_GetIconLocation(This, uFlags, lpwstrFile, cchMax, piIndex, pwFlags);
345         WideCharToMultiByte(CP_ACP, 0, lpwstrFile, -1, szIconFile, cchMax, NULL, NULL);
346         HeapFree(GetProcessHeap(), 0, lpwstrFile);
347
348         TRACE("-- %s %x\n", szIconFile, *piIndex);
349         return ret;
350 }
351 /**************************************************************************
352 *  IExtractIconA_Extract
353 */
354 static HRESULT WINAPI IExtractIconA_fnExtract(IExtractIconA * iface, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
355 {
356         HRESULT ret;
357         INT len = MultiByteToWideChar(CP_ACP, 0, pszFile, -1, NULL, 0);
358         LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
359         _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
360
361         TRACE("(%p) (file=%p index=%u %p %p size=%u)\n", This, pszFile, nIconIndex, phiconLarge, phiconSmall, nIconSize);
362
363         MultiByteToWideChar(CP_ACP, 0, pszFile, -1, lpwstrFile, len);
364         ret = IExtractIconW_Extract(This, lpwstrFile, nIconIndex, phiconLarge, phiconSmall, nIconSize);
365         HeapFree(GetProcessHeap(), 0, lpwstrFile);
366         return ret;
367 }
368
369 static struct ICOM_VTABLE(IExtractIconA) eiavt =
370 {
371         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
372         IExtractIconA_fnQueryInterface,
373         IExtractIconA_fnAddRef,
374         IExtractIconA_fnRelease,
375         IExtractIconA_fnGetIconLocation,
376         IExtractIconA_fnExtract
377 };
378
379 /************************************************************************
380  * IEIPersistFile_QueryInterface (IUnknown)
381  */
382 static HRESULT WINAPI IEIPersistFile_fnQueryInterface(
383         IPersistFile    *iface,
384         REFIID          iid,
385         LPVOID          *ppvObj)
386 {
387         _ICOM_THIS_From_IPersistFile(IExtractIconW, iface);
388
389         return IExtractIconW_QueryInterface(This, iid, ppvObj);
390 }
391
392 /************************************************************************
393  * IEIPersistFile_AddRef (IUnknown)
394  */
395 static ULONG WINAPI IEIPersistFile_fnAddRef(
396         IPersistFile    *iface)
397 {
398         _ICOM_THIS_From_IPersistFile(IExtractIconW, iface);
399
400         return IExtractIconW_AddRef(This);
401 }
402
403 /************************************************************************
404  * IEIPersistFile_Release (IUnknown)
405  */
406 static ULONG WINAPI IEIPersistFile_fnRelease(
407         IPersistFile    *iface)
408 {
409         _ICOM_THIS_From_IPersistFile(IExtractIconW, iface);
410
411         return IExtractIconW_Release(This);
412 }
413
414 /************************************************************************
415  * IEIPersistFile_GetClassID (IPersist)
416  */
417 static HRESULT WINAPI IEIPersistFile_fnGetClassID(
418         IPersistFile    *iface,
419         LPCLSID         lpClassId)
420 {
421         CLSID StdFolderID = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
422
423         if (lpClassId==NULL)
424           return E_POINTER;
425
426         memcpy(lpClassId, &StdFolderID, sizeof(StdFolderID));
427
428         return S_OK;
429 }
430
431 /************************************************************************
432  * IEIPersistFile_Load (IPersistFile)
433  */
434 static HRESULT WINAPI IEIPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFileName, DWORD dwMode)
435 {
436         _ICOM_THIS_From_IPersistFile(IExtractIconW, iface);
437         FIXME("%p\n", This);
438         return E_NOTIMPL;
439
440 }
441
442 static struct ICOM_VTABLE(IPersistFile) pfvt =
443 {
444         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
445         IEIPersistFile_fnQueryInterface,
446         IEIPersistFile_fnAddRef,
447         IEIPersistFile_fnRelease,
448         IEIPersistFile_fnGetClassID,
449         (void *) 0xdeadbeef /* IEIPersistFile_fnIsDirty */,
450         IEIPersistFile_fnLoad,
451         (void *) 0xdeadbeef /* IEIPersistFile_fnSave */,
452         (void *) 0xdeadbeef /* IEIPersistFile_fnSaveCompleted */,
453         (void *) 0xdeadbeef /* IEIPersistFile_fnGetCurFile */
454 };