Moved function from mslu to utils to make the
[wxWidgets.git] / src / msw / mslu.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/mslu.cpp
3 // Purpose: Fixes for bugs in MSLU
4 // Author: Vaclav Slavik
5 // Modified by:
6 // Created: 2002/02/17
7 // RCS-ID: $Id$
8 // Copyright: (c) 2002 Vaclav Slavik
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #include <dir.h>
22 #endif
23
24 #ifndef WX_PRECOMP
25 #include "wx/defs.h"
26 #endif
27
28 //------------------------------------------------------------------------
29
30 #if wxUSE_UNICODE_MSLU
31
32 //------------------------------------------------------------------------
33 //
34 // NB: MSLU only covers Win32 API, it doesn't provide Unicode implementation of
35 // libc functions. Unfortunately, some of MSVCRT wchar_t functions
36 // (e.g. _wopen) don't work on Windows 9x, so we have to workaround it
37 // by calling the char version. We still want to use wchar_t version on
38 // NT/2000/XP, though, because they allow for Unicode file names.
39 //
40 // Moreover, there are bugs in unicows.dll, of course. We have to
41 // workaround them, too.
42 //
43 //------------------------------------------------------------------------
44
45 #include "wx/msw/private.h"
46 #include "wx/msw/mslu.h"
47
48 #include <stdio.h>
49 #include <io.h>
50 #include <sys/stat.h>
51
52 #ifdef __VISUALC__
53 #include <direct.h>
54 #endif
55
56 // Undef redirection macros defined in wx/msw/mslu.h:
57 #undef DrawStateW
58 #undef GetOpenFileNameW
59 #undef GetSaveFileNameW
60
61 //------------------------------------------------------------------------
62 // Wrongly implemented functions from unicows.dll
63 //------------------------------------------------------------------------
64
65 #if wxUSE_GUI
66
67 WXDLLEXPORT int wxMSLU_DrawStateW(WXHDC dc, WXHBRUSH br, WXFARPROC outputFunc,
68 WXLPARAM lData, WXWPARAM wData,
69 int x, int y, int cx, int cy,
70 unsigned int flags)
71 {
72 // VS: There's yet another bug in MSLU: DrawStateW behaves like if it was
73 // expecting char*, not wchar_t* input. We have to use DrawStateA
74 // explicitly.
75
76 if ( wxUsingUnicowsDll() )
77 {
78 return DrawStateA((HDC)dc, (HBRUSH)br, (DRAWSTATEPROC)outputFunc,
79 (LPARAM)(const char*)
80 wxConvLocal.cWX2MB((const wxChar*)lData),
81 wData, x, y, cx, cy, flags);
82 }
83 else
84 {
85 return DrawStateW((HDC)dc, (HBRUSH)br, (DRAWSTATEPROC)outputFunc,
86 lData, wData, x, y, cx, cy, flags);
87 }
88 }
89
90 static void wxFixOPENFILENAME(LPOPENFILENAME ofn)
91 {
92 #ifdef OFN_EXPLORER
93 // VS: there's a bug in unicows.dll - when multiple files are selected,
94 // of.nFileOffset doesn't point to the first filename but rather to
95 // the last component of directory name. This bug is known to MSLU
96 // developers, but they are not going to fix it: "this is a true
97 // limitation, that we have decided to live with" and "working
98 // harder on this case just did not seem worth the effort"...
99 //
100 // Our only option is to try to fix it ourselves:
101
102 if ( (ofn->Flags & OFN_ALLOWMULTISELECT) &&
103 ofn->lpstrFile[ofn->nFileOffset-1] != wxT('\0') )
104 {
105 if ( wxDirExists(ofn->lpstrFile) )
106 {
107 // 1st component is dir => multiple files selected
108 ofn->nFileOffset = wxStrlen(ofn->lpstrFile)+1;
109 }
110 }
111 #endif
112 }
113
114 WXDLLEXPORT int wxMSLU_GetOpenFileNameW(void *ofn)
115 {
116 int ret = GetOpenFileName((LPOPENFILENAME)ofn);
117 if ( wxUsingUnicowsDll() && ret != 0 )
118 wxFixOPENFILENAME((LPOPENFILENAME)ofn);
119 return ret;
120 }
121
122 WXDLLEXPORT int wxMSLU_GetSaveFileNameW(void *ofn)
123 {
124 int ret = GetSaveFileName((LPOPENFILENAME)ofn);
125 if ( wxUsingUnicowsDll() && ret != 0 )
126 wxFixOPENFILENAME((LPOPENFILENAME)ofn);
127 return ret;
128 }
129
130 #endif // wxUSE_GUI
131
132 //------------------------------------------------------------------------
133 // Missing libc file manipulation functions in Win9x
134 //------------------------------------------------------------------------
135
136 #if wxUSE_BASE
137
138 WXDLLIMPEXP_BASE int wxMSLU__trename(const wxChar *oldname,
139 const wxChar *newname)
140 {
141 if ( wxUsingUnicowsDll() )
142 return rename(wxConvFile.cWX2MB(oldname), wxConvFile.cWX2MB(newname));
143 else
144 return _trename(oldname, newname);
145 }
146
147 WXDLLIMPEXP_BASE int wxMSLU__tremove(const wxChar *name)
148 {
149 if ( wxUsingUnicowsDll() )
150 return remove(wxConvFile.cWX2MB(name));
151 else
152 return _tremove(name);
153 }
154
155 #if defined( __VISUALC__ ) \
156 || ( defined(__MINGW32__) && wxCHECK_W32API_VERSION( 0, 5 ) ) \
157 || ( defined(__MWERKS__) && defined(__WXMSW__) ) \
158 || ( defined(__BORLANDC__) && (__BORLANDC__ > 0x460) )
159
160 WXDLLIMPEXP_BASE int wxMSLU__wopen(const wxChar *name, int flags, int mode)
161 {
162 if ( wxUsingUnicowsDll() )
163 #ifdef __BORLANDC__
164 return open(wxConvFile.cWX2MB(name), flags, mode);
165 #else
166 return _open(wxConvFile.cWX2MB(name), flags, mode);
167 #endif
168 else
169 return _wopen(name, flags, mode);
170 }
171
172 WXDLLIMPEXP_BASE int wxMSLU__waccess(const wxChar *name, int mode)
173 {
174 if ( wxUsingUnicowsDll() )
175 return _access(wxConvFile.cWX2MB(name), mode);
176 else
177 return _waccess(name, mode);
178 }
179
180 WXDLLIMPEXP_BASE int wxMSLU__wmkdir(const wxChar *name)
181 {
182 if ( wxUsingUnicowsDll() )
183 return _mkdir(wxConvFile.cWX2MB(name));
184 else
185 return _wmkdir(name);
186 }
187
188 WXDLLIMPEXP_BASE int wxMSLU__wrmdir(const wxChar *name)
189 {
190 if ( wxUsingUnicowsDll() )
191 return _rmdir(wxConvFile.cWX2MB(name));
192 else
193 return _wrmdir(name);
194 }
195
196 WXDLLIMPEXP_BASE int wxMSLU__wstat(const wxChar *name, struct _stat *buffer)
197 {
198 if ( wxUsingUnicowsDll() )
199 return _stat((const char*)wxConvFile.cWX2MB(name), buffer);
200 else
201 return _wstat(name, buffer);
202 }
203
204 WXDLLIMPEXP_BASE int wxMSLU__wstati64(const wxChar *name, struct _stati64 *buffer)
205 {
206 if ( wxUsingUnicowsDll() )
207 return _stati64((const char*)wxConvFile.cWX2MB(name), buffer);
208 else
209 return _wstati64(name, buffer);
210 }
211
212 #endif // compilers having wopen() &c
213
214 #endif // wxUSE_BASE
215
216 #endif // wxUSE_UNICODE_MSLU