From 136cb3c7a9fff4252c2bb48aac5db124f8dc3ce0 Mon Sep 17 00:00:00 2001
From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= <vslavik@fastmail.fm>
Date: Sun, 17 Feb 2002 23:35:18 +0000
Subject: [PATCH] more MSLU fixes and moved MSLU stuff into separate file

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14293 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 src/msw/filedlg.cpp  |  23 -----
 src/msw/mslu.cpp     | 196 +++++++++++++++++++++++++++++++++++++++++++
 src/msw/ownerdrw.cpp |  21 +----
 src/msw/textctrl.cpp |   4 +-
 src/msw/window.cpp   |  19 +++--
 5 files changed, 212 insertions(+), 51 deletions(-)
 create mode 100644 src/msw/mslu.cpp

diff --git a/src/msw/filedlg.cpp b/src/msw/filedlg.cpp
index 4f0d03e243..c50dfe1f0d 100644
--- a/src/msw/filedlg.cpp
+++ b/src/msw/filedlg.cpp
@@ -398,29 +398,6 @@ int wxFileDialog::ShowModal()
                                             : (GetOpenFileName(&of) != 0);
         }
     }
-
-#if wxUSE_UNICODE_MSLU && defined(OFN_EXPLORER)
-    // VS: there's a bug in unicows.dll - when multiple files are selected, 
-    //     of.nFileOffset doesn't point to the first filename but rather to 
-    //     the last component of directory name. This bug is known to MSLU
-    //     developers, but they are not going to fix it: "this is a true 
-    //     limitation, that we have decided to live with" and "working
-    //     harder on this case just did not seem worth the effort"...
-    //
-    //     Our only option is to try to fix it ourselves:
-
-    if ( (m_dialogStyle & wxMULTIPLE) &&
-         (fileNameBuffer[of.nFileOffset-1] != wxT('\0')) &&
-         wxGetOsVersion() == wxWIN95 /*using unicows.dll*/)
-    {
-        if ( wxDirExists(fileNameBuffer) )
-        {
-            // 1st component is dir => multiple files selected
-            of.nFileOffset = wxStrlen(fileNameBuffer)+1;
-        }
-    }
-#endif // wxUSE_UNICODE_MSLU
-
 #endif // __WIN32__
 
     if ( success )
diff --git a/src/msw/mslu.cpp b/src/msw/mslu.cpp
new file mode 100644
index 0000000000..8e1dea110d
--- /dev/null
+++ b/src/msw/mslu.cpp
@@ -0,0 +1,196 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        msw/mslu.cpp
+// Purpose:     Fixes for bugs in MSLU
+// Author:      Vaclav Slavik
+// Modified by:
+// Created:     2002/02/17
+// RCS-ID:      $Id$
+// Copyright:   (c) 2002 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+    #include "wx/defs.h"
+#endif
+
+#if wxUSE_UNICODE_MSLU
+
+//------------------------------------------------------------------------
+//
+// NB: MSLU only covers Win32 API, it doesn't provide Unicode implementation of
+//     libc functions. Unfortunately, some of MSVCRT wchar_t functions
+//     (e.g. _wopen) don't work on Windows 9x, so we have to workaround it
+//     by calling the char version. We still want to use wchar_t version on
+//     NT/2000/XP, though, because they allow for Unicode file names.
+//
+//     Moreover, there are bugs in unicows.dll, of course. We have to 
+//     workaround them, too.
+//
+//------------------------------------------------------------------------
+
+#include "wx/msw/private.h"
+#include "wx/msw/mslu.h"
+
+#include <stdio.h>
+#include <io.h>
+
+#ifdef __GNUWIN32__
+    #include <wchar.h>
+    #include <sys/stat.h>
+#endif
+
+
+// Undef redirection macros defined in wx/msw/mslu.h:
+#undef DrawStateW
+#undef GetOpenFileNameW
+#undef GetSaveFileNameW
+
+//------------------------------------------------------------------------
+// Wrongly implemented functions from unicows.dll
+//------------------------------------------------------------------------
+
+#if wxUSE_GUI
+
+WXDLLEXPORT bool wxMSLU_DrawStateW(WXHDC dc, WXHBRUSH br, WXFARPROC outputFunc, 
+                                   WXLPARAM lData, WXWPARAM wData, 
+                                   int x, int y, int cx, int cy, 
+                                   unsigned int flags)
+{
+    // VS: There's yet another bug in MSLU: DrawStateW behaves like if it was
+    //     expecting char*, not wchar_t* input. We have to use DrawStateA 
+    //     explicitly.
+
+    if ( wxUsingUnicowsDll() )
+    {
+		return DrawStateA((HDC)dc, (HBRUSH)br, (DRAWSTATEPROC)outputFunc,
+                          (LPARAM)(const char*)
+                                wxConvLocal.cWX2MB((const wxChar*)lData),
+                          wData, x, y, cx, cy, flags);
+    }
+    else
+    {
+        return DrawStateW((HDC)dc, (HBRUSH)br, (DRAWSTATEPROC)outputFunc, 
+                          lData, wData, x, y, cx, cy, flags);
+    }
+}
+
+static void wxFixOPENFILENAME(LPOPENFILENAME ofn)
+{
+#ifdef OFN_EXPLORER
+    // VS: there's a bug in unicows.dll - when multiple files are selected, 
+    //     of.nFileOffset doesn't point to the first filename but rather to 
+    //     the last component of directory name. This bug is known to MSLU
+    //     developers, but they are not going to fix it: "this is a true 
+    //     limitation, that we have decided to live with" and "working
+    //     harder on this case just did not seem worth the effort"...
+    //
+    //     Our only option is to try to fix it ourselves:
+
+    if ( (ofn->Flags & OFN_ALLOWMULTISELECT) &&
+         ofn->lpstrFile[ofn->nFileOffset-1] != wxT('\0') )
+    {
+        if ( wxDirExists(ofn->lpstrFile) )
+        {
+            // 1st component is dir => multiple files selected
+            ofn->nFileOffset = wxStrlen(ofn->lpstrFile)+1;
+        }
+    }
+#endif
+}
+
+WXDLLEXPORT bool wxMSLU_GetOpenFileNameW(void *ofn)
+{
+    bool ret = GetOpenFileName((LPOPENFILENAME)ofn);
+    if ( wxUsingUnicowsDll() && ret != 0 )
+        wxFixOPENFILENAME((LPOPENFILENAME)ofn);
+    return ret;
+}
+
+WXDLLEXPORT bool wxMSLU_GetSaveFileNameW(void *ofn)
+{
+    bool ret = GetSaveFileName((LPOPENFILENAME)ofn);
+    if ( wxUsingUnicowsDll() && ret != 0 )
+        wxFixOPENFILENAME((LPOPENFILENAME)ofn);
+    return ret;
+}
+
+#endif // wxUSE_GUI
+
+//------------------------------------------------------------------------
+// Missing libc file manipulation functions in Win9x
+//------------------------------------------------------------------------
+
+WXDLLEXPORT int wxMSLU__trename(const wxChar *oldname, const wxChar *newname)
+{
+    if ( wxUsingUnicowsDll() )
+        return rename(wxConvFile.cWX2MB(oldname), wxConvFile.cWX2MB(newname));
+    else
+        return _trename(oldname, newname);
+}
+
+WXDLLEXPORT int wxMSLU__tremove(const wxChar *name)
+{
+    if ( wxUsingUnicowsDll() )
+        return remove(wxConvFile.cWX2MB(name));
+    else
+        return _tremove(name);
+}
+
+#if defined( __VISUALC__ ) \
+    || ( defined(__MINGW32__) && wxCHECK_W32API_VERSION( 0, 5 ) ) \
+    || ( defined(__MWERKS__) && defined(__WXMSW__) )
+
+WXDLLEXPORT int wxMSLU__wopen(const wxChar *name, int flags, int mode)
+{
+    if ( wxUsingUnicowsDll() )
+        return _open(wxConvFile.cWX2MB(name), flags, mode);
+    else
+        return _wopen(name, flags, mode);
+}
+
+WXDLLEXPORT int wxMSLU__waccess(const wxChar *name, int mode)
+{
+    if ( wxUsingUnicowsDll() )
+        return _access(wxConvFile.cWX2MB(name), mode);
+    else
+        return _waccess(name, mode);
+}
+
+WXDLLEXPORT int wxMSLU__wmkdir(const wxChar *name)
+{
+    if ( wxUsingUnicowsDll() )
+        return _mkdir(wxConvFile.cWX2MB(name));
+    else
+        return _wmkdir(name);
+}
+
+WXDLLEXPORT int wxMSLU__wrmdir(const wxChar *name)
+{
+    if ( wxUsingUnicowsDll() )
+        return _rmdir(wxConvFile.cWX2MB(name));
+    else
+        return _wrmdir(name);
+}
+
+WXDLLEXPORT int wxMSLU__wstat(const wxChar *name, struct _stat *buffer)
+{
+    if ( wxUsingUnicowsDll() )
+        return _stat((const char*)wxConvFile.cWX2MB(name), buffer);
+    else
+        return _wstat(name, buffer);
+}
+
+#endif
+
+#endif // wxUSE_UNICODE_MSLU
diff --git a/src/msw/ownerdrw.cpp b/src/msw/ownerdrw.cpp
index 37ea1f8b81..fe811c55d6 100644
--- a/src/msw/ownerdrw.cpp
+++ b/src/msw/ownerdrw.cpp
@@ -23,7 +23,7 @@
 
 #ifndef WX_PRECOMP
   #include "wx/window.h"
-//  #include "wx/msw/private.h"
+  #include "wx/msw/private.h"
   #include "wx/font.h"
   #include "wx/bitmap.h"
   #include "wx/dcmemory.h"
@@ -191,29 +191,12 @@ bool wxOwnerDrawn::OnDrawItem(wxDC& dc,
 
     HFONT hPrevFont = (HFONT) ::SelectObject(hdc, hfont);
    
-
-#if wxUSE_UNICODE_MSLU
-	if ( wxGetOsVersion() == wxWIN95 /* using unicows.dll */ )
-	{
-		// VS: There's yet another bug in MSLU: DrawStateW behaves
-		//     like if it was expecting char*, not wchar_t* input.
-		//     We have to use DrawStateA explicitly.
-		DrawStateA(hdc, NULL, NULL,
-				   (LPARAM)(const char*)m_strName.mb_str(wxConvLocal),
-				   m_strName.length(),
-                   x, rc.y, rc.GetWidth(), rc.GetHeight(),
-                   DST_PREFIXTEXT | 
-					   (st & wxODDisabled ? DSS_DISABLED : 0));
-	}
-	else
-#else
 	DrawState(hdc, NULL, NULL,
               (LPARAM)m_strName.c_str(), m_strName.length(),
               x, rc.y, rc.GetWidth(), rc.GetHeight(),
               DST_PREFIXTEXT | (st & wxODDisabled ? DSS_DISABLED : 0));
-#endif
 
-	 if ( !m_strAccel.empty() )
+    if ( !m_strAccel.empty() )
     {
         RECT r;
         r.top = rc.GetTop();
diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp
index 3b742402c4..b5a07c4239 100644
--- a/src/msw/textctrl.cpp
+++ b/src/msw/textctrl.cpp
@@ -633,7 +633,7 @@ void wxTextCtrl::DoWriteText(const wxString& value, bool selectionOnly)
 #if wxUSE_UNICODE_MSLU
         // RichEdit doesn't have Unicode version of EM_REPLACESEL on Win9x,
         // but EM_STREAMIN works
-        if ( wxGetOsVersion() == wxWIN95 && GetRichVersion() > 1 )
+        if ( wxUsingUnicowsDll() && GetRichVersion() > 1 )
         {
            done = StreamIn(valueDos, wxFONTENCODING_SYSTEM, selectionOnly);
         }
@@ -1718,7 +1718,7 @@ bool wxRichEditModule::OnInit()
 
 void wxRichEditModule::OnExit()
 {
-    for ( int i = 0; i < WXSIZEOF(ms_hRichEdit); i++ )
+    for ( size_t i = 0; i < WXSIZEOF(ms_hRichEdit); i++ )
     {
         if ( ms_hRichEdit[i] )
         {
diff --git a/src/msw/window.cpp b/src/msw/window.cpp
index b05e19decc..1f157a7511 100644
--- a/src/msw/window.cpp
+++ b/src/msw/window.cpp
@@ -998,15 +998,20 @@ bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
     //     FIXME: Doesn't handle wnd procs set by SetWindowLong, only these set
     //            with RegisterClass!!
 
-    static wxChar buffer[512];
-    WNDCLASS cls;
+    if ( wxUsingUnicowsDll() )
+    {
+        static wxChar buffer[512];
+        WNDCLASS cls;
 
-    ::GetClassName((HWND)hWnd, buffer, 512);
-    ::GetClassInfo(wxGetInstance(), buffer, &cls);
-    return wndProc == (WXFARPROC)cls.lpfnWndProc;
-#else
-    return wndProc == (WXFARPROC)::GetWindowLong((HWND)hWnd, GWL_WNDPROC);
+        ::GetClassName((HWND)hWnd, buffer, 512);
+        ::GetClassInfo(wxGetInstance(), buffer, &cls);
+        return wndProc == (WXFARPROC)cls.lpfnWndProc;
+    }
+    else
 #endif
+    {
+        return wndProc == (WXFARPROC)::GetWindowLong((HWND)hWnd, GWL_WNDPROC);
+    }
 }
 
 // ----------------------------------------------------------------------------
-- 
2.47.2