Index: trunk/src/user32/oslibmenu.cpp
===================================================================
--- trunk/src/user32/oslibmenu.cpp	(revision 1512)
+++ trunk/src/user32/oslibmenu.cpp	(revision 1513)
@@ -1,3 +1,3 @@
-/* $Id: oslibmenu.cpp,v 1.3 1999-10-25 20:17:18 sandervl Exp $ */
+/* $Id: oslibmenu.cpp,v 1.4 1999-10-30 09:19:44 sandervl Exp $ */
 /*
  * Window Menu wrapper functions for OS/2
@@ -31,4 +31,5 @@
    if (currMenu)
    {
+      dprintf(("OSLibWinSetMenu: old menu %x, new menu %x", currMenu, hMenu));
       WinSetOwner (currMenu, HWND_OBJECT);
       WinSetParent(currMenu, HWND_OBJECT, FALSE);
@@ -37,11 +38,15 @@
    if (hMenu)
    {
-      if(WinIsWindow(GetThreadHAB(), hMenu) == TRUE) {
-         WinSetOwner (hMenu, hwndParent);
-         WinSetParent(hMenu, hwndParent, FALSE );
-         WinSetWindowUShort(hMenu, QWS_ID, FID_MENU);
-     WinSendMsg(hwndParent, WM_UPDATEFRAME, (MPARAM)FCF_MENU, 0);
-     return hMenu;
-      }
+      	if(WinIsWindow(GetThreadHAB(), hMenu) == TRUE) 
+	{
+         	WinSetOwner (hMenu, hwndParent);
+         	WinSetParent(hMenu, hwndParent, FALSE );
+         	WinSetWindowUShort(hMenu, QWS_ID, FID_MENU);
+     		WinSendMsg(hwndParent, WM_UPDATEFRAME, (MPARAM)FCF_MENU, 0);
+     		return hMenu;
+      	}
+	else {
+		dprintf(("OSLibWinSetMenu: %x = invalid menu handle", hMenu));
+	}
    }
    return 0;
Index: trunk/src/user32/uitools.cpp
===================================================================
--- trunk/src/user32/uitools.cpp	(revision 1512)
+++ trunk/src/user32/uitools.cpp	(revision 1513)
@@ -1,3 +1,3 @@
-/* $Id: uitools.cpp,v 1.14 1999-10-17 19:32:05 cbratschi Exp $ */
+/* $Id: uitools.cpp,v 1.15 1999-10-30 09:19:44 sandervl Exp $ */
 /*
  * User Interface Functions
@@ -1908,5 +1908,5 @@
         return 0;
     }
-    dprintf(("DrawMenuBar\n"));
+    dprintf(("DrawMenuBar %x", hwnd));
     return O32_DrawMenuBar(window->getOS2FrameWindowHandle());
 }
Index: trunk/src/user32/win32dlg.cpp
===================================================================
--- trunk/src/user32/win32dlg.cpp	(revision 1512)
+++ trunk/src/user32/win32dlg.cpp	(revision 1513)
@@ -1,3 +1,3 @@
-/* $Id: win32dlg.cpp,v 1.21 1999-10-28 23:51:05 sandervl Exp $ */
+/* $Id: win32dlg.cpp,v 1.22 1999-10-30 09:19:45 sandervl Exp $ */
 /*
  * Win32 Dialog Code for OS/2
@@ -606,4 +606,5 @@
 
         dprintf(("Create CONTROL %d", info.id));
+#if 0
         if(isUnicode) {
             hwndCtrl = ::CreateWindowExW( info.exStyle | WS_EX_NOPARENTNOTIFY,
@@ -619,4 +620,5 @@
         }
         else {
+#endif
             char *classNameA = NULL;
             char *windowNameA = NULL;
@@ -646,5 +648,5 @@
                 FreeAsciiString(windowNameA);
             }
-        }
+//        }
 
         if (!hwndCtrl) return FALSE;
Index: trunk/src/user32/win32wbase.cpp
===================================================================
--- trunk/src/user32/win32wbase.cpp	(revision 1512)
+++ trunk/src/user32/win32wbase.cpp	(revision 1513)
@@ -1,3 +1,3 @@
-/* $Id: win32wbase.cpp,v 1.67 1999-10-29 16:06:56 cbratschi Exp $ */
+/* $Id: win32wbase.cpp,v 1.68 1999-10-30 09:19:45 sandervl Exp $ */
 /*
  * Win32 Window Base Class for OS/2
@@ -420,27 +420,4 @@
   hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
                   ? HWND_BOTTOM : HWND_TOP;
-#endif
-
-#if 0
-//TODO
-    /* Call the WH_CBT hook */
-
-    if (HOOK_IsHooked( WH_CBT ))
-    {
-        CBT_CREATEWNDA cbtc;
-        LRESULT ret;
-
-        cbtc.lpcs = cs;
-        cbtc.hwndInsertAfter = hwndLinkAfter;
-        ret = unicode ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc)
-                      : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc);
-        if (ret)
-    {
-        TRACE_(win)("CBT-hook returned 0\n");
-        wndPtr->pDriver->pFinalize(wndPtr);
-            retvalue =  0;
-            goto end;
-    }
-    }
 #endif
 
@@ -1256,6 +1233,6 @@
   return NULL;
 }
-/***********************************************************************/
-/***********************************************************************/
+//******************************************************************************
+//******************************************************************************
 VOID Win32BaseWindow::subclassScrollBars(BOOL subHorz,BOOL subVert)
 {
@@ -1596,12 +1573,27 @@
 
     case WM_GETTEXT:   //TODO: SS_ICON controls
-        lstrcpynW((LPWSTR)lParam, windowNameW, wParam);
-        return min(wndNameLength, wParam);
+    {
+            LRESULT result;
+            char *str = (char *) malloc(wParam + 1);
+            result = DefWindowProcA(Msg, wParam, (LPARAM)str );
+            lstrcpynAtoW( (LPWSTR)lParam, str, wParam );
+            free(str);
+            return result;
+    }
 
     case WM_SETTEXT:
-        if(!fInternalMsg) {
-                return SetWindowTextW((LPWSTR)lParam);
+    {
+        if(!fInternalMsg) 
+        {
+           LRESULT result;
+           char *aText = (char *) malloc((lstrlenW((LPWSTR)lParam)+1)*sizeof(WCHAR));
+           *aText = 0;
+           lstrcpyWtoA(aText, (LPWSTR) lParam);
+           result = SetWindowTextA(aText);
+           free(aText);
+           return result;
         }
         else    return 0;
+    }
 
     default:
@@ -1902,5 +1894,6 @@
     dprintf(("Win32BaseWindow::SetIcon %x", hIcon));
     if(OSLibWinSetIcon(OS2HwndFrame, hIcon) == TRUE) {
-        SendMessageA(WM_SETICON, hIcon, 0);
+//TODO: Wine does't send these. Correct?
+//        SendMessageA(WM_SETICON, ICON_BIG, hIcon);
         return TRUE;
     }
Index: trunk/src/user32/win32wmdichild.cpp
===================================================================
--- trunk/src/user32/win32wmdichild.cpp	(revision 1512)
+++ trunk/src/user32/win32wmdichild.cpp	(revision 1513)
@@ -1,3 +1,3 @@
-/* $Id: win32wmdichild.cpp,v 1.8 1999-10-28 12:00:36 sandervl Exp $ */
+/* $Id: win32wmdichild.cpp,v 1.9 1999-10-30 09:19:46 sandervl Exp $ */
 /*
  * Win32 MDI Child Window Class for OS/2
@@ -115,5 +115,5 @@
 
     case WM_CLOSE:
-        client->SendMessageA(WM_MDIDESTROY,(WPARAM16)getWindowHandle(), 0L);
+        client->SendMessageA(WM_MDIDESTROY,(WPARAM)getWindowHandle(), 0L);
         return 0;
 
Index: trunk/src/user32/win32wmdiclient.cpp
===================================================================
--- trunk/src/user32/win32wmdiclient.cpp	(revision 1512)
+++ trunk/src/user32/win32wmdiclient.cpp	(revision 1513)
@@ -1,3 +1,3 @@
-/* $Id: win32wmdiclient.cpp,v 1.11 1999-10-28 12:00:36 sandervl Exp $ */
+/* $Id: win32wmdiclient.cpp,v 1.12 1999-10-30 09:19:46 sandervl Exp $ */
 /*
  * Win32 MDI Client Window Class for OS/2
@@ -365,5 +365,5 @@
     }
 
-    dprintf(("childActivate: %x %x", this, child->getWindowHandle()));
+    dprintf(("childActivate: %x %x", this, (child) ? child->getWindowHandle() : 0));
     activeChild = child;
 
Index: trunk/src/user32/window.cpp
===================================================================
--- trunk/src/user32/window.cpp	(revision 1512)
+++ trunk/src/user32/window.cpp	(revision 1513)
@@ -1,3 +1,3 @@
-/* $Id: window.cpp,v 1.26 1999-10-27 18:25:24 sandervl Exp $ */
+/* $Id: window.cpp,v 1.27 1999-10-30 09:19:47 sandervl Exp $ */
 /*
  * Win32 window apis for OS/2
@@ -47,4 +47,23 @@
         return CreateMDIWindowA(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
 
+#if 1
+    /* Find the class atom */
+    if (!(classAtom = GlobalFindAtomA(className)))
+    {
+       if (!HIWORD(className))
+           dprintf(("CreateWindowEx32A: bad class name %04x\n",LOWORD(className)));
+       else
+           dprintf(("CreateWindowEx32A: bad class name '%s'\n", className));
+
+       SetLastError(ERROR_INVALID_PARAMETER);
+       return 0;
+    }
+
+    if (!HIWORD(className))
+    {
+      sprintf(tmpClass,"#%d", (int) className);
+      className = tmpClass;
+    }
+#else
     /* Find the class atom */
     if (!HIWORD(className) || !(classAtom = GlobalFindAtomA(className)))
@@ -67,5 +86,5 @@
         }
     }
-
+#endif
     /* Create the window */
     cs.lpCreateParams = data;
Index: trunk/src/user32/windowmsg.cpp
===================================================================
--- trunk/src/user32/windowmsg.cpp	(revision 1512)
+++ trunk/src/user32/windowmsg.cpp	(revision 1513)
@@ -1,3 +1,3 @@
-/* $Id: windowmsg.cpp,v 1.1 1999-09-15 23:19:02 sandervl Exp $ */
+/* $Id: windowmsg.cpp,v 1.2 1999-10-30 09:19:47 sandervl Exp $ */
 /*
  * Win32 window message APIs for OS/2
@@ -5,5 +5,5 @@
  * Copyright 1999 Sander van Leeuwen
  *
- * Parts based on Wine Windows code (windows\message.c)
+ * Parts based on Wine Windows code (windows\message.c) 990508
  *
  * Copyright 1993, 1994 Alexandre Julliard
@@ -18,4 +18,5 @@
 #include <win.h>
 #include <hooks.h>
+#include <heapstring.h>
 #include "oslibwin.h"
 #include "oslibmsg.h"
@@ -249,39 +250,4 @@
     FreeAsciiString(astring);
     return rc;
-}
-//******************************************************************************
-//******************************************************************************
-LRESULT WIN32API CallWindowProcA(WNDPROC wndprcPrev,
-                                 HWND       arg2,
-                                 UINT       arg3,
-                                 WPARAM     arg4,
-                                 LPARAM     arg5)
-{
-#ifdef DEBUG
-////    WriteLog("USER32:  CallWindowProcA %X hwnd=%X, msg = %X\n", wndprcPrev, arg2, arg3);
-#endif
-
-    return wndprcPrev(arg2, arg3, arg4, arg5);   //win32 callback (__stdcall)
-}
-//******************************************************************************
-//******************************************************************************
-LRESULT WIN32API CallWindowProcW(WNDPROC arg1,
-                                 HWND       arg2,
-                                 UINT       arg3,
-                                 WPARAM     arg4,
-                                 LPARAM     arg5)
-{
-  dprintf(("USER32:  CallWindowProcW(%08xh,%08xh,%08xh,%08xh,%08xh) not properly implemented.\n",
-           arg1,
-           arg2,
-           arg3,
-           arg4,
-           arg5));
-
-  return CallWindowProcA(arg1,
-                            arg2,
-                            arg3,
-                            arg4,
-                            arg5);
 }
 //******************************************************************************
@@ -468,2 +434,572 @@
 //******************************************************************************
 //******************************************************************************
+/**********************************************************************
+ *	     WINPROC_TestCBForStr
+ *
+ * Return TRUE if the lparam is a string
+ */
+BOOL WINPROC_TestCBForStr ( HWND hwnd )
+{
+    BOOL retvalue;
+    DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);  
+    retvalue = ( !(LOWORD(dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
+	      (LOWORD(dwStyle) & CBS_HASSTRINGS) );
+    return retvalue;
+}
+/**********************************************************************
+ *	     WINPROC_TestLBForStr
+ *
+ * Return TRUE if the lparam is a string
+ */
+BOOL WINPROC_TestLBForStr ( HWND hwnd )
+{
+    BOOL retvalue;
+    DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);  
+    retvalue = ( !(LOWORD(dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) ||
+	    (LOWORD(dwStyle) & LBS_HASSTRINGS) );
+    return retvalue;
+}
+
+/**********************************************************************
+ *	     WINPROC_MapMsg32ATo32W
+ *
+ * Map a message from Ansi to Unicode.
+ * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
+ *
+ * FIXME:
+ *  WM_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR, WM_SYSDEADCHAR
+ *
+ * FIXME:
+ *  WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
+ *  the first four bytes are the handle of the icon 
+ *  when the WM_SETTEXT message has been used to set the icon
+ */
+INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
+{
+    switch(msg)
+    {
+    case WM_GETTEXT:
+        {
+            LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
+                                     wParam * sizeof(WCHAR) + sizeof(LPARAM) );
+            if (!ptr) return -1;
+            *ptr++ = *plparam;  /* Store previous lParam */
+            *plparam = (LPARAM)ptr;
+        }
+        return 1;
+    /* lparam is string (0-terminated) */
+    case WM_SETTEXT:
+    case WM_WININICHANGE:
+    case CB_DIR:
+    case CB_FINDSTRING:
+    case CB_FINDSTRINGEXACT:
+    case CB_SELECTSTRING:
+    case LB_DIR:
+    case LB_ADDFILE:
+    case LB_FINDSTRING:
+    case LB_SELECTSTRING:
+    case EM_REPLACESEL:
+        *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
+        return (*plparam ? 1 : -1);
+
+    case WM_NCCREATE:
+    case WM_CREATE:
+        {
+            CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
+                                                            sizeof(*cs) );
+            if (!cs) return -1;
+            *cs = *(CREATESTRUCTW *)*plparam;
+            if (HIWORD(cs->lpszName))
+                cs->lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
+                                                (LPCSTR)cs->lpszName );
+            if (HIWORD(cs->lpszClass))
+                cs->lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
+                                                 (LPCSTR)cs->lpszClass );
+            *plparam = (LPARAM)cs;
+        }
+        return 1;
+    case WM_MDICREATE:
+        {
+            MDICREATESTRUCTW *cs =
+                (MDICREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
+            if (!cs) return -1;
+            *cs = *(MDICREATESTRUCTW *)*plparam;
+            if (HIWORD(cs->szClass))
+                cs->szClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
+                                               (LPCSTR)cs->szClass );
+            if (HIWORD(cs->szTitle))
+                cs->szTitle = HEAP_strdupAtoW( GetProcessHeap(), 0,
+                                               (LPCSTR)cs->szTitle );
+            *plparam = (LPARAM)cs;
+        }
+        return 1;
+
+/* Listbox */
+    case LB_ADDSTRING:
+    case LB_INSERTSTRING:
+	if ( WINPROC_TestLBForStr( hwnd ))
+          *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
+        return (*plparam ? 1 : -1);
+
+    case LB_GETTEXT:		    /* fixme: fixed sized buffer */
+        { if ( WINPROC_TestLBForStr( hwnd ))
+	  { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
+            if (!ptr) return -1;
+            *ptr++ = *plparam;  /* Store previous lParam */
+            *plparam = (LPARAM)ptr;
+	  }
+        }
+        return 1;
+
+/* Combobox */
+    case CB_ADDSTRING:
+    case CB_INSERTSTRING:
+	if ( WINPROC_TestCBForStr( hwnd ))
+          *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
+        return (*plparam ? 1 : -1);
+
+    case CB_GETLBTEXT:    /* fixme: fixed sized buffer */
+        { if ( WINPROC_TestCBForStr( hwnd ))
+          { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
+            if (!ptr) return -1;
+            *ptr++ = *plparam;  /* Store previous lParam */
+            *plparam = (LPARAM)ptr;
+	  }
+        }
+        return 1;
+
+/* Multiline edit */
+    case EM_GETLINE:
+        { WORD len = (WORD)*plparam;
+	  LPARAM *ptr = (LPARAM *) HEAP_xalloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
+          if (!ptr) return -1;
+          *ptr++ = *plparam;  /* Store previous lParam */
+	  *((WORD *) ptr) = len;   /* Store the length */
+          *plparam = (LPARAM)ptr;
+	}
+        return 1;
+
+    case WM_ASKCBFORMATNAME:
+    case WM_DEVMODECHANGE:
+    case WM_PAINTCLIPBOARD:
+    case WM_SIZECLIPBOARD:
+    case EM_SETPASSWORDCHAR:
+        // FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg), msg );
+        return -1;
+    default:  /* No translation needed */
+        return 0;
+    }
+}
+
+
+/**********************************************************************
+ *	     WINPROC_UnmapMsg32ATo32W
+ *
+ * Unmap a message that was mapped from Ansi to Unicode.
+ */
+void WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+{
+    switch(msg)
+    {
+    case WM_GETTEXT:
+        {
+            LPARAM *ptr = (LPARAM *)lParam - 1;
+            lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)lParam, wParam );
+            HeapFree( GetProcessHeap(), 0, ptr );
+        }
+        break;
+
+    case WM_NCCREATE:
+    case WM_CREATE:
+        {
+            CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
+            if (HIWORD(cs->lpszName))
+                HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
+            if (HIWORD(cs->lpszClass))
+                HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
+            HeapFree( GetProcessHeap(), 0, cs );
+        }
+        break;
+
+    case WM_MDICREATE:
+        {
+            MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
+            if (HIWORD(cs->szTitle))
+                HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
+            if (HIWORD(cs->szClass))
+                HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
+            HeapFree( GetProcessHeap(), 0, cs );
+        }
+        break;
+
+    case WM_SETTEXT:
+    case WM_WININICHANGE:
+    case CB_DIR:
+    case CB_FINDSTRING:
+    case CB_FINDSTRINGEXACT:
+    case CB_SELECTSTRING:
+    case LB_DIR:
+    case LB_ADDFILE:
+    case LB_FINDSTRING:
+    case LB_SELECTSTRING:
+    case EM_REPLACESEL:
+        HeapFree( GetProcessHeap(), 0, (void *)lParam );
+        break;
+
+/* Listbox */
+    case LB_ADDSTRING:
+    case LB_INSERTSTRING:
+	if ( WINPROC_TestLBForStr( hwnd ))
+          HeapFree( GetProcessHeap(), 0, (void *)lParam );
+        break;
+
+    case LB_GETTEXT:
+        { if ( WINPROC_TestLBForStr( hwnd ))
+          { LPARAM *ptr = (LPARAM *)lParam - 1;
+	    lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
+            HeapFree( GetProcessHeap(), 0, ptr );
+	  }
+        }
+        break;
+
+/* Combobox */
+    case CB_ADDSTRING:
+    case CB_INSERTSTRING:
+	if ( WINPROC_TestCBForStr( hwnd ))
+          HeapFree( GetProcessHeap(), 0, (void *)lParam );
+        break;
+
+    case CB_GETLBTEXT:
+        { if ( WINPROC_TestCBForStr( hwnd ))
+	  { LPARAM *ptr = (LPARAM *)lParam - 1;
+            lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
+            HeapFree( GetProcessHeap(), 0, ptr );
+	  }
+        }
+        break;
+
+/* Multiline edit */
+    case EM_GETLINE:
+        { LPARAM * ptr = (LPARAM *)lParam - 1;  /* get the old lParam */
+	  WORD len = *(WORD *) lParam;
+          lstrcpynWtoA( (LPSTR)*ptr , (LPWSTR)lParam, len );
+          HeapFree( GetProcessHeap(), 0, ptr );
+        }
+        break;
+    }
+}
+
+
+/**********************************************************************
+ *	     WINPROC_MapMsg32WTo32A
+ *
+ * Map a message from Unicode to Ansi.
+ * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
+ */
+INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam)
+{   switch(msg)
+    {
+    case WM_GETTEXT:
+        {
+            LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
+                                               wParam + sizeof(LPARAM) );
+            if (!ptr) return -1;
+            *ptr++ = *plparam;  /* Store previous lParam */
+            *plparam = (LPARAM)ptr;
+        }
+        return 1;
+
+    case WM_SETTEXT:
+    case WM_WININICHANGE:
+    case CB_DIR:
+    case CB_FINDSTRING:
+    case CB_FINDSTRINGEXACT:
+    case CB_SELECTSTRING:
+    case LB_DIR:
+    case LB_ADDFILE:
+    case LB_FINDSTRING:
+    case LB_SELECTSTRING:
+    case EM_REPLACESEL:
+        *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
+        return (*plparam ? 1 : -1);
+
+    case WM_NCCREATE:
+    case WM_CREATE:
+        {
+            CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0,
+                                                            sizeof(*cs) );
+            if (!cs) return -1;
+            *cs = *(CREATESTRUCTA *)*plparam;
+            if (HIWORD(cs->lpszName))
+                cs->lpszName  = HEAP_strdupWtoA( GetProcessHeap(), 0,
+                                                 (LPCWSTR)cs->lpszName );
+            if (HIWORD(cs->lpszClass))
+                cs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
+                                                 (LPCWSTR)cs->lpszClass);
+            *plparam = (LPARAM)cs;
+        }
+        return 1;
+    case WM_MDICREATE:
+        {
+            MDICREATESTRUCTA *cs =
+                (MDICREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
+
+            if (!cs) return -1;
+            *cs = *(MDICREATESTRUCTA *)*plparam;
+            if (HIWORD(cs->szTitle))
+                cs->szTitle = HEAP_strdupWtoA( GetProcessHeap(), 0,
+                                               (LPCWSTR)cs->szTitle );
+            if (HIWORD(cs->szClass))
+                cs->szClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
+                                               (LPCWSTR)cs->szClass );
+            *plparam = (LPARAM)cs;
+        }
+        return 1;
+
+/* Listbox */
+    case LB_ADDSTRING:
+    case LB_INSERTSTRING:
+	if ( WINPROC_TestLBForStr( hwnd ))
+          *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
+        return (*plparam ? 1 : -1);
+
+    case LB_GETTEXT:			/* fixme: fixed sized buffer */
+        { if ( WINPROC_TestLBForStr( hwnd ))
+	  { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
+            if (!ptr) return -1;
+            *ptr++ = *plparam;  /* Store previous lParam */
+            *plparam = (LPARAM)ptr;
+	  }
+        }
+        return 1;
+
+/* Combobox */
+    case CB_ADDSTRING:
+    case CB_INSERTSTRING:
+	if ( WINPROC_TestCBForStr( hwnd ))
+          *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
+        return (*plparam ? 1 : -1);
+
+    case CB_GETLBTEXT:		/* fixme: fixed sized buffer */
+        { if ( WINPROC_TestCBForStr( hwnd ))
+	  { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
+            if (!ptr) return -1;
+            *ptr++ = *plparam;  /* Store previous lParam */
+            *plparam = (LPARAM)ptr;
+	  }
+        }
+        return 1;
+
+/* Multiline edit */
+    case EM_GETLINE:
+        { WORD len = (WORD)*plparam;
+	  LPARAM *ptr = (LPARAM *) HEAP_xalloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
+          if (!ptr) return -1;
+          *ptr++ = *plparam;  /* Store previous lParam */
+	  *((WORD *) ptr) = len;   /* Store the length */
+          *plparam = (LPARAM)ptr;
+	}
+        return 1;
+
+    case WM_ASKCBFORMATNAME:
+    case WM_DEVMODECHANGE:
+    case WM_PAINTCLIPBOARD:
+    case WM_SIZECLIPBOARD:
+    case EM_SETPASSWORDCHAR:
+        // FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg),msg );
+        return -1;
+    default:  /* No translation needed */
+        return 0;
+    }
+}
+
+
+/**********************************************************************
+ *	     WINPROC_UnmapMsg32WTo32A
+ *
+ * Unmap a message that was mapped from Unicode to Ansi.
+ */
+void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+{
+    switch(msg)
+    {
+    case WM_GETTEXT:
+        {
+            LPARAM *ptr = (LPARAM *)lParam - 1;
+            lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)lParam, wParam );
+            HeapFree( GetProcessHeap(), 0, ptr );
+        }
+        break;
+
+    case WM_SETTEXT:
+    case WM_WININICHANGE:
+    case CB_DIR:
+    case CB_FINDSTRING:
+    case CB_FINDSTRINGEXACT:
+    case CB_SELECTSTRING:
+    case LB_DIR:
+    case LB_ADDFILE:
+    case LB_FINDSTRING:
+    case LB_SELECTSTRING:
+    case EM_REPLACESEL:
+        HeapFree( GetProcessHeap(), 0, (void *)lParam );
+        break;
+
+    case WM_NCCREATE:
+    case WM_CREATE:
+        {
+            CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
+            if (HIWORD(cs->lpszName))
+                HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
+            if (HIWORD(cs->lpszClass))
+                HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
+            HeapFree( GetProcessHeap(), 0, cs );
+        }
+        break;
+
+    case WM_MDICREATE:
+        {
+            MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
+            if (HIWORD(cs->szTitle))
+                HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
+            if (HIWORD(cs->szClass))
+                HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
+            HeapFree( GetProcessHeap(), 0, cs );
+        }
+        break;
+
+/* Listbox */
+    case LB_ADDSTRING:
+    case LB_INSERTSTRING:
+	if ( WINPROC_TestLBForStr( hwnd ))
+          HeapFree( GetProcessHeap(), 0, (void *)lParam );
+        break;
+
+    case LB_GETTEXT:
+        { if ( WINPROC_TestLBForStr( hwnd ))
+          { LPARAM *ptr = (LPARAM *)lParam - 1;
+            lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
+            HeapFree(GetProcessHeap(), 0, ptr );
+	  }
+        }
+        break;
+
+/* Combobox */
+    case CB_ADDSTRING:
+    case CB_INSERTSTRING:
+	if ( WINPROC_TestCBForStr( hwnd ))
+          HeapFree( GetProcessHeap(), 0, (void *)lParam );
+        break;
+
+    case CB_GETLBTEXT:
+        { if ( WINPROC_TestCBForStr( hwnd ))
+          { LPARAM *ptr = (LPARAM *)lParam - 1;
+            lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
+            HeapFree( GetProcessHeap(), 0, ptr );
+	  }
+        }
+        break;
+
+/* Multiline edit */
+    case EM_GETLINE:
+        { LPARAM * ptr = (LPARAM *)lParam - 1;  /* get the old lparam */
+	  WORD len = *(WORD *)ptr;
+          lstrcpynAtoW( (LPWSTR) *ptr, (LPSTR)lParam, len );
+          HeapFree( GetProcessHeap(), 0, ptr );
+        }
+        break;
+    }
+}
+
+/**********************************************************************
+ *	     WINPROC_CallProc32ATo32W
+ *
+ * Call a window procedure, translating args from Ansi to Unicode.
+ */
+static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
+                                         UINT msg, WPARAM wParam,
+                                         LPARAM lParam )
+{
+    LRESULT result;
+
+    if (WINPROC_MapMsg32ATo32W( hwnd, msg, wParam, &lParam ) == -1) return 0;
+    result = func( hwnd, msg, wParam, lParam );
+    WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
+    return result;
+}
+
+/**********************************************************************
+ *	     WINPROC_CallProc32WTo32A
+ *
+ * Call a window procedure, translating args from Unicode to Ansi.
+ */
+static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
+                                         UINT msg, WPARAM wParam,
+                                         LPARAM lParam )
+{
+    LRESULT result;
+
+    if (WINPROC_MapMsg32WTo32A( hwnd, msg, wParam, &lParam ) == -1) return 0;
+
+    result = func( hwnd, msg, wParam, lParam );
+    WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
+    return result;
+}
+/**********************************************************************
+ *	     CallWindowProc32A    
+ */
+LRESULT WIN32API CallWindowProcA(
+    WNDPROC func, /* window procedure */
+    HWND hwnd, /* target window */
+    UINT msg,  /* message */
+    WPARAM wParam, /* message dependent parameter */
+    LPARAM lParam    /* message dependent parameter */
+) 
+{
+
+    Win32BaseWindow *window = Win32BaseWindow::GetWindowFromHandle(hwnd);
+    if(!window) {
+        dprintf(("CallWindowProcA, window %x not found", hwnd));
+        // return func( hwnd, msg, wParam, lParam );
+        return 0;
+    }
+   
+    dprintf(("CallWindowProcA(wndproc=%p,hwnd=%08x,msg=%08x,wp=%08x,lp=%08lx)",
+                   func, hwnd, msg, wParam, lParam ));
+
+#if testing
+    return func( hwnd, msg, wParam, lParam );
+#endif
+
+    if(window->IsUnicode())
+        return WINPROC_CallProc32ATo32W( func, hwnd, msg, wParam, lParam);
+    else
+        return func( hwnd, msg, wParam, lParam );
+}
+
+
+/**********************************************************************
+ *	     CallWindowProc32W    (USER32.19)
+ */
+LRESULT WIN32API CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
+                                  WPARAM wParam, LPARAM lParam )
+{
+    Win32BaseWindow *window = Win32BaseWindow::GetWindowFromHandle(hwnd);
+    if(!window) {
+        dprintf(("CallWindowProcW, window %x not found", hwnd));
+        // return func( hwnd, msg, wParam, lParam );
+        return 0;
+    }
+   
+    dprintf(("CallWindowProcW(wndproc=%p,hwnd=%08x,msg=%08x,wp=%08x,lp=%08lx)",
+             func, hwnd, msg, wParam, lParam ));
+
+#if testing
+    return func( hwnd, msg, wParam, lParam );
+#endif
+
+    if(window->IsUnicode())
+        return func( hwnd, msg, wParam, lParam );
+    else
+        return WINPROC_CallProc32WTo32A( func, hwnd, msg, wParam, lParam);
+}
