- fixed reported bugs
[wine.git] / dlls / commdlg / cdlg32.c
blobe6381da24cb058861700f41b1417de8c2d1a729f
1 /*
2 * Common Dialog Boxes interface (32 bit)
3 * Find/Replace
5 * Copyright 1999 Bertho A. Stultiens
6 */
8 #include "winbase.h"
9 #include "wine/winbase16.h"
10 #include "commdlg.h"
11 #include "cderr.h"
12 #include "debugtools.h"
14 DEFAULT_DEBUG_CHANNEL(commdlg);
16 #include "cdlg.h"
19 HINSTANCE COMDLG32_hInstance = 0;
20 HINSTANCE16 COMDLG32_hInstance16 = 0;
22 static DWORD COMDLG32_TlsIndex;
23 static int COMDLG32_Attach = 0;
25 HINSTANCE COMCTL32_hInstance = 0;
26 HINSTANCE SHELL32_hInstance = 0;
27 HINSTANCE SHLWAPI_hInstance = 0;
28 HINSTANCE SHFOLDER_hInstance = 0;
30 /* IMAGELIST */
31 BOOL (WINAPI* COMDLG32_ImageList_Draw) (HIMAGELIST himl, int i, HDC hdcDest, int x, int y, UINT fStyle);
33 /* ITEMIDLIST */
34 LPITEMIDLIST (WINAPI *COMDLG32_PIDL_ILClone) (LPCITEMIDLIST);
35 LPITEMIDLIST (WINAPI *COMDLG32_PIDL_ILCombine)(LPCITEMIDLIST,LPCITEMIDLIST);
36 LPITEMIDLIST (WINAPI *COMDLG32_PIDL_ILGetNext)(LPITEMIDLIST);
37 BOOL (WINAPI *COMDLG32_PIDL_ILRemoveLastID)(LPCITEMIDLIST);
38 BOOL (WINAPI *COMDLG32_PIDL_ILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST);
40 /* SHELL */
41 BOOL (WINAPI *COMDLG32_SHGetPathFromIDListA) (LPCITEMIDLIST,LPSTR);
42 HRESULT (WINAPI *COMDLG32_SHGetSpecialFolderLocation)(HWND,INT,LPITEMIDLIST *);
43 DWORD (WINAPI *COMDLG32_SHGetDesktopFolder)(IShellFolder **);
44 DWORD (WINAPI *COMDLG32_SHGetFileInfoA)(LPCSTR,DWORD,SHFILEINFOA*,UINT,UINT);
45 LPVOID (WINAPI *COMDLG32_SHAlloc)(DWORD);
46 DWORD (WINAPI *COMDLG32_SHFree)(LPVOID);
47 HRESULT (WINAPI *COMDLG32_SHGetDataFromIDListA)(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len);
48 HRESULT (WINAPI *COMDLG32_StrRetToBufA)(LPSTRRET,LPITEMIDLIST,LPSTR,DWORD);
49 HRESULT (WINAPI *COMDLG32_StrRetToBufW)(LPSTRRET,LPITEMIDLIST,LPWSTR,DWORD);
50 BOOL (WINAPI *COMDLG32_SHGetFolderPathA)(HWND,int,HANDLE,DWORD,LPSTR);
52 /* PATH */
53 BOOL (WINAPI *COMDLG32_PathIsRootA)(LPCSTR x);
54 LPSTR (WINAPI *COMDLG32_PathFindFileNameA)(LPCSTR path);
55 DWORD (WINAPI *COMDLG32_PathRemoveFileSpecA)(LPSTR fn);
56 BOOL (WINAPI *COMDLG32_PathMatchSpecW)(LPCWSTR x, LPCWSTR y);
57 LPSTR (WINAPI *COMDLG32_PathAddBackslashA)(LPSTR path);
58 BOOL (WINAPI *COMDLG32_PathCanonicalizeA)(LPSTR pszBuf, LPCSTR pszPath);
59 int (WINAPI *COMDLG32_PathGetDriveNumberA)(LPCSTR lpszPath);
60 BOOL (WINAPI *COMDLG32_PathIsRelativeA) (LPCSTR lpszPath);
61 LPSTR (WINAPI *COMDLG32_PathFindNextComponentA)(LPCSTR pszPath);
62 LPWSTR (WINAPI *COMDLG32_PathAddBackslashW)(LPWSTR lpszPath);
63 LPSTR (WINAPI *COMDLG32_PathFindExtensionA)(LPCVOID lpszPath);
64 BOOL (WINAPI *COMDLG32_PathAddExtensionA)(LPSTR pszPath,LPCSTR pszExtension);
66 /***********************************************************************
67 * COMDLG32_DllEntryPoint (COMDLG32.entry)
69 * Initialization code for the COMDLG32 DLL
71 * RETURNS:
72 * FALSE if sibling could not be loaded or instantiated twice, TRUE
73 * otherwise.
75 static char * GPA_string = "Failed to get entry point %s for hinst = 0x%08x\n";
76 #define GPA(dest, hinst, name) \
77 if(!(dest = (void*)GetProcAddress(hinst,name)))\
78 { \
79 ERR(GPA_string, debugres_a(name), hinst); \
80 return FALSE; \
83 BOOL WINAPI COMDLG32_DllEntryPoint(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
85 TRACE("(%08x, %08lx, %p)\n", hInstance, Reason, Reserved);
87 switch(Reason)
89 case DLL_PROCESS_ATTACH:
90 COMDLG32_Attach++;
91 if(COMDLG32_hInstance)
93 ERR("comdlg32.dll instantiated twice in one address space!\n");
95 * We should return FALSE here, but that will break
96 * most apps that use CreateProcess because we do
97 * not yet support seperate address spaces.
99 return TRUE;
102 COMDLG32_hInstance = hInstance;
103 DisableThreadLibraryCalls(hInstance);
105 if(!COMDLG32_hInstance16)
107 if(!(COMDLG32_hInstance16 = LoadLibrary16("commdlg.dll")))
109 ERR("Could not load sibling commdlg.dll\n");
110 return FALSE;
114 COMDLG32_TlsIndex = 0xffffffff;
116 COMCTL32_hInstance = GetModuleHandleA("COMCTL32.DLL");
117 SHELL32_hInstance = GetModuleHandleA("SHELL32.DLL");
118 SHLWAPI_hInstance = GetModuleHandleA("SHLWAPI.DLL");
120 if (!COMCTL32_hInstance || !SHELL32_hInstance || !SHLWAPI_hInstance)
122 ERR("loading of comctl32 or shell32 or shlwapi failed\n");
123 return FALSE;
126 /* IMAGELIST */
127 GPA(COMDLG32_ImageList_Draw, COMCTL32_hInstance,"ImageList_Draw");
129 /* ITEMIDLIST */
130 GPA(COMDLG32_PIDL_ILIsEqual, SHELL32_hInstance, (LPCSTR)21L);
131 GPA(COMDLG32_PIDL_ILCombine, SHELL32_hInstance, (LPCSTR)25L);
132 GPA(COMDLG32_PIDL_ILGetNext, SHELL32_hInstance, (LPCSTR)153L);
133 GPA(COMDLG32_PIDL_ILClone, SHELL32_hInstance, (LPCSTR)18L);
134 GPA(COMDLG32_PIDL_ILRemoveLastID, SHELL32_hInstance, (LPCSTR)17L);
136 /* SHELL */
138 GPA(COMDLG32_SHAlloc, SHELL32_hInstance, (LPCSTR)196L);
139 GPA(COMDLG32_SHFree, SHELL32_hInstance, (LPCSTR)195L);
140 GPA(COMDLG32_SHGetSpecialFolderLocation, SHELL32_hInstance,"SHGetSpecialFolderLocation");
141 GPA(COMDLG32_SHGetPathFromIDListA, SHELL32_hInstance,"SHGetPathFromIDListA");
142 GPA(COMDLG32_SHGetDesktopFolder, SHELL32_hInstance,"SHGetDesktopFolder");
143 GPA(COMDLG32_SHGetFileInfoA, SHELL32_hInstance,"SHGetFileInfoA");
144 GPA(COMDLG32_SHGetDataFromIDListA, SHELL32_hInstance,"SHGetDataFromIDListA");
146 /* for the first versions of shell32 SHGetFolderPathA is in SHFOLDER.DLL */
147 COMDLG32_SHGetFolderPathA = (void*)GetProcAddress(SHELL32_hInstance,"SHGetFolderPathA");
148 if (!COMDLG32_SHGetFolderPathA)
150 SHFOLDER_hInstance = LoadLibraryA("SHFOLDER.DLL");
151 GPA(COMDLG32_SHGetFolderPathA, SHFOLDER_hInstance,"SHGetFolderPathA");
154 /* ### WARINIG ###
155 We can't do a GetProcAddress to link to StrRetToBuf[A|W] sine not all
156 versions of the shlwapi are exporting these functions. When we are
157 seperating the dlls then we have to dublicate code from shell32 into comdlg32.
158 Till then just call these functions. These functions don't have any side effects
159 so it won't break the use of any combination of native and buildin dll's (jsch) */
161 /* PATH */
162 GPA(COMDLG32_PathMatchSpecW, SHLWAPI_hInstance,"PathMatchSpecW");
163 GPA(COMDLG32_PathIsRootA, SHLWAPI_hInstance,"PathIsRootA");
164 GPA(COMDLG32_PathRemoveFileSpecA, SHLWAPI_hInstance,"PathRemoveFileSpecA");
165 GPA(COMDLG32_PathFindFileNameA, SHLWAPI_hInstance,"PathFindFileNameA");
166 GPA(COMDLG32_PathAddBackslashA, SHLWAPI_hInstance,"PathAddBackslashA");
167 GPA(COMDLG32_PathCanonicalizeA, SHLWAPI_hInstance,"PathCanonicalizeA");
168 GPA(COMDLG32_PathGetDriveNumberA, SHLWAPI_hInstance,"PathGetDriveNumberA");
169 GPA(COMDLG32_PathIsRelativeA, SHLWAPI_hInstance,"PathIsRelativeA");
170 GPA(COMDLG32_PathFindNextComponentA, SHLWAPI_hInstance,"PathFindNextComponentA");
171 GPA(COMDLG32_PathAddBackslashW, SHLWAPI_hInstance,"PathAddBackslashW");
172 GPA(COMDLG32_PathFindExtensionA, SHLWAPI_hInstance,"PathFindExtensionA");
173 GPA(COMDLG32_PathAddExtensionA, SHLWAPI_hInstance,"PathAddExtensionA");
174 break;
176 case DLL_PROCESS_DETACH:
177 if(!--COMDLG32_Attach)
179 if (COMDLG32_TlsIndex != 0xffffffff)
180 TlsFree(COMDLG32_TlsIndex);
181 COMDLG32_TlsIndex = 0xffffffff;
182 COMDLG32_hInstance = 0;
183 if(COMDLG32_hInstance16)
184 FreeLibrary16(COMDLG32_hInstance16);
185 if(SHFOLDER_hInstance)
186 FreeLibrary(SHFOLDER_hInstance);
189 break;
191 return TRUE;
193 #undef GPA
195 /***********************************************************************
196 * COMDLG32_AllocMem (internal)
197 * Get memory for internal datastructure plus stringspace etc.
198 * RETURNS
199 * Pointer to a heap block: Succes
200 * NULL: Failure
202 LPVOID COMDLG32_AllocMem(
203 int size /* [in] Block size to allocate */
205 LPVOID ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
206 if(!ptr)
208 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
209 return NULL;
211 return ptr;
215 /***********************************************************************
216 * COMDLG32_SetCommDlgExtendedError (internal)
218 * Used to set the thread's local error value if a comdlg32 function fails.
220 void COMDLG32_SetCommDlgExtendedError(DWORD err)
222 TRACE("(%08lx)\n", err);
223 if (COMDLG32_TlsIndex == 0xffffffff)
224 COMDLG32_TlsIndex = TlsAlloc();
225 if (COMDLG32_TlsIndex != 0xffffffff)
226 TlsSetValue(COMDLG32_TlsIndex, (void *)err);
227 else
228 FIXME("No Tls Space\n");
232 /***********************************************************************
233 * CommDlgExtendedError (COMDLG32.5)
235 * Get the thread's local error value if a comdlg32 function fails.
236 * RETURNS
237 * Current error value which might not be valid
238 * if a previous call succeeded.
240 DWORD WINAPI CommDlgExtendedError(void)
242 if (COMDLG32_TlsIndex != 0xffffffff)
243 return (DWORD)TlsGetValue(COMDLG32_TlsIndex);
244 else
246 FIXME("No Tls Space\n");
247 return 0;