Drop flags during font enumeration for font chooser if we get no
[wine] / dlls / commdlg / cdlg32.c
1 /*
2  *  Common Dialog Boxes interface (32 bit)
3  *  Find/Replace
4  *
5  * Copyright 1999 Bertho A. Stultiens
6  */
7
8 #include "winbase.h"
9 #include "wine/winbase16.h"
10 #include "commdlg.h"
11 #include "cderr.h"
12 #include "debugtools.h"
13
14 DEFAULT_DEBUG_CHANNEL(commdlg);
15
16 #include "cdlg.h"
17
18
19 HINSTANCE       COMDLG32_hInstance = 0;
20 HINSTANCE16     COMDLG32_hInstance16 = 0;
21
22 static DWORD    COMDLG32_TlsIndex;
23
24 HINSTANCE       SHELL32_hInstance = 0;
25 HINSTANCE       SHFOLDER_hInstance = 0;
26
27 /* ITEMIDLIST */
28 LPITEMIDLIST WINAPI (*COMDLG32_PIDL_ILClone) (LPCITEMIDLIST);
29 LPITEMIDLIST WINAPI (*COMDLG32_PIDL_ILCombine)(LPCITEMIDLIST,LPCITEMIDLIST);
30 LPITEMIDLIST WINAPI (*COMDLG32_PIDL_ILGetNext)(LPITEMIDLIST);
31 BOOL WINAPI (*COMDLG32_PIDL_ILRemoveLastID)(LPCITEMIDLIST);
32 BOOL WINAPI (*COMDLG32_PIDL_ILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST);
33
34 /* SHELL */
35 LPVOID WINAPI (*COMDLG32_SHAlloc)(DWORD);
36 DWORD WINAPI (*COMDLG32_SHFree)(LPVOID);
37 BOOL WINAPI (*COMDLG32_SHGetFolderPathA)(HWND,int,HANDLE,DWORD,LPSTR);
38
39 /***********************************************************************
40  *      COMDLG32_DllEntryPoint                  (COMDLG32.entry)
41  *
42  *    Initialization code for the COMDLG32 DLL
43  *
44  * RETURNS:
45  *      FALSE if sibling could not be loaded or instantiated twice, TRUE
46  *      otherwise.
47  */
48 static char * GPA_string = "Failed to get entry point %s for hinst = 0x%08x\n";
49 #define GPA(dest, hinst, name) \
50         if(!(dest = (void*)GetProcAddress(hinst,name)))\
51         { \
52           ERR(GPA_string, debugres_a(name), hinst); \
53           return FALSE; \
54         }
55
56 BOOL WINAPI COMDLG32_DllEntryPoint(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
57 {
58         TRACE("(%08x, %08lx, %p)\n", hInstance, Reason, Reserved);
59
60         switch(Reason)
61         {
62         case DLL_PROCESS_ATTACH:
63                 COMDLG32_hInstance = hInstance;
64                 DisableThreadLibraryCalls(hInstance);
65
66                 if(!COMDLG32_hInstance16)
67                 {
68                         if(!(COMDLG32_hInstance16 = LoadLibrary16("commdlg.dll")))
69                         {
70                                 ERR("Could not load sibling commdlg.dll\n");
71                                 return FALSE;
72                         }
73                 }
74
75                 COMDLG32_TlsIndex = 0xffffffff;
76
77                 SHELL32_hInstance = GetModuleHandleA("SHELL32.DLL");
78                 
79                 if (!SHELL32_hInstance)
80                 {
81                         ERR("loading of shell32 failed\n");
82                         return FALSE;
83                 }
84
85                 /* ITEMIDLIST */
86                 GPA(COMDLG32_PIDL_ILIsEqual, SHELL32_hInstance, (LPCSTR)21L);
87                 GPA(COMDLG32_PIDL_ILCombine, SHELL32_hInstance, (LPCSTR)25L);
88                 GPA(COMDLG32_PIDL_ILGetNext, SHELL32_hInstance, (LPCSTR)153L);
89                 GPA(COMDLG32_PIDL_ILClone, SHELL32_hInstance, (LPCSTR)18L);
90                 GPA(COMDLG32_PIDL_ILRemoveLastID, SHELL32_hInstance, (LPCSTR)17L);
91                 
92                 /* SHELL */
93                 
94                 GPA(COMDLG32_SHAlloc, SHELL32_hInstance, (LPCSTR)196L);
95                 GPA(COMDLG32_SHFree, SHELL32_hInstance, (LPCSTR)195L);
96                 /* for the first versions of shell32 SHGetFolderPathA is in SHFOLDER.DLL */
97                 COMDLG32_SHGetFolderPathA = (void*)GetProcAddress(SHELL32_hInstance,"SHGetFolderPathA");
98                 if (!COMDLG32_SHGetFolderPathA)
99                 {
100                   SHFOLDER_hInstance = LoadLibraryA("SHFOLDER.DLL");
101                   GPA(COMDLG32_SHGetFolderPathA, SHFOLDER_hInstance,"SHGetFolderPathA");
102                 }
103
104                 break;
105
106         case DLL_PROCESS_DETACH:
107             if (COMDLG32_TlsIndex != 0xffffffff) TlsFree(COMDLG32_TlsIndex);
108             COMDLG32_TlsIndex = 0xffffffff;
109             COMDLG32_hInstance = 0;
110             if(COMDLG32_hInstance16) FreeLibrary16(COMDLG32_hInstance16);
111             if(SHFOLDER_hInstance) FreeLibrary(SHFOLDER_hInstance);
112             break;
113         }
114         return TRUE;
115 }
116 #undef GPA
117
118 /***********************************************************************
119  *      COMDLG32_AllocMem                       (internal)
120  * Get memory for internal datastructure plus stringspace etc.
121  *      RETURNS
122  *              Pointer to a heap block: Succes
123  *              NULL: Failure
124  */
125 LPVOID COMDLG32_AllocMem(
126         int size        /* [in] Block size to allocate */
127 ) {
128         LPVOID ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
129         if(!ptr)
130         {
131                 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
132                 return NULL;
133         }
134         return ptr;
135 }
136
137
138 /***********************************************************************
139  *      COMDLG32_SetCommDlgExtendedError        (internal)
140  *
141  * Used to set the thread's local error value if a comdlg32 function fails.
142  */
143 void COMDLG32_SetCommDlgExtendedError(DWORD err)
144 {
145         TRACE("(%08lx)\n", err);
146         if (COMDLG32_TlsIndex == 0xffffffff)
147           COMDLG32_TlsIndex = TlsAlloc();
148         if (COMDLG32_TlsIndex != 0xffffffff)
149           TlsSetValue(COMDLG32_TlsIndex, (void *)err);
150         else
151           FIXME("No Tls Space\n");
152 }
153
154
155 /***********************************************************************
156  *      CommDlgExtendedError                    (COMDLG32.5)
157  *
158  * Get the thread's local error value if a comdlg32 function fails.
159  *      RETURNS
160  *              Current error value which might not be valid
161  *              if a previous call succeeded.
162  */
163 DWORD WINAPI CommDlgExtendedError(void)
164 {
165         if (COMDLG32_TlsIndex != 0xffffffff) 
166           return (DWORD)TlsGetValue(COMDLG32_TlsIndex);
167         else
168           return 0; /* we never set an error, so there isn't one */
169 }