Use min/max instead of MIN/MAX.
[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 "commdlg.h"
10 #include "cderr.h"
11 #include "debugtools.h"
12
13 DEFAULT_DEBUG_CHANNEL(commdlg)
14
15 #include "cdlg.h"
16
17
18 HINSTANCE       COMDLG32_hInstance = 0;
19 HINSTANCE16     COMDLG32_hInstance16 = 0;
20
21 static DWORD    COMDLG32_TlsIndex;
22 static int      COMDLG32_Attach = 0;
23
24 HINSTANCE       COMCTL32_hInstance = 0;
25 HINSTANCE       SHELL32_hInstance = 0;
26 HINSTANCE       SHLWAPI_hInstance = 0;
27
28 /* DPA */
29 HDPA    (WINAPI* COMDLG32_DPA_Create) (INT);  
30 LPVOID  (WINAPI* COMDLG32_DPA_GetPtr) (const HDPA, INT);   
31 LPVOID  (WINAPI* COMDLG32_DPA_DeletePtr) (const HDPA hdpa, INT i);
32 LPVOID  (WINAPI* COMDLG32_DPA_DeleteAllPtrs) (const HDPA hdpa);
33 INT     (WINAPI* COMDLG32_DPA_InsertPtr) (const HDPA, INT, LPVOID); 
34 BOOL    (WINAPI* COMDLG32_DPA_Destroy) (const HDPA); 
35
36 /* IMAGELIST */
37 HICON   (WINAPI* COMDLG32_ImageList_GetIcon) (HIMAGELIST, INT, UINT);
38 HIMAGELIST (WINAPI *COMDLG32_ImageList_LoadImageA) (HINSTANCE, LPCSTR, INT, INT, COLORREF, UINT, UINT);
39 BOOL    (WINAPI* COMDLG32_ImageList_Draw) (HIMAGELIST himl, int i, HDC hdcDest, int x, int y, UINT fStyle);
40 BOOL    (WINAPI* COMDLG32_ImageList_Destroy) (HIMAGELIST himl);
41
42 /* ITEMIDLIST */
43 LPITEMIDLIST (WINAPI *COMDLG32_PIDL_ILClone) (LPCITEMIDLIST);
44 LPITEMIDLIST (WINAPI *COMDLG32_PIDL_ILCombine)(LPCITEMIDLIST,LPCITEMIDLIST);
45 LPITEMIDLIST (WINAPI *COMDLG32_PIDL_ILGetNext)(LPITEMIDLIST);
46 BOOL (WINAPI *COMDLG32_PIDL_ILRemoveLastID)(LPCITEMIDLIST);
47 BOOL (WINAPI *COMDLG32_PIDL_ILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST);
48
49 /* SHELL */
50 BOOL (WINAPI *COMDLG32_SHGetPathFromIDListA) (LPCITEMIDLIST,LPSTR);
51 HRESULT (WINAPI *COMDLG32_SHGetSpecialFolderLocation)(HWND,INT,LPITEMIDLIST *);
52 DWORD (WINAPI *COMDLG32_SHGetDesktopFolder)(IShellFolder **);
53 DWORD   (WINAPI *COMDLG32_SHGetFileInfoA)(LPCSTR,DWORD,SHFILEINFOA*,UINT,UINT);
54 DWORD (WINAPI *COMDLG32_SHFree)(LPVOID);
55
56 /* PATH */
57 BOOL (WINAPI *COMDLG32_PathIsRootA)(LPCSTR x);
58 LPCSTR (WINAPI *COMDLG32_PathFindFilenameA)(LPCSTR path);
59 DWORD (WINAPI *COMDLG32_PathRemoveFileSpecA)(LPSTR fn);
60 BOOL (WINAPI *COMDLG32_PathMatchSpecW)(LPCWSTR x, LPCWSTR y);
61 LPSTR (WINAPI *COMDLG32_PathAddBackslashA)(LPSTR path);
62
63 /***********************************************************************
64  *      COMDLG32_DllEntryPoint                  (COMDLG32.entry)
65  *
66  *    Initialization code for the COMDLG32 DLL
67  *
68  * RETURNS:
69  *      FALSE if sibling could not be loaded or instantiated twice, TRUE
70  *      otherwise.
71  */
72 BOOL WINAPI COMDLG32_DllEntryPoint(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
73 {
74         TRACE("(%08x, %08lx, %p)\n", hInstance, Reason, Reserved);
75
76         switch(Reason)
77         {
78         case DLL_PROCESS_ATTACH:
79                 COMDLG32_Attach++;
80                 if(COMDLG32_hInstance)
81                 {
82                         ERR("comdlg32.dll instantiated twice in one address space!\n");
83                         /*
84                          * We should return FALSE here, but that will break
85                          * most apps that use CreateProcess because we do
86                          * not yet support seperate address spaces.
87                          */
88                         return TRUE;
89                 }
90
91                 COMDLG32_hInstance = hInstance;
92                 DisableThreadLibraryCalls(hInstance);
93
94                 if(!COMDLG32_hInstance16)
95                 {
96                         if(!(COMDLG32_hInstance16 = LoadLibrary16("commdlg.dll")))
97                         {
98                                 ERR("Could not load sibling commdlg.dll\n");
99                                 return FALSE;
100                         }
101                 }
102
103                 if((COMDLG32_TlsIndex = TlsAlloc()) == 0xffffffff)
104                 {
105                         ERR("No space for COMDLG32 TLS\n");
106                         return FALSE;
107                 }
108
109                 COMCTL32_hInstance = LoadLibraryA("COMCTL32.DLL");      
110                 SHELL32_hInstance = LoadLibraryA("SHELL32.DLL");
111                 SHLWAPI_hInstance = LoadLibraryA("SHLWAPI.DLL");
112                 
113                 if (!COMCTL32_hInstance || !SHELL32_hInstance || !SHLWAPI_hInstance)
114                 {
115                         ERR("loading of comctl32 or shell32 or shlwapi failed\n");
116                         return FALSE;
117                 }
118                 /* DPA */
119                 COMDLG32_DPA_Create=(void*)GetProcAddress(COMCTL32_hInstance, (LPCSTR)328L);
120                 COMDLG32_DPA_Destroy=(void*)GetProcAddress(COMCTL32_hInstance, (LPCSTR)329L);
121                 COMDLG32_DPA_GetPtr=(void*)GetProcAddress(COMCTL32_hInstance, (LPCSTR)332L);
122                 COMDLG32_DPA_InsertPtr=(void*)GetProcAddress(COMCTL32_hInstance, (LPCSTR)334L);
123                 COMDLG32_DPA_DeletePtr=(void*)GetProcAddress(COMCTL32_hInstance, (LPCSTR)336L);
124                 COMDLG32_DPA_DeleteAllPtrs=(void*)GetProcAddress(COMCTL32_hInstance, (LPCSTR)337L);
125
126                 /* IMAGELIST */
127                 COMDLG32_ImageList_GetIcon=(void*)GetProcAddress(COMCTL32_hInstance,"ImageList_GetIcon");
128                 COMDLG32_ImageList_LoadImageA=(void*)GetProcAddress(COMCTL32_hInstance,"ImageList_LoadImageA");
129                 COMDLG32_ImageList_Draw=(void*)GetProcAddress(COMCTL32_hInstance,"ImageList_Draw");
130                 COMDLG32_ImageList_Destroy=(void*)GetProcAddress(COMCTL32_hInstance,"ImageList_Destroy");
131                 
132                 /* ITEMISLIST */
133                 
134                 COMDLG32_PIDL_ILIsEqual =(void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)21L);
135                 COMDLG32_PIDL_ILCombine =(void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)25L);
136                 COMDLG32_PIDL_ILGetNext =(void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)153L);
137                 COMDLG32_PIDL_ILClone =(void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)18L);
138                 COMDLG32_PIDL_ILRemoveLastID =(void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)17L);
139                 
140                 /* SHELL */
141                 
142                 COMDLG32_SHFree = (void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)195L);
143                 COMDLG32_SHGetSpecialFolderLocation = (void*)GetProcAddress(SHELL32_hInstance,"SHGetSpecialFolderLocation");
144                 COMDLG32_SHGetPathFromIDListA = (void*)GetProcAddress(SHELL32_hInstance,"SHGetPathFromIDListA");
145                 COMDLG32_SHGetDesktopFolder = (void*)GetProcAddress(SHELL32_hInstance,"SHGetDesktopFolder");
146                 COMDLG32_SHGetFileInfoA = (void*)GetProcAddress(SHELL32_hInstance,"SHGetFileInfoA");
147
148                 /* ### WARINIG ### 
149                 We can't do a GetProcAddress to link to  StrRetToBuf[A|W] sine not all 
150                 versions of the shlwapi are exporting these functions. When we are 
151                 seperating the dlls then we have to dublicate code from shell32 into comdlg32. 
152                 Till then just call these functions. These functions don't have any side effects 
153                 so it won't break the use of any combination of native and buildin dll's (jsch) */
154
155                 /* PATH */
156                 COMDLG32_PathMatchSpecW = (void*)GetProcAddress(SHLWAPI_hInstance,"PathMatchSpecW");
157                 COMDLG32_PathIsRootA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathIsRootA");
158                 COMDLG32_PathRemoveFileSpecA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathRemoveFileSpecA");
159                 COMDLG32_PathFindFilenameA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathFindFileNameA");
160                 COMDLG32_PathAddBackslashA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathAddBackslashA");
161                 break;
162
163         case DLL_PROCESS_DETACH:
164                 if(!--COMDLG32_Attach)
165                 {
166                         TlsFree(COMDLG32_TlsIndex);
167                         COMDLG32_hInstance = 0;
168                         if(COMDLG32_hInstance16)
169                                 FreeLibrary16(COMDLG32_hInstance16);
170
171                 }
172                 FreeLibrary(COMCTL32_hInstance);
173                 FreeLibrary(SHELL32_hInstance);
174                 FreeLibrary(SHLWAPI_hInstance);
175                 break;
176         }
177         return TRUE;
178 }
179
180
181 /***********************************************************************
182  *      COMDLG32_AllocMem                       (internal)
183  * Get memory for internal datastructure plus stringspace etc.
184  *      RETURNS
185  *              Pointer to a heap block: Succes
186  *              NULL: Failure
187  */
188 LPVOID COMDLG32_AllocMem(
189         int size        /* [in] Block size to allocate */
190 ) {
191         LPVOID ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
192         if(!ptr)
193         {
194                 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
195                 return NULL;
196         }
197         return ptr;
198 }
199
200
201 /***********************************************************************
202  *      COMDLG32_SetCommDlgExtendedError        (internal)
203  *
204  * Used to set the thread's local error value if a comdlg32 function fails.
205  */
206 void COMDLG32_SetCommDlgExtendedError(DWORD err)
207 {
208         TRACE("(%08lx)\n", err);
209         TlsSetValue(COMDLG32_TlsIndex, (void *)err);
210 }
211
212
213 /***********************************************************************
214  *      CommDlgExtendedError                    (COMDLG32.5)
215  *
216  * Get the thread's local error value if a comdlg32 function fails.
217  *      RETURNS
218  *              Current error value which might not be valid
219  *              if a previous call succeeded.
220  */
221 DWORD WINAPI CommDlgExtendedError(void)
222 {
223         return (DWORD)TlsGetValue(COMDLG32_TlsIndex);
224 }