2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/port.h"
33 #include "wine/winbase16.h"
34 #include "wine/winuser16.h"
38 #include "user_private.h"
41 #include "wine/unicode.h"
42 #include "wine/debug.h"
44 WINE_DECLARE_DEBUG_CHANNEL(msg);
45 WINE_DECLARE_DEBUG_CHANNEL(relay);
46 WINE_DEFAULT_DEBUG_CHANNEL(win);
48 typedef struct tagWINDOWPROC
50 WNDPROC16 proc16; /* 16-bit window proc */
51 WNDPROC procA; /* ASCII window proc */
52 WNDPROC procW; /* Unicode window proc */
55 #define WINPROC_HANDLE (~0UL >> 16)
56 #define MAX_WINPROCS 8192
58 static WINDOWPROC winproc_array[MAX_WINPROCS];
59 static UINT winproc_used;
61 static CRITICAL_SECTION winproc_cs;
62 static CRITICAL_SECTION_DEBUG critsect_debug =
65 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
66 0, 0, { (DWORD_PTR)(__FILE__ ": winproc_cs") }
68 static CRITICAL_SECTION winproc_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
70 static inline void *get_buffer( void *static_buffer, size_t size, size_t need )
72 if (size >= need) return static_buffer;
73 return HeapAlloc( GetProcessHeap(), 0, need );
76 static inline void free_buffer( void *static_buffer, void *buffer )
78 if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
81 /* map a Unicode string to a 16-bit pointer */
82 inline static SEGPTR map_str_32W_to_16( LPCWSTR str )
87 if (!HIWORD(str)) return (SEGPTR)LOWORD(str);
88 len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
89 if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
90 WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
94 /* unmap a Unicode string that was converted to a 16-bit pointer */
95 inline static void unmap_str_32W_to_16( SEGPTR str )
97 if (!HIWORD(str)) return;
98 HeapFree( GetProcessHeap(), 0, MapSL(str) );
102 /* map a 16-bit pointer to a Unicode string */
103 inline static LPWSTR map_str_16_to_32W( SEGPTR str )
108 if (!HIWORD(str)) return (LPWSTR)(ULONG_PTR)LOWORD(str);
109 len = MultiByteToWideChar( CP_ACP, 0, MapSL(str), -1, NULL, 0 );
110 if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
111 MultiByteToWideChar( CP_ACP, 0, MapSL(str), -1, ret, len );
115 /* unmap a 16-bit pointer that was converted to a Unicode string */
116 inline static void unmap_str_16_to_32W( LPCWSTR str )
118 if (HIWORD(str)) HeapFree( GetProcessHeap(), 0, (void *)str );
121 /* find an existing winproc for a given 16-bit function and type */
122 /* FIXME: probably should do something more clever than a linear search */
123 static inline WINDOWPROC *find_winproc16( WNDPROC16 func )
127 for (i = 0; i < winproc_used; i++)
129 if (winproc_array[i].proc16 == func) return &winproc_array[i];
134 /* find an existing winproc for a given function and type */
135 /* FIXME: probably should do something more clever than a linear search */
136 static inline WINDOWPROC *find_winproc( WNDPROC funcA, WNDPROC funcW )
140 for (i = 0; i < winproc_used; i++)
142 if (funcA && winproc_array[i].procA != funcA) continue;
143 if (funcW && winproc_array[i].procW != funcW) continue;
144 return &winproc_array[i];
149 /* return the window proc for a given handle, or NULL for an invalid handle */
150 static inline WINDOWPROC *handle_to_proc( WNDPROC handle )
152 UINT index = LOWORD(handle);
153 if ((ULONG_PTR)handle >> 16 != WINPROC_HANDLE) return NULL;
154 if (index >= winproc_used) return NULL;
155 return &winproc_array[index];
158 /* create a handle for a given window proc */
159 static inline WNDPROC proc_to_handle( WINDOWPROC *proc )
161 return (WNDPROC)(ULONG_PTR)((proc - winproc_array) | (WINPROC_HANDLE << 16));
164 /* allocate and initialize a new winproc */
165 static inline WINDOWPROC *alloc_winproc( WNDPROC funcA, WNDPROC funcW )
169 /* check if the function is already a win proc */
170 if (funcA && (proc = handle_to_proc( funcA ))) return proc;
171 if (funcW && (proc = handle_to_proc( funcW ))) return proc;
172 if (!funcA && !funcW) return NULL;
174 EnterCriticalSection( &winproc_cs );
176 /* check if we already have a winproc for that function */
177 if (!(proc = find_winproc( funcA, funcW )))
179 if (winproc_used < MAX_WINPROCS)
181 proc = &winproc_array[winproc_used++];
184 TRACE( "allocated %p for %p/%p (%d/%d used)\n",
185 proc_to_handle(proc), funcA, funcW, winproc_used, MAX_WINPROCS );
187 else FIXME( "too many winprocs, cannot allocate one for %p/%p\n", funcA, funcW );
189 else TRACE( "reusing %p for %p/%p\n", proc_to_handle(proc), funcA, funcW );
191 LeaveCriticalSection( &winproc_cs );
198 #include "pshpack1.h"
200 /* Window procedure 16-to-32-bit thunk */
203 BYTE popl_eax; /* popl %eax (return address) */
204 BYTE pushl_func; /* pushl $proc */
206 BYTE pushl_eax; /* pushl %eax */
207 BYTE ljmp; /* ljmp relay*/
208 DWORD relay_offset; /* __wine_call_wndproc */
214 #define MAX_THUNKS (0x10000 / sizeof(WINPROC_THUNK))
216 static WINPROC_THUNK *thunk_array;
217 static UINT thunk_selector;
218 static UINT thunk_used;
220 /* return the window proc for a given handle, or NULL for an invalid handle */
221 static inline WINDOWPROC *handle16_to_proc( WNDPROC16 handle )
223 if (HIWORD(handle) == thunk_selector)
225 UINT index = LOWORD(handle) / sizeof(WINPROC_THUNK);
226 /* check alignment */
227 if (index * sizeof(WINPROC_THUNK) != LOWORD(handle)) return NULL;
228 /* check array limits */
229 if (index >= thunk_used) return NULL;
230 return thunk_array[index].proc;
232 return handle_to_proc( (WNDPROC)handle );
235 /* allocate a 16-bit thunk for an existing window proc */
236 static WNDPROC16 alloc_win16_thunk( WINDOWPROC *proc )
238 static FARPROC16 relay;
241 if (proc->proc16) return proc->proc16;
243 EnterCriticalSection( &winproc_cs );
245 if (!thunk_array) /* allocate the array and its selector */
249 if (!(thunk_selector = wine_ldt_alloc_entries(1))) goto done;
250 if (!(thunk_array = VirtualAlloc( NULL, MAX_THUNKS * sizeof(WINPROC_THUNK), MEM_COMMIT,
251 PAGE_EXECUTE_READWRITE ))) goto done;
252 wine_ldt_set_base( &entry, thunk_array );
253 wine_ldt_set_limit( &entry, MAX_THUNKS * sizeof(WINPROC_THUNK) - 1 );
254 wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT );
255 wine_ldt_set_entry( thunk_selector, &entry );
256 relay = GetProcAddress16( GetModuleHandle16("user"), "__wine_call_wndproc" );
259 /* check if it already exists */
260 for (i = 0; i < thunk_used; i++) if (thunk_array[i].proc == proc) break;
262 if (i == thunk_used) /* create a new one */
264 WINPROC_THUNK *thunk;
266 if (thunk_used >= MAX_THUNKS) goto done;
267 thunk = &thunk_array[thunk_used++];
268 thunk->popl_eax = 0x58; /* popl %eax */
269 thunk->pushl_func = 0x68; /* pushl $proc */
271 thunk->pushl_eax = 0x50; /* pushl %eax */
272 thunk->ljmp = 0xea; /* ljmp relay*/
273 thunk->relay_offset = OFFSETOF(relay);
274 thunk->relay_sel = SELECTOROF(relay);
276 proc->proc16 = (WNDPROC16)MAKESEGPTR( thunk_selector, i * sizeof(WINPROC_THUNK) );
278 LeaveCriticalSection( &winproc_cs );
284 static inline WINDOWPROC *handle16_to_proc( WNDPROC16 handle )
286 return handle_to_proc( (WNDPROC)handle );
289 static inline WNDPROC16 alloc_win16_thunk( WINDOWPROC *proc )
294 #endif /* __i386__ */
298 /* Some window procedures modify register they shouldn't, or are not
299 * properly declared stdcall; so we need a small assembly wrapper to
301 extern LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
302 WPARAM wParam, LPARAM lParam );
303 __ASM_GLOBAL_FUNC( WINPROC_wrapper,
314 "movl 8(%ebp),%eax\n\t"
316 "leal -12(%ebp),%esp\n\t"
323 static inline LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
324 WPARAM wParam, LPARAM lParam )
326 return proc( hwnd, msg, wParam, lParam );
328 #endif /* __i386__ */
331 static void MINMAXINFO32to16( const MINMAXINFO *from, MINMAXINFO16 *to )
333 to->ptReserved.x = from->ptReserved.x;
334 to->ptReserved.y = from->ptReserved.y;
335 to->ptMaxSize.x = from->ptMaxSize.x;
336 to->ptMaxSize.y = from->ptMaxSize.y;
337 to->ptMaxPosition.x = from->ptMaxPosition.x;
338 to->ptMaxPosition.y = from->ptMaxPosition.y;
339 to->ptMinTrackSize.x = from->ptMinTrackSize.x;
340 to->ptMinTrackSize.y = from->ptMinTrackSize.y;
341 to->ptMaxTrackSize.x = from->ptMaxTrackSize.x;
342 to->ptMaxTrackSize.y = from->ptMaxTrackSize.y;
345 static void MINMAXINFO16to32( const MINMAXINFO16 *from, MINMAXINFO *to )
347 to->ptReserved.x = from->ptReserved.x;
348 to->ptReserved.y = from->ptReserved.y;
349 to->ptMaxSize.x = from->ptMaxSize.x;
350 to->ptMaxSize.y = from->ptMaxSize.y;
351 to->ptMaxPosition.x = from->ptMaxPosition.x;
352 to->ptMaxPosition.y = from->ptMaxPosition.y;
353 to->ptMinTrackSize.x = from->ptMinTrackSize.x;
354 to->ptMinTrackSize.y = from->ptMinTrackSize.y;
355 to->ptMaxTrackSize.x = from->ptMaxTrackSize.x;
356 to->ptMaxTrackSize.y = from->ptMaxTrackSize.y;
359 static void WINDOWPOS32to16( const WINDOWPOS* from, WINDOWPOS16* to )
361 to->hwnd = HWND_16(from->hwnd);
362 to->hwndInsertAfter = HWND_16(from->hwndInsertAfter);
367 to->flags = from->flags;
370 static void WINDOWPOS16to32( const WINDOWPOS16* from, WINDOWPOS* to )
372 to->hwnd = WIN_Handle32(from->hwnd);
373 to->hwndInsertAfter = (from->hwndInsertAfter == (HWND16)-1) ?
374 HWND_TOPMOST : WIN_Handle32(from->hwndInsertAfter);
379 to->flags = from->flags;
382 /* The strings are not copied */
383 static void CREATESTRUCT32Ato16( const CREATESTRUCTA* from, CREATESTRUCT16* to )
385 to->lpCreateParams = (SEGPTR)from->lpCreateParams;
386 to->hInstance = HINSTANCE_16(from->hInstance);
387 to->hMenu = HMENU_16(from->hMenu);
388 to->hwndParent = HWND_16(from->hwndParent);
393 to->style = from->style;
394 to->dwExStyle = from->dwExStyle;
397 static void CREATESTRUCT16to32A( const CREATESTRUCT16* from, CREATESTRUCTA *to )
400 to->lpCreateParams = (LPVOID)from->lpCreateParams;
401 to->hInstance = HINSTANCE_32(from->hInstance);
402 to->hMenu = HMENU_32(from->hMenu);
403 to->hwndParent = WIN_Handle32(from->hwndParent);
408 to->style = from->style;
409 to->dwExStyle = from->dwExStyle;
412 /* The strings are not copied */
413 static void MDICREATESTRUCT32Ato16( const MDICREATESTRUCTA* from, MDICREATESTRUCT16* to )
415 to->hOwner = HINSTANCE_16(from->hOwner);
420 to->style = from->style;
421 to->lParam = from->lParam;
424 static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16* from, MDICREATESTRUCTA *to )
426 to->hOwner = HINSTANCE_32(from->hOwner);
431 to->style = from->style;
432 to->lParam = from->lParam;
435 static WPARAM map_wparam_char_AtoW( WPARAM wParam, DWORD len )
440 ch[0] = (wParam >> 8);
441 ch[1] = wParam & 0xff;
442 if (len > 1 && ch[0])
443 RtlMultiByteToUnicodeN( &wch, sizeof(wch), NULL, ch, 2 );
445 RtlMultiByteToUnicodeN( &wch, sizeof(wch), NULL, ch + 1, 1 );
446 return MAKEWPARAM( wch, HIWORD(wParam) );
449 static WPARAM map_wparam_char_WtoA( WPARAM wParam, DWORD len )
454 RtlUnicodeToMultiByteN( (LPSTR)ch, len, &len, &wch, sizeof(wch) );
456 return MAKEWPARAM( (ch[0] << 8) | ch[1], HIWORD(wParam) );
458 return MAKEWPARAM( ch[0], HIWORD(wParam) );
461 /* call a 32-bit window procedure */
462 static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result, void *arg )
468 hwnd = WIN_GetFullHandle( hwnd );
470 DPRINTF( "%04lx:Call window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
471 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wp, lp );
473 *result = WINPROC_wrapper( proc, hwnd, msg, wp, lp );
476 DPRINTF( "%04lx:Ret window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
477 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wp, lp, *result );
481 /* call a 32-bit dialog procedure */
482 static LRESULT call_dialog_proc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result, void *arg )
489 hwnd = WIN_GetFullHandle( hwnd );
491 DPRINTF( "%04lx:Call dialog proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
492 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wp, lp );
494 ret = WINPROC_wrapper( proc, hwnd, msg, wp, lp );
495 *result = GetWindowLongPtrW( hwnd, DWLP_MSGRESULT );
498 DPRINTF( "%04lx:Ret dialog proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx result=%08lx\n",
499 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wp, lp, ret, *result );
503 /**********************************************************************
504 * WINPROC_CallWndProc32
506 * Call a 32-bit WndProc.
508 static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
509 WPARAM wParam, LPARAM lParam )
515 hwnd = WIN_GetFullHandle( hwnd );
517 DPRINTF( "%04lx:Call window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
518 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam );
520 retvalue = WINPROC_wrapper( proc, hwnd, msg, wParam, lParam );
523 DPRINTF( "%04lx:Ret window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
524 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam, retvalue );
528 /* call a 16-bit window procedure */
529 static LRESULT call_window_proc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam,
530 LRESULT *result, void *arg )
532 WNDPROC16 proc = arg;
541 DRAWITEMSTRUCT16 dis16;
542 COMPAREITEMSTRUCT16 cis16;
548 /* Window procedures want ax = hInstance, ds = es = ss */
550 memset(&context, 0, sizeof(context));
551 context.SegDs = context.SegEs = SELECTOROF(NtCurrentTeb()->WOW32Reserved);
552 context.SegFs = wine_get_fs();
553 context.SegGs = wine_get_gs();
554 if (!(context.Eax = GetWindowWord( HWND_32(hwnd), GWLP_HINSTANCE ))) context.Eax = context.SegDs;
555 context.SegCs = SELECTOROF(proc);
556 context.Eip = OFFSETOF(proc);
557 context.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + (WORD)&((STACK16FRAME*)0)->bp;
561 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
562 work if structures passed in lParam are placed in the stack/data
563 segment. Programmers easily make the mistake of converting lParam
564 to a near rather than a far pointer, since Windows apparently
565 allows this. We copy the structures to the 16 bit stack; this is
566 ugly but makes these programs work. */
571 size = sizeof(CREATESTRUCT16); break;
573 size = sizeof(DRAWITEMSTRUCT16); break;
575 size = sizeof(COMPAREITEMSTRUCT16); break;
579 memcpy( &args.u, MapSL(lParam), size );
580 lParam = (SEGPTR)NtCurrentTeb()->WOW32Reserved - size;
584 args.params[4] = hwnd;
585 args.params[3] = msg;
586 args.params[2] = wParam;
587 args.params[1] = HIWORD(lParam);
588 args.params[0] = LOWORD(lParam);
589 WOWCallback16Ex( 0, WCB16_REGS, sizeof(args.params) + size, &args, (DWORD *)&context );
590 *result = MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) );
594 /* call a 16-bit dialog procedure */
595 static LRESULT call_dialog_proc16( HWND16 hwnd, UINT16 msg, WPARAM16 wp, LPARAM lp,
596 LRESULT *result, void *arg )
598 LRESULT ret = call_window_proc16( hwnd, msg, wp, lp, result, arg );
599 *result = GetWindowLongPtrW( WIN_Handle32(hwnd), DWLP_MSGRESULT );
604 /**********************************************************************
607 * Get a window procedure pointer that can be passed to the Windows program.
609 WNDPROC16 WINPROC_GetProc16( WNDPROC proc, BOOL unicode )
613 if (unicode) ptr = alloc_winproc( NULL, proc );
614 else ptr = alloc_winproc( proc, NULL );
617 return alloc_win16_thunk( ptr );
621 /**********************************************************************
624 * Get a window procedure pointer that can be passed to the Windows program.
626 WNDPROC WINPROC_GetProc( WNDPROC proc, BOOL unicode )
628 WINDOWPROC *ptr = handle_to_proc( proc );
630 if (!ptr) return proc;
633 if (ptr->procW) return ptr->procW;
638 if (ptr->procA) return ptr->procA;
644 /**********************************************************************
645 * WINPROC_AllocProc16
647 * Allocate a window procedure for a window or class.
649 * Note that allocated winprocs are never freed; the idea is that even if an app creates a
650 * lot of windows, it will usually only have a limited number of window procedures, so the
651 * array won't grow too large, and this way we avoid the need to track allocations per window.
653 WNDPROC WINPROC_AllocProc16( WNDPROC16 func )
657 if (!func) return NULL;
659 /* check if the function is already a win proc */
660 if (!(proc = handle16_to_proc( func )))
662 EnterCriticalSection( &winproc_cs );
664 /* then check if we already have a winproc for that function */
665 if (!(proc = find_winproc16( func )))
667 if (winproc_used < MAX_WINPROCS)
669 proc = &winproc_array[winproc_used++];
671 TRACE( "allocated %p for %p/16-bit (%d/%d used)\n",
672 proc_to_handle(proc), func, winproc_used, MAX_WINPROCS );
674 else FIXME( "too many winprocs, cannot allocate one for 16-bit %p\n", func );
676 else TRACE( "reusing %p for %p/16-bit\n", proc_to_handle(proc), func );
678 LeaveCriticalSection( &winproc_cs );
680 return proc_to_handle( proc );
684 /**********************************************************************
687 * Allocate a window procedure for a window or class.
689 * Note that allocated winprocs are never freed; the idea is that even if an app creates a
690 * lot of windows, it will usually only have a limited number of window procedures, so the
691 * array won't grow too large, and this way we avoid the need to track allocations per window.
693 WNDPROC WINPROC_AllocProc( WNDPROC funcA, WNDPROC funcW )
697 if (!(proc = alloc_winproc( funcA, funcW ))) return NULL;
698 return proc_to_handle( proc );
702 /**********************************************************************
705 * Return the window procedure type, or the default value if not a winproc handle.
707 BOOL WINPROC_IsUnicode( WNDPROC proc, BOOL def_val )
709 WINDOWPROC *ptr = handle_to_proc( proc );
711 if (!ptr) return def_val;
712 if (ptr->procA && ptr->procW) return def_val; /* can be both */
713 return (ptr->procW != NULL);
717 /**********************************************************************
718 * WINPROC_TestLBForStr
720 * Return TRUE if the lparam is a string
722 inline static BOOL WINPROC_TestLBForStr( HWND hwnd, UINT msg )
724 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
725 if (msg <= CB_MSGMAX)
726 return (!(style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) || (style & CBS_HASSTRINGS));
728 return (!(style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) || (style & LBS_HASSTRINGS));
731 /**********************************************************************
732 * WINPROC_MapMsg32ATo32W
734 * Map a message from Ansi to Unicode.
735 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
738 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
739 * the first four bytes are the handle of the icon
740 * when the WM_SETTEXT message has been used to set the icon
742 static INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
747 case WM_ASKCBFORMATNAME:
749 LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0,
750 *pwparam * sizeof(WCHAR) + sizeof(LPARAM) );
752 *ptr++ = *plparam; /* Store previous lParam */
753 *plparam = (LPARAM)ptr;
756 /* lparam is string (0-terminated) */
758 case WM_WININICHANGE:
759 case WM_DEVMODECHANGE:
764 if (!*plparam) return 0;
767 DWORD len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)*plparam, -1, NULL, 0);
768 WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
769 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)*plparam, -1, buf, len);
770 *plparam = (LPARAM)buf;
771 return (*plparam ? 1 : -1);
773 case WM_GETTEXTLENGTH:
774 case CB_GETLBTEXTLEN:
776 return 1; /* need to map result */
780 { WORD len = (WORD)*plparam;
781 LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
783 *ptr++ = *plparam; /* Store previous lParam */
784 *((WORD *) ptr) = len; /* Store the length */
785 *plparam = (LPARAM)ptr;
795 case EM_SETPASSWORDCHAR:
796 *pwparam = map_wparam_char_AtoW( *pwparam, 1 );
800 *pwparam = map_wparam_char_AtoW( *pwparam, 2 );
803 case WM_PAINTCLIPBOARD:
804 case WM_SIZECLIPBOARD:
805 FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg, hwnd), msg );
807 default: /* No translation needed */
813 /**********************************************************************
814 * WINPROC_UnmapMsg32ATo32W
816 * Unmap a message that was mapped from Ansi to Unicode.
818 static LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
819 LRESULT result, WNDPROC dispatch )
824 case WM_ASKCBFORMATNAME:
826 LPARAM *ptr = (LPARAM *)lParam - 1;
827 if (!wParam) result = 0;
828 else if (!(result = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
829 (LPSTR)*ptr, wParam, NULL, NULL )))
831 ((LPSTR)*ptr)[wParam-1] = 0;
834 else result--; /* do not count terminating null */
835 HeapFree( GetProcessHeap(), 0, ptr );
838 case WM_GETTEXTLENGTH:
839 case CB_GETLBTEXTLEN:
843 /* Determine respective GETTEXT message */
845 (msg == WM_GETTEXTLENGTH) ? WM_GETTEXT :
846 ((msg == CB_GETLBTEXTLEN) ? CB_GETLBTEXT : LB_GETTEXT);
847 /* wParam differs between the messages */
848 WPARAM wp = (msg == WM_GETTEXTLENGTH) ? (WPARAM)(result + 1) : wParam;
850 WCHAR* p = HeapAlloc (GetProcessHeap(), 0, (result + 1) * sizeof(WCHAR));
857 n = WINPROC_CallWndProc(dispatch, hwnd, msgGetText, wp, (LPARAM)p);
859 n = SendMessageW (hwnd, msgGetText, wp, (LPARAM)p);
861 result = WideCharToMultiByte( CP_ACP, 0, p, n, NULL, 0, 0, NULL );
862 HeapFree (GetProcessHeap(), 0, p);
868 case WM_WININICHANGE:
869 case WM_DEVMODECHANGE:
874 HeapFree( GetProcessHeap(), 0, (void *)lParam );
880 LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
881 WORD len = *(WORD *) lParam;
882 result = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, result,
883 (LPSTR)*ptr, len, NULL, NULL );
884 if (result < len) ((LPSTR)*ptr)[result] = 0;
885 HeapFree( GetProcessHeap(), 0, ptr );
893 static UINT convert_handle_16_to_32(HANDLE16 src, unsigned int flags)
896 UINT sz = GlobalSize16(src);
899 if (!(dst = GlobalAlloc(flags, sz)))
901 ptr16 = GlobalLock16(src);
902 ptr32 = GlobalLock(dst);
903 if (ptr16 != NULL && ptr32 != NULL) memcpy(ptr32, ptr16, sz);
910 /**********************************************************************
911 * WINPROC_MapMsg16To32A
913 * Map a message from 16- to 32-bit Ansi.
914 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
916 INT WINPROC_MapMsg16To32A( HWND hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
917 WPARAM *pwparam32, LPARAM *plparam )
919 *pmsg32 = (UINT)msg16;
920 *pwparam32 = (WPARAM)wParam16;
927 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
928 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
932 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
933 *plparam = (LPARAM)WIN_Handle32( HIWORD(*plparam) );
936 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
937 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
938 *pwparam32 = (WPARAM)HDC_32(wParam16);
939 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
943 COMPAREITEMSTRUCT16* cis16 = MapSL(*plparam);
944 COMPAREITEMSTRUCT *cis = HeapAlloc(GetProcessHeap(), 0, sizeof(*cis));
946 cis->CtlType = cis16->CtlType;
947 cis->CtlID = cis16->CtlID;
948 cis->hwndItem = WIN_Handle32( cis16->hwndItem );
949 cis->itemID1 = cis16->itemID1;
950 cis->itemData1 = cis16->itemData1;
951 cis->itemID2 = cis16->itemID2;
952 cis->itemData2 = cis16->itemData2;
953 cis->dwLocaleId = 0; /* FIXME */
954 *plparam = (LPARAM)cis;
959 PCOPYDATASTRUCT16 pcds16 = MapSL(*plparam);
960 PCOPYDATASTRUCT pcds = HeapAlloc ( GetProcessHeap(), 0, sizeof(*pcds));
961 pcds->dwData = pcds16->dwData;
962 pcds->cbData = pcds16->cbData;
963 pcds->lpData = MapSL( pcds16->lpData);
964 *plparam = (LPARAM)pcds;
969 DELETEITEMSTRUCT16* dis16 = MapSL(*plparam);
970 DELETEITEMSTRUCT *dis = HeapAlloc(GetProcessHeap(), 0, sizeof(*dis));
972 dis->CtlType = dis16->CtlType;
973 dis->CtlID = dis16->CtlID;
974 dis->hwndItem = WIN_Handle32( dis16->hwndItem );
975 dis->itemData = dis16->itemData;
976 *plparam = (LPARAM)dis;
981 MEASUREITEMSTRUCT16* mis16 = MapSL(*plparam);
982 MEASUREITEMSTRUCT *mis = HeapAlloc(GetProcessHeap(), 0,
983 sizeof(*mis) + sizeof(LPARAM));
985 mis->CtlType = mis16->CtlType;
986 mis->CtlID = mis16->CtlID;
987 mis->itemID = mis16->itemID;
988 mis->itemWidth = mis16->itemWidth;
989 mis->itemHeight = mis16->itemHeight;
990 mis->itemData = mis16->itemData;
991 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
992 *plparam = (LPARAM)mis;
997 DRAWITEMSTRUCT16* dis16 = MapSL(*plparam);
998 DRAWITEMSTRUCT *dis = HeapAlloc(GetProcessHeap(), 0, sizeof(*dis));
1000 dis->CtlType = dis16->CtlType;
1001 dis->CtlID = dis16->CtlID;
1002 dis->itemID = dis16->itemID;
1003 dis->itemAction = dis16->itemAction;
1004 dis->itemState = dis16->itemState;
1005 dis->hwndItem = (dis->CtlType == ODT_MENU) ? (HWND)HMENU_32(dis16->hwndItem)
1006 : WIN_Handle32( dis16->hwndItem );
1007 dis->hDC = HDC_32(dis16->hDC);
1008 dis->itemData = dis16->itemData;
1009 dis->rcItem.left = dis16->rcItem.left;
1010 dis->rcItem.top = dis16->rcItem.top;
1011 dis->rcItem.right = dis16->rcItem.right;
1012 dis->rcItem.bottom = dis16->rcItem.bottom;
1013 *plparam = (LPARAM)dis;
1016 case WM_GETMINMAXINFO:
1018 MINMAXINFO *mmi = HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi) + sizeof(LPARAM));
1019 if (!mmi) return -1;
1020 MINMAXINFO16to32( MapSL(*plparam), mmi );
1021 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1022 *plparam = (LPARAM)mmi;
1027 case WM_WININICHANGE:
1028 case WM_DEVMODECHANGE:
1029 case WM_ASKCBFORMATNAME:
1030 *plparam = (LPARAM)MapSL(*plparam);
1034 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1035 MDICREATESTRUCTA *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1037 MDICREATESTRUCT16to32A( cs16, cs );
1038 cs->szTitle = MapSL(cs16->szTitle);
1039 cs->szClass = MapSL(cs16->szClass);
1040 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1041 *plparam = (LPARAM)cs;
1044 case WM_MDIGETACTIVE:
1045 *plparam = (LPARAM)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL) );
1046 *(BOOL*)(*plparam) = 0;
1049 if(wParam16) *pmsg32=WM_MDIREFRESHMENU;
1050 *pwparam32 = (WPARAM)HMENU_32(LOWORD(*plparam));
1051 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1054 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1055 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1058 if((LOWORD(*plparam) & MF_POPUP) && (LOWORD(*plparam) != 0xFFFF))
1060 HMENU hmenu=HMENU_32(HIWORD(*plparam));
1061 UINT Pos=MENU_FindSubMenu( &hmenu, HMENU_32(wParam16));
1062 if(Pos==0xFFFF) Pos=0; /* NO_SELECTED_ITEM */
1063 *pwparam32 = MAKEWPARAM( Pos, LOWORD(*plparam) );
1065 else *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1066 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1068 case WM_MDIACTIVATE:
1071 *pwparam32 = (WPARAM)WIN_Handle32( HIWORD(*plparam) );
1072 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1074 else /* message sent to MDI client */
1075 *pwparam32 = wParam16;
1079 NCCALCSIZE_PARAMS16 *nc16;
1080 NCCALCSIZE_PARAMS *nc;
1082 nc = HeapAlloc( GetProcessHeap(), 0, sizeof(*nc) + sizeof(LPARAM) );
1084 nc16 = MapSL(*plparam);
1085 nc->rgrc[0].left = nc16->rgrc[0].left;
1086 nc->rgrc[0].top = nc16->rgrc[0].top;
1087 nc->rgrc[0].right = nc16->rgrc[0].right;
1088 nc->rgrc[0].bottom = nc16->rgrc[0].bottom;
1091 nc->lppos = HeapAlloc( GetProcessHeap(), 0, sizeof(*nc->lppos) );
1092 nc->rgrc[1].left = nc16->rgrc[1].left;
1093 nc->rgrc[1].top = nc16->rgrc[1].top;
1094 nc->rgrc[1].right = nc16->rgrc[1].right;
1095 nc->rgrc[1].bottom = nc16->rgrc[1].bottom;
1096 nc->rgrc[2].left = nc16->rgrc[2].left;
1097 nc->rgrc[2].top = nc16->rgrc[2].top;
1098 nc->rgrc[2].right = nc16->rgrc[2].right;
1099 nc->rgrc[2].bottom = nc16->rgrc[2].bottom;
1100 if (nc->lppos) WINDOWPOS16to32( MapSL(nc16->lppos), nc->lppos );
1102 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1103 *plparam = (LPARAM)nc;
1109 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1110 CREATESTRUCTA *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1112 CREATESTRUCT16to32A( cs16, cs );
1113 cs->lpszName = MapSL(cs16->lpszName);
1114 cs->lpszClass = MapSL(cs16->lpszClass);
1116 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1118 MDICREATESTRUCT16 *mdi_cs16;
1119 MDICREATESTRUCTA *mdi_cs = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs));
1122 HeapFree(GetProcessHeap(), 0, cs);
1125 mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs16->lpCreateParams);
1126 MDICREATESTRUCT16to32A(mdi_cs16, mdi_cs);
1127 mdi_cs->szTitle = MapSL(mdi_cs16->szTitle);
1128 mdi_cs->szClass = MapSL(mdi_cs16->szClass);
1130 cs->lpCreateParams = mdi_cs;
1132 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1133 *plparam = (LPARAM)cs;
1136 case WM_PARENTNOTIFY:
1137 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1139 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1140 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1143 case WM_WINDOWPOSCHANGING:
1144 case WM_WINDOWPOSCHANGED:
1146 WINDOWPOS *wp = HeapAlloc( GetProcessHeap(), 0, sizeof(*wp) + sizeof(LPARAM) );
1148 WINDOWPOS16to32( MapSL(*plparam), wp );
1149 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1150 *plparam = (LPARAM)wp;
1156 LPMSG16 msg16 = MapSL(*plparam);
1157 LPMSG msg32 = HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1159 if (!msg32) return -1;
1160 msg32->hwnd = WIN_Handle32( msg16->hwnd );
1161 msg32->message = msg16->message;
1162 msg32->wParam = msg16->wParam;
1163 msg32->lParam = msg16->lParam;
1164 msg32->time = msg16->time;
1165 msg32->pt.x = msg16->pt.x;
1166 msg32->pt.y = msg16->pt.y;
1167 *plparam = (LPARAM)msg32;
1172 *plparam = (LPARAM)MapSL(*plparam);
1174 case WM_ACTIVATEAPP:
1175 /* We need this when SetActiveWindow sends a Sendmessage16() to
1176 * a 32bit window. Might be superflous with 32bit interprocess
1177 * message queues. */
1178 if (*plparam) *plparam = HTASK_32( *plparam );
1182 MDINEXTMENU *next = HeapAlloc( GetProcessHeap(), 0, sizeof(*next) );
1183 if (!next) return -1;
1184 next->hmenuIn = (HMENU)*plparam;
1185 next->hmenuNext = 0;
1187 *plparam = (LPARAM)next;
1190 case WM_PAINTCLIPBOARD:
1191 case WM_SIZECLIPBOARD:
1192 FIXME_(msg)("message %04x needs translation\n",msg16 );
1194 case WM_DDE_INITIATE:
1195 case WM_DDE_TERMINATE:
1196 case WM_DDE_UNADVISE:
1197 case WM_DDE_REQUEST:
1198 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1208 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1209 lo16 = LOWORD(*plparam);
1210 hi = HIWORD(*plparam);
1211 if (lo16 && !(lo32 = convert_handle_16_to_32(lo16, GMEM_DDESHARE)))
1213 *plparam = PackDDElParam(msg16, lo32, hi);
1215 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1222 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1224 lo = LOWORD(*plparam);
1225 hi = HIWORD(*plparam);
1227 if (GlobalGetAtomNameA(hi, buf, 2) > 0) flag |= 1;
1228 if (GlobalSize16(hi) != 0) flag |= 2;
1234 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1239 break; /* atom, nothing to do */
1241 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi);
1244 hi = convert_handle_16_to_32(hi, GMEM_DDESHARE);
1247 *plparam = PackDDElParam(WM_DDE_ACK, lo, hi);
1249 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1250 case WM_DDE_EXECUTE:
1251 *plparam = convert_handle_16_to_32(*plparam, GMEM_DDESHARE);
1252 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1253 default: /* No translation needed */
1259 /**********************************************************************
1260 * WINPROC_UnmapMsg16To32A
1262 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1264 static LRESULT WINPROC_UnmapMsg16To32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1269 case WM_COMPAREITEM:
1273 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
1275 case WM_MEASUREITEM:
1277 MEASUREITEMSTRUCT16 *mis16;
1278 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1279 lParam = *(LPARAM *)(mis + 1);
1280 mis16 = MapSL(lParam);
1281 mis16->itemWidth = (UINT16)mis->itemWidth;
1282 mis16->itemHeight = (UINT16)mis->itemHeight;
1283 HeapFree( GetProcessHeap(), 0, mis );
1286 case WM_GETMINMAXINFO:
1288 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1289 lParam = *(LPARAM *)(mmi + 1);
1290 MINMAXINFO32to16( mmi, MapSL(lParam));
1291 HeapFree( GetProcessHeap(), 0, mmi );
1296 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1297 lParam = *(LPARAM *)(cs + 1);
1298 MDICREATESTRUCT32Ato16( cs, MapSL(lParam) );
1299 HeapFree( GetProcessHeap(), 0, cs );
1302 case WM_MDIGETACTIVE:
1303 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1304 HeapFree( GetProcessHeap(), 0, (BOOL *)lParam );
1308 NCCALCSIZE_PARAMS16 *nc16;
1309 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1310 lParam = *(LPARAM *)(nc + 1);
1311 nc16 = MapSL(lParam);
1312 nc16->rgrc[0].left = nc->rgrc[0].left;
1313 nc16->rgrc[0].top = nc->rgrc[0].top;
1314 nc16->rgrc[0].right = nc->rgrc[0].right;
1315 nc16->rgrc[0].bottom = nc->rgrc[0].bottom;
1318 nc16->rgrc[1].left = nc->rgrc[1].left;
1319 nc16->rgrc[1].top = nc->rgrc[1].top;
1320 nc16->rgrc[1].right = nc->rgrc[1].right;
1321 nc16->rgrc[1].bottom = nc->rgrc[1].bottom;
1322 nc16->rgrc[2].left = nc->rgrc[2].left;
1323 nc16->rgrc[2].top = nc->rgrc[2].top;
1324 nc16->rgrc[2].right = nc->rgrc[2].right;
1325 nc16->rgrc[2].bottom = nc->rgrc[2].bottom;
1328 WINDOWPOS32to16( nc->lppos, MapSL(nc16->lppos));
1329 HeapFree( GetProcessHeap(), 0, nc->lppos );
1332 HeapFree( GetProcessHeap(), 0, nc );
1338 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1339 lParam = *(LPARAM *)(cs + 1);
1340 CREATESTRUCT32Ato16( cs, MapSL(lParam) );
1342 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1343 HeapFree(GetProcessHeap(), 0, cs->lpCreateParams);
1345 HeapFree( GetProcessHeap(), 0, cs );
1348 case WM_WINDOWPOSCHANGING:
1349 case WM_WINDOWPOSCHANGED:
1351 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1352 lParam = *(LPARAM *)(wp + 1);
1353 WINDOWPOS32to16(wp, MapSL(lParam));
1354 HeapFree( GetProcessHeap(), 0, wp );
1360 LPMSG msg32 = (LPMSG)lParam;
1361 HeapFree( GetProcessHeap(), 0, msg32 );
1366 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
1367 result = MAKELONG( HMENU_16(next->hmenuNext), HWND_16(next->hwndNext) );
1368 HeapFree( GetProcessHeap(), 0, next );
1376 /**********************************************************************
1377 * WINPROC_MapMsg16To32W
1379 * Map a message from 16- to 32-bit Unicode.
1380 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1382 static INT WINPROC_MapMsg16To32W( HWND hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1383 WPARAM *pwparam32, LPARAM *plparam )
1385 *pmsg32=(UINT)msg16;
1386 *pwparam32 = (WPARAM)wParam16;
1391 case WM_WININICHANGE:
1392 case WM_DEVMODECHANGE:
1393 case WM_ASKCBFORMATNAME:
1394 *plparam = (LPARAM)MapSL(*plparam);
1395 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, pwparam32, plparam );
1396 case WM_GETTEXTLENGTH:
1397 case CB_GETLBTEXTLEN:
1399 return 1; /* need to map result */
1403 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1404 CREATESTRUCTW *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1406 CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1407 cs->lpszName = map_str_16_to_32W(cs16->lpszName);
1408 cs->lpszClass = map_str_16_to_32W(cs16->lpszClass);
1410 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1412 MDICREATESTRUCT16 *mdi_cs16;
1413 MDICREATESTRUCTW *mdi_cs = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs));
1416 HeapFree(GetProcessHeap(), 0, cs);
1419 mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs16->lpCreateParams);
1420 MDICREATESTRUCT16to32A(mdi_cs16, (MDICREATESTRUCTA *)mdi_cs);
1421 mdi_cs->szTitle = map_str_16_to_32W(mdi_cs16->szTitle);
1422 mdi_cs->szClass = map_str_16_to_32W(mdi_cs16->szClass);
1424 cs->lpCreateParams = mdi_cs;
1426 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1427 *plparam = (LPARAM)cs;
1432 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1433 MDICREATESTRUCTW *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1435 MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1436 cs->szTitle = map_str_16_to_32W(cs16->szTitle);
1437 cs->szClass = map_str_16_to_32W(cs16->szClass);
1438 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1439 *plparam = (LPARAM)cs;
1445 LPMSG16 msg16 = MapSL(*plparam);
1446 LPMSG msg32 = HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1448 if (!msg32) return -1;
1449 msg32->hwnd = WIN_Handle32( msg16->hwnd );
1450 msg32->message = msg16->message;
1451 msg32->wParam = msg16->wParam;
1452 msg32->lParam = msg16->lParam;
1453 msg32->time = msg16->time;
1454 msg32->pt.x = msg16->pt.x;
1455 msg32->pt.y = msg16->pt.y;
1456 switch(msg32->message)
1461 case WM_SYSDEADCHAR:
1462 msg32->wParam = map_wparam_char_AtoW( msg16->wParam, 1 );
1465 *plparam = (LPARAM)msg32;
1471 *pwparam32 = MAKEWPARAM( map_wparam_char_AtoW( wParam16, 1 ), HIWORD(*plparam) );
1472 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1475 *pwparam32 = MAKEWPARAM( map_wparam_char_AtoW( wParam16, 1 ), LOWORD(*plparam) );
1476 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1481 case WM_SYSDEADCHAR:
1482 *pwparam32 = map_wparam_char_AtoW( wParam16, 1 );
1485 *pwparam32 = map_wparam_char_AtoW( wParam16, 2 );
1488 default: /* No Unicode translation needed */
1489 return WINPROC_MapMsg16To32A( hwnd, msg16, wParam16, pmsg32,
1490 pwparam32, plparam );
1495 /**********************************************************************
1496 * WINPROC_UnmapMsg16To32W
1498 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1500 static LRESULT WINPROC_UnmapMsg16To32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1501 LRESULT result, WNDPROC dispatch )
1507 case WM_GETTEXTLENGTH:
1508 case CB_GETLBTEXTLEN:
1510 case WM_ASKCBFORMATNAME:
1511 return WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result, dispatch );
1515 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1516 lParam = *(LPARAM *)(cs + 1);
1517 CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs, MapSL(lParam) );
1518 unmap_str_16_to_32W( cs->lpszName );
1519 unmap_str_16_to_32W( cs->lpszClass );
1521 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1523 MDICREATESTRUCTW *mdi_cs = (MDICREATESTRUCTW *)cs->lpCreateParams;
1524 unmap_str_16_to_32W( mdi_cs->szTitle );
1525 unmap_str_16_to_32W( mdi_cs->szClass );
1526 HeapFree(GetProcessHeap(), 0, cs->lpCreateParams);
1528 HeapFree( GetProcessHeap(), 0, cs );
1533 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1534 lParam = *(LPARAM *)(cs + 1);
1535 MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs, MapSL(lParam) );
1536 unmap_str_16_to_32W( cs->szTitle );
1537 unmap_str_16_to_32W( cs->szClass );
1538 HeapFree( GetProcessHeap(), 0, cs );
1544 LPMSG msg32 = (LPMSG)lParam;
1545 HeapFree( GetProcessHeap(), 0, msg32 );
1549 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1554 static HANDLE16 convert_handle_32_to_16(UINT src, unsigned int flags)
1557 UINT sz = GlobalSize((HANDLE)src);
1560 if (!(dst = GlobalAlloc16(flags, sz)))
1562 ptr32 = GlobalLock((HANDLE)src);
1563 ptr16 = GlobalLock16(dst);
1564 if (ptr16 != NULL && ptr32 != NULL) memcpy(ptr16, ptr32, sz);
1565 GlobalUnlock((HANDLE)src);
1566 GlobalUnlock16(dst);
1572 /**********************************************************************
1573 * WINPROC_MapMsg32ATo16
1575 * Map a message from 32-bit Ansi to 16-bit.
1576 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1578 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1579 UINT16 *pmsg16, WPARAM16 *pwparam16,
1582 *pmsg16 = (UINT16)msg32;
1583 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1587 *pmsg16 = SBM_SETRANGE16;
1588 *plparam = MAKELPARAM(wParam32, *plparam);
1593 *pmsg16 = SBM_GETRANGE16;
1601 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1610 case EM_SCROLLCARET:
1613 case EM_GETLINECOUNT:
1625 case EM_LINEFROMCHAR:
1626 case EM_SETTABSTOPS:
1627 case EM_SETPASSWORDCHAR:
1628 case EM_EMPTYUNDOBUFFER:
1629 case EM_GETFIRSTVISIBLELINE:
1630 case EM_SETREADONLY:
1631 case EM_SETWORDBREAKPROC:
1632 case EM_GETWORDBREAKPROC:
1633 case EM_GETPASSWORDCHAR:
1634 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1639 case LB_DELETESTRING:
1640 case LB_GETANCHORINDEX:
1641 case LB_GETCARETINDEX:
1644 case LB_GETHORIZONTALEXTENT:
1645 case LB_GETITEMDATA:
1646 case LB_GETITEMHEIGHT:
1648 case LB_GETSELCOUNT:
1650 case LB_GETTOPINDEX:
1651 case LB_RESETCONTENT:
1652 case LB_SELITEMRANGE:
1653 case LB_SELITEMRANGEEX:
1654 case LB_SETANCHORINDEX:
1655 case LB_SETCARETINDEX:
1656 case LB_SETCOLUMNWIDTH:
1658 case LB_SETHORIZONTALEXTENT:
1659 case LB_SETITEMDATA:
1660 case LB_SETITEMHEIGHT:
1662 case LB_SETTOPINDEX:
1663 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1665 case CB_DELETESTRING:
1667 case CB_GETLBTEXTLEN:
1669 case CB_RESETCONTENT:
1673 case CB_SHOWDROPDOWN:
1674 case CB_SETITEMDATA:
1675 case CB_SETITEMHEIGHT:
1676 case CB_GETITEMHEIGHT:
1677 case CB_SETEXTENDEDUI:
1678 case CB_GETEXTENDEDUI:
1679 case CB_GETDROPPEDSTATE:
1680 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1683 *pmsg16 = CB_GETEDITSEL16;
1688 case LB_FINDSTRINGEXACT:
1689 case LB_INSERTSTRING:
1690 case LB_SELECTSTRING:
1693 *plparam = (LPARAM)MapLS( (LPSTR)*plparam );
1694 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1699 case CB_FINDSTRINGEXACT:
1700 case CB_INSERTSTRING:
1701 case CB_SELECTSTRING:
1703 *plparam = (LPARAM)MapLS( (LPSTR)*plparam );
1704 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1707 case LB_GETITEMRECT:
1709 RECT16 *rect = HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16) + sizeof(LPARAM) );
1710 if (!rect) return -1;
1711 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1712 *plparam = MapLS( rect );
1714 *pmsg16 = LB_GETITEMRECT16;
1716 case LB_GETSELITEMS:
1718 LPARAM *items; /* old LPARAM first, then *pwparam16 x INT16 entries */
1720 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1721 if (!(items = HeapAlloc( GetProcessHeap(), 0,
1722 *pwparam16 * sizeof(INT16) + sizeof(LPARAM)))) return -1;
1723 *items++ = *plparam; /* Store the previous lParam */
1724 *plparam = MapLS( items );
1726 *pmsg16 = LB_GETSELITEMS16;
1728 case LB_SETTABSTOPS:
1733 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1734 if (!(stops = HeapAlloc( GetProcessHeap(), 0,
1735 *pwparam16 * sizeof(INT16) + sizeof(LPARAM)))) return -1;
1736 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1737 *plparam = MapLS( stops );
1740 *pmsg16 = LB_SETTABSTOPS16;
1743 case CB_GETDROPPEDCONTROLRECT:
1745 RECT16 *rect = HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16) + sizeof(LPARAM) );
1746 if (!rect) return -1;
1747 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1748 *plparam = (LPARAM)MapLS(rect);
1750 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1754 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1755 *pmsg16 = LB_GETTEXT16;
1759 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1760 *pmsg16 = CB_GETLBTEXT16;
1765 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
1766 *pmsg16 = EM_SETSEL16;
1773 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1777 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1781 PCOPYDATASTRUCT pcds32 = (PCOPYDATASTRUCT) *plparam;
1782 PCOPYDATASTRUCT16 pcds = HeapAlloc( GetProcessHeap(), 0, sizeof( *pcds));
1783 pcds->dwData = pcds32->dwData;
1784 pcds->cbData = pcds32->cbData;
1785 pcds->lpData = MapLS( pcds32->lpData);
1786 *plparam = MapLS( pcds );
1789 case WM_CTLCOLORMSGBOX:
1790 case WM_CTLCOLOREDIT:
1791 case WM_CTLCOLORLISTBOX:
1792 case WM_CTLCOLORBTN:
1793 case WM_CTLCOLORDLG:
1794 case WM_CTLCOLORSCROLLBAR:
1795 case WM_CTLCOLORSTATIC:
1796 *pmsg16 = WM_CTLCOLOR;
1797 *plparam = MAKELPARAM( (HWND16)*plparam,
1798 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1800 case WM_COMPAREITEM:
1802 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
1803 COMPAREITEMSTRUCT16 *cis = HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16));
1804 if (!cis) return -1;
1805 cis->CtlType = (UINT16)cis32->CtlType;
1806 cis->CtlID = (UINT16)cis32->CtlID;
1807 cis->hwndItem = HWND_16( cis32->hwndItem );
1808 cis->itemID1 = (UINT16)cis32->itemID1;
1809 cis->itemData1 = cis32->itemData1;
1810 cis->itemID2 = (UINT16)cis32->itemID2;
1811 cis->itemData2 = cis32->itemData2;
1812 *plparam = MapLS( cis );
1817 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
1818 DELETEITEMSTRUCT16 *dis = HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16) );
1819 if (!dis) return -1;
1820 dis->CtlType = (UINT16)dis32->CtlType;
1821 dis->CtlID = (UINT16)dis32->CtlID;
1822 dis->itemID = (UINT16)dis32->itemID;
1823 dis->hwndItem = (dis->CtlType == ODT_MENU) ? (HWND16)LOWORD(dis32->hwndItem)
1824 : HWND_16( dis32->hwndItem );
1825 dis->itemData = dis32->itemData;
1826 *plparam = MapLS( dis );
1831 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
1832 DRAWITEMSTRUCT16 *dis = HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16) );
1833 if (!dis) return -1;
1834 dis->CtlType = (UINT16)dis32->CtlType;
1835 dis->CtlID = (UINT16)dis32->CtlID;
1836 dis->itemID = (UINT16)dis32->itemID;
1837 dis->itemAction = (UINT16)dis32->itemAction;
1838 dis->itemState = (UINT16)dis32->itemState;
1839 dis->hwndItem = HWND_16( dis32->hwndItem );
1840 dis->hDC = HDC_16(dis32->hDC);
1841 dis->itemData = dis32->itemData;
1842 dis->rcItem.left = dis32->rcItem.left;
1843 dis->rcItem.top = dis32->rcItem.top;
1844 dis->rcItem.right = dis32->rcItem.right;
1845 dis->rcItem.bottom = dis32->rcItem.bottom;
1846 *plparam = MapLS( dis );
1849 case WM_MEASUREITEM:
1851 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
1852 MEASUREITEMSTRUCT16 *mis = HeapAlloc( GetProcessHeap(), 0, sizeof(*mis)+sizeof(LPARAM));
1853 if (!mis) return -1;
1854 mis->CtlType = (UINT16)mis32->CtlType;
1855 mis->CtlID = (UINT16)mis32->CtlID;
1856 mis->itemID = (UINT16)mis32->itemID;
1857 mis->itemWidth = (UINT16)mis32->itemWidth;
1858 mis->itemHeight = (UINT16)mis32->itemHeight;
1859 mis->itemData = mis32->itemData;
1860 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1861 *plparam = MapLS( mis );
1864 case WM_GETMINMAXINFO:
1866 MINMAXINFO16 *mmi = HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi) + sizeof(LPARAM) );
1867 if (!mmi) return -1;
1868 MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
1869 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1870 *plparam = MapLS( mmi );
1874 case WM_ASKCBFORMATNAME:
1876 LPARAM *str; /* store LPARAM, then *pwparam16 char space */
1877 *pwparam16 = (WPARAM16)min( wParam32, 0xff80 ); /* Must be < 64K */
1878 if (!(str = HeapAlloc( GetProcessHeap(), 0, *pwparam16 + sizeof(LPARAM)))) return -1;
1879 *str++ = *plparam; /* Store the previous lParam */
1880 *plparam = MapLS( str );
1885 MDICREATESTRUCT16 *cs;
1886 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
1888 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16) ))) return -1;
1889 MDICREATESTRUCT32Ato16( cs32, cs );
1890 cs->szTitle = MapLS( cs32->szTitle );
1891 cs->szClass = MapLS( cs32->szClass );
1892 *plparam = MapLS( cs );
1895 case WM_MDIGETACTIVE:
1898 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1899 (HMENU16)LOWORD(*plparam) );
1900 *pwparam16 = (*plparam == 0);
1903 if(HIWORD(wParam32) & MF_POPUP)
1906 if (((UINT)HIWORD(wParam32) != 0xFFFF) || (*plparam))
1908 if((hmenu = GetSubMenu((HMENU)*plparam, *pwparam16)))
1909 *pwparam16=HMENU_16(hmenu);
1914 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1916 case WM_MDIACTIVATE:
1917 if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_MDICHILD)
1919 *pwparam16 = ((HWND)*plparam == hwnd);
1920 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1921 (HWND16)LOWORD(wParam32) );
1925 *pwparam16 = HWND_16( (HWND)wParam32 );
1931 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
1932 NCCALCSIZE_PARAMS16 *nc = HeapAlloc( GetProcessHeap(), 0, sizeof(*nc) + sizeof(LPARAM));
1935 nc->rgrc[0].left = nc32->rgrc[0].left;
1936 nc->rgrc[0].top = nc32->rgrc[0].top;
1937 nc->rgrc[0].right = nc32->rgrc[0].right;
1938 nc->rgrc[0].bottom = nc32->rgrc[0].bottom;
1942 nc->rgrc[1].left = nc32->rgrc[1].left;
1943 nc->rgrc[1].top = nc32->rgrc[1].top;
1944 nc->rgrc[1].right = nc32->rgrc[1].right;
1945 nc->rgrc[1].bottom = nc32->rgrc[1].bottom;
1946 nc->rgrc[2].left = nc32->rgrc[2].left;
1947 nc->rgrc[2].top = nc32->rgrc[2].top;
1948 nc->rgrc[2].right = nc32->rgrc[2].right;
1949 nc->rgrc[2].bottom = nc32->rgrc[2].bottom;
1950 if (!(wp = HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16) )))
1952 HeapFree( GetProcessHeap(), 0, nc );
1955 WINDOWPOS32to16( nc32->lppos, wp );
1956 nc->lppos = MapLS( wp );
1958 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1959 *plparam = MapLS( nc );
1966 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
1968 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16) ))) return -1;
1969 CREATESTRUCT32Ato16( cs32, cs );
1970 cs->lpszName = MapLS( cs32->lpszName );
1971 cs->lpszClass = MapLS( cs32->lpszClass );
1973 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1975 MDICREATESTRUCT16 *mdi_cs16;
1976 MDICREATESTRUCTA *mdi_cs = (MDICREATESTRUCTA *)cs32->lpCreateParams;
1977 mdi_cs16 = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs16));
1980 HeapFree(GetProcessHeap(), 0, cs);
1983 MDICREATESTRUCT32Ato16(mdi_cs, mdi_cs16);
1984 mdi_cs16->szTitle = MapLS( mdi_cs->szTitle );
1985 mdi_cs16->szClass = MapLS( mdi_cs->szClass );
1986 cs->lpCreateParams = MapLS( mdi_cs16 );
1988 *plparam = MapLS( cs );
1991 case WM_PARENTNOTIFY:
1992 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1993 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1994 /* else nothing to do */
1997 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
2000 case WM_WININICHANGE:
2001 case WM_DEVMODECHANGE:
2002 *plparam = MapLS( (LPSTR)*plparam );
2004 case WM_WINDOWPOSCHANGING:
2005 case WM_WINDOWPOSCHANGED:
2007 WINDOWPOS16 *wp = HeapAlloc( GetProcessHeap(), 0, sizeof(*wp) + sizeof(LPARAM) );
2009 WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
2010 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
2011 *plparam = MapLS( wp );
2016 LPMSG msg32 = (LPMSG) *plparam;
2017 LPMSG16 msg16 = HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16) );
2019 if (!msg16) return -1;
2020 msg16->hwnd = HWND_16( msg32->hwnd );
2021 msg16->message = msg32->message;
2022 msg16->wParam = msg32->wParam;
2023 msg16->lParam = msg32->lParam;
2024 msg16->time = msg32->time;
2025 msg16->pt.x = msg32->pt.x;
2026 msg16->pt.y = msg32->pt.y;
2027 *plparam = MapLS( msg16 );
2032 case WM_ACTIVATEAPP:
2033 if (*plparam) *plparam = HTASK_16( (HANDLE)*plparam );
2037 MDINEXTMENU *next = (MDINEXTMENU *)*plparam;
2038 *plparam = (LPARAM)next->hmenuIn;
2042 if (IsIconic( hwnd ) && GetClassLongPtrW( hwnd, GCLP_HICON ))
2044 *pmsg16 = WM_PAINTICON;
2049 if (IsIconic( hwnd ) && GetClassLongPtrW( hwnd, GCLP_HICON ))
2050 *pmsg16 = WM_ICONERASEBKGND;
2052 case WM_PAINTCLIPBOARD:
2053 case WM_SIZECLIPBOARD:
2054 FIXME_(msg)("message %04x needs translation\n", msg32 );
2056 /* following messages should not be sent to 16-bit apps */
2059 case WM_CAPTURECHANGED:
2060 case WM_STYLECHANGING:
2061 case WM_STYLECHANGED:
2063 case WM_DDE_INITIATE:
2064 case WM_DDE_TERMINATE:
2065 case WM_DDE_UNADVISE:
2066 case WM_DDE_REQUEST:
2067 *pwparam16 = HWND_16((HWND)wParam32);
2076 *pwparam16 = HWND_16((HWND)wParam32);
2077 UnpackDDElParam(msg32, *plparam, &lo32, &hi);
2078 if (lo32 && !(lo16 = convert_handle_32_to_16(lo32, GMEM_DDESHARE)))
2080 *plparam = MAKELPARAM(lo16, hi);
2082 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2089 *pwparam16 = HWND_16((HWND)wParam32);
2091 UnpackDDElParam(msg32, *plparam, &lo, &hi);
2093 if (GlobalGetAtomNameA((ATOM)hi, buf, sizeof(buf)) > 0) flag |= 1;
2094 if (GlobalSize((HANDLE)hi) != 0) flag |= 2;
2100 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
2105 break; /* atom, nothing to do */
2107 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi);
2110 hi = convert_handle_32_to_16(hi, GMEM_DDESHARE);
2113 *plparam = MAKELPARAM(lo, hi);
2115 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2116 case WM_DDE_EXECUTE:
2117 *plparam = convert_handle_32_to_16(*plparam, GMEM_DDESHARE);
2118 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2119 default: /* No translation needed */
2125 /**********************************************************************
2126 * WINPROC_UnmapMsg32ATo16
2128 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2130 static void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2131 WPARAM16 wParam16, LPARAM lParam16, LRESULT *result )
2136 *(LPINT)wParam = LOWORD(*result);
2137 *(LPINT)lParam = HIWORD(*result);
2144 case LB_FINDSTRINGEXACT:
2145 case LB_INSERTSTRING:
2146 case LB_SELECTSTRING:
2150 case CB_FINDSTRINGEXACT:
2151 case CB_INSERTSTRING:
2152 case CB_SELECTSTRING:
2156 case WM_WININICHANGE:
2157 case WM_DEVMODECHANGE:
2158 UnMapLS( (SEGPTR)lParam16 );
2160 case LB_SETTABSTOPS:
2161 case WM_COMPAREITEM:
2165 void *ptr = MapSL( lParam16 );
2166 UnMapLS( lParam16 );
2167 HeapFree( GetProcessHeap(), 0, ptr );
2172 PCOPYDATASTRUCT16 pcds = MapSL( lParam16 );
2173 UnMapLS( lParam16 );
2174 UnMapLS( pcds->lpData );
2175 HeapFree( GetProcessHeap(), 0, pcds );
2178 case CB_GETDROPPEDCONTROLRECT:
2179 case LB_GETITEMRECT:
2182 RECT16 *rect = MapSL(lParam16);
2183 UnMapLS( lParam16 );
2184 lParam16 = *(LPARAM *)(rect + 1);
2185 r32 = (RECT *)lParam16;
2186 r32->left = rect->left;
2187 r32->top = rect->top;
2188 r32->right = rect->right;
2189 r32->bottom = rect->bottom;
2190 HeapFree( GetProcessHeap(), 0, rect );
2193 case LB_GETSELITEMS:
2196 LPINT16 items = MapSL(lParam16);
2197 UnMapLS( lParam16 );
2198 lParam16 = *((LPARAM *)items - 1);
2199 for (i = 0; i < wParam16; i++) *((LPINT)lParam16 + i) = items[i];
2200 HeapFree( GetProcessHeap(), 0, (LPARAM *)items - 1 );
2206 *((PUINT)(wParam)) = LOWORD(*result);
2208 *((PUINT)(lParam)) = HIWORD(*result); /* FIXME: substract 1? */
2211 case WM_MEASUREITEM:
2213 MEASUREITEMSTRUCT16 *mis = MapSL(lParam16);
2214 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
2215 mis32->itemWidth = mis->itemWidth;
2216 mis32->itemHeight = mis->itemHeight;
2217 UnMapLS( lParam16 );
2218 HeapFree( GetProcessHeap(), 0, mis );
2221 case WM_GETMINMAXINFO:
2223 MINMAXINFO16 *mmi = MapSL(lParam16);
2224 UnMapLS( lParam16 );
2225 lParam16 = *(LPARAM *)(mmi + 1);
2226 MINMAXINFO16to32( mmi, (MINMAXINFO *)lParam16 );
2227 HeapFree( GetProcessHeap(), 0, mmi );
2231 case WM_ASKCBFORMATNAME:
2233 LPSTR str = MapSL(lParam16);
2234 UnMapLS( lParam16 );
2235 lParam16 = *((LPARAM *)str - 1);
2236 lstrcpynA( (LPSTR)lParam16, str, wParam16 );
2237 HeapFree( GetProcessHeap(), 0, (LPARAM *)str - 1 );
2242 MDICREATESTRUCT16 *cs = MapSL(lParam16);
2243 UnMapLS( cs->szTitle );
2244 UnMapLS( cs->szClass );
2245 UnMapLS( lParam16 );
2246 HeapFree( GetProcessHeap(), 0, cs );
2249 case WM_MDIGETACTIVE:
2250 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(*result);
2251 *result = (LRESULT)WIN_Handle32( LOWORD(*result) );
2255 NCCALCSIZE_PARAMS *nc32;
2256 NCCALCSIZE_PARAMS16 *nc = MapSL(lParam16);
2257 UnMapLS( lParam16 );
2258 lParam16 = *(LPARAM *)(nc + 1);
2259 nc32 = (NCCALCSIZE_PARAMS *)lParam16;
2260 nc32->rgrc[0].left = nc->rgrc[0].left;
2261 nc32->rgrc[0].top = nc->rgrc[0].top;
2262 nc32->rgrc[0].right = nc->rgrc[0].right;
2263 nc32->rgrc[0].bottom = nc->rgrc[0].bottom;
2266 WINDOWPOS16 *pos = MapSL(nc->lppos);
2267 UnMapLS( nc->lppos );
2268 nc32->rgrc[1].left = nc->rgrc[1].left;
2269 nc32->rgrc[1].top = nc->rgrc[1].top;
2270 nc32->rgrc[1].right = nc->rgrc[1].right;
2271 nc32->rgrc[1].bottom = nc->rgrc[1].bottom;
2272 nc32->rgrc[2].left = nc->rgrc[2].left;
2273 nc32->rgrc[2].top = nc->rgrc[2].top;
2274 nc32->rgrc[2].right = nc->rgrc[2].right;
2275 nc32->rgrc[2].bottom = nc->rgrc[2].bottom;
2276 WINDOWPOS16to32( pos, nc32->lppos );
2277 HeapFree( GetProcessHeap(), 0, pos );
2279 HeapFree( GetProcessHeap(), 0, nc );
2285 CREATESTRUCT16 *cs = MapSL(lParam16);
2286 UnMapLS( lParam16 );
2287 UnMapLS( cs->lpszName );
2288 UnMapLS( cs->lpszClass );
2289 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2291 MDICREATESTRUCT16 *mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs->lpCreateParams);
2292 UnMapLS( cs->lpCreateParams );
2293 UnMapLS( mdi_cs16->szTitle );
2294 UnMapLS( mdi_cs16->szClass );
2295 HeapFree(GetProcessHeap(), 0, mdi_cs16);
2297 HeapFree( GetProcessHeap(), 0, cs );
2300 case WM_WINDOWPOSCHANGING:
2301 case WM_WINDOWPOSCHANGED:
2303 WINDOWPOS16 *wp = MapSL(lParam16);
2304 UnMapLS( lParam16 );
2305 lParam16 = *(LPARAM *)(wp + 1);
2306 WINDOWPOS16to32( wp, (WINDOWPOS *)lParam16 );
2307 HeapFree( GetProcessHeap(), 0, wp );
2316 LPMSG16 msg16 = MapSL(lParam16);
2317 UnMapLS( lParam16 );
2318 HeapFree( GetProcessHeap(), 0, msg16 );
2323 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
2324 next->hmenuNext = HMENU_32( LOWORD(*result) );
2325 next->hwndNext = WIN_Handle32( HIWORD(*result) );
2333 /**********************************************************************
2334 * WINPROC_MapMsg32WTo16
2336 * Map a message from 32-bit Unicode to 16-bit.
2337 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2339 static INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
2340 UINT16 *pmsg16, WPARAM16 *pwparam16, LPARAM *plparam )
2342 *pmsg16 = LOWORD(msg32);
2343 *pwparam16 = LOWORD(wParam32);
2348 case LB_FINDSTRINGEXACT:
2349 case LB_INSERTSTRING:
2350 case LB_SELECTSTRING:
2353 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2354 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2359 case CB_FINDSTRINGEXACT:
2360 case CB_INSERTSTRING:
2361 case CB_SELECTSTRING:
2363 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2364 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2371 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2373 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16) ))) return -1;
2374 CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2375 cs->lpszName = map_str_32W_to_16( cs32->lpszName );
2376 cs->lpszClass = map_str_32W_to_16( cs32->lpszClass );
2378 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2380 MDICREATESTRUCT16 *mdi_cs16;
2381 MDICREATESTRUCTW *mdi_cs = (MDICREATESTRUCTW *)cs32->lpCreateParams;
2382 mdi_cs16 = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs16));
2385 HeapFree(GetProcessHeap(), 0, cs);
2388 MDICREATESTRUCT32Ato16((MDICREATESTRUCTA *)mdi_cs, mdi_cs16);
2389 mdi_cs16->szTitle = map_str_32W_to_16(mdi_cs->szTitle);
2390 mdi_cs16->szClass = map_str_32W_to_16(mdi_cs->szClass);
2391 cs->lpCreateParams = MapLS(mdi_cs16);
2393 *plparam = MapLS(cs);
2398 MDICREATESTRUCT16 *cs;
2399 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2401 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16) ))) return -1;
2402 MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2403 cs->szTitle = map_str_32W_to_16( cs32->szTitle );
2404 cs->szClass = map_str_32W_to_16( cs32->szClass );
2405 *plparam = MapLS(cs);
2409 case WM_WININICHANGE:
2410 case WM_DEVMODECHANGE:
2411 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2415 if ( WINPROC_TestLBForStr( hwnd, msg32 ))
2417 LPSTR str = HeapAlloc( GetProcessHeap(), 0, 512 ); /* FIXME: fixed sized buffer */
2418 if (!str) return -1;
2419 *pmsg16 = (msg32 == LB_GETTEXT) ? LB_GETTEXT16 : CB_GETLBTEXT16;
2420 *plparam = (LPARAM)MapLS(str);
2425 *pwparam16 = map_wparam_char_WtoA( wParam32, 1 );
2426 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
2429 *pwparam16 = map_wparam_char_WtoA( wParam32, 1 );
2430 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
2435 case WM_SYSDEADCHAR:
2436 *pwparam16 = map_wparam_char_WtoA( wParam32, 1 );
2439 *pwparam16 = map_wparam_char_WtoA( wParam32, 2 );
2442 default: /* No Unicode translation needed (?) */
2443 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2444 pwparam16, plparam );
2449 /**********************************************************************
2450 * WINPROC_UnmapMsg32WTo16
2452 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2454 static void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2455 WPARAM16 wParam16, LPARAM lParam16, LRESULT *result )
2461 case LB_FINDSTRINGEXACT:
2462 case LB_INSERTSTRING:
2463 case LB_SELECTSTRING:
2468 case CB_FINDSTRINGEXACT:
2469 case CB_INSERTSTRING:
2470 case CB_SELECTSTRING:
2473 case WM_WININICHANGE:
2474 case WM_DEVMODECHANGE:
2475 unmap_str_32W_to_16( lParam16 );
2480 CREATESTRUCT16 *cs = MapSL(lParam16);
2481 UnMapLS( lParam16 );
2482 unmap_str_32W_to_16( cs->lpszName );
2483 unmap_str_32W_to_16( cs->lpszClass );
2485 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2487 MDICREATESTRUCT16 *mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs->lpCreateParams);
2488 UnMapLS( cs->lpCreateParams );
2489 unmap_str_32W_to_16(mdi_cs16->szTitle);
2490 unmap_str_32W_to_16(mdi_cs16->szClass);
2491 HeapFree(GetProcessHeap(), 0, mdi_cs16);
2493 HeapFree( GetProcessHeap(), 0, cs );
2498 MDICREATESTRUCT16 *cs = MapSL(lParam16);
2499 UnMapLS( lParam16 );
2500 unmap_str_32W_to_16( cs->szTitle );
2501 unmap_str_32W_to_16( cs->szClass );
2502 HeapFree( GetProcessHeap(), 0, cs );
2506 case WM_ASKCBFORMATNAME:
2508 LPSTR str = MapSL(lParam16);
2509 UnMapLS( lParam16 );
2510 lParam16 = *((LPARAM *)str - 1);
2511 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)lParam16, 0x7fffffff );
2512 *result = strlenW( (LPWSTR)lParam16 );
2513 HeapFree( GetProcessHeap(), 0, (LPARAM *)str - 1 );
2518 if ( WINPROC_TestLBForStr( hwnd, msg ))
2520 LPSTR str = MapSL(lParam16);
2521 UnMapLS( lParam16 );
2522 *result = MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)lParam, 0x7fffffff ) - 1;
2523 HeapFree( GetProcessHeap(), 0, (LPARAM *)str );
2527 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, wParam16, lParam16, result );
2533 /**********************************************************************
2534 * WINPROC_CallProcAtoW
2536 * Call a window procedure, translating args from Ansi to Unicode.
2538 LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg, WPARAM wParam,
2539 LPARAM lParam, LRESULT *result, void *arg )
2544 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2545 hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
2552 WCHAR *ptr, buffer[512];
2553 CREATESTRUCTA *csA = (CREATESTRUCTA *)lParam;
2554 CREATESTRUCTW csW = *(CREATESTRUCTW *)csA;
2555 MDICREATESTRUCTW mdi_cs;
2556 DWORD name_lenA = 0, name_lenW = 0, class_lenA = 0, class_lenW = 0;
2558 if (HIWORD(csA->lpszClass))
2560 class_lenA = strlen(csA->lpszClass) + 1;
2561 RtlMultiByteToUnicodeSize( &class_lenW, csA->lpszClass, class_lenA );
2563 if (HIWORD(csA->lpszName))
2565 name_lenA = strlen(csA->lpszName) + 1;
2566 RtlMultiByteToUnicodeSize( &name_lenW, csA->lpszName, name_lenA );
2569 if (!(ptr = get_buffer( buffer, sizeof(buffer), class_lenW + name_lenW ))) break;
2573 csW.lpszClass = ptr;
2574 RtlMultiByteToUnicodeN( ptr, class_lenW, NULL, csA->lpszClass, class_lenA );
2578 csW.lpszName = ptr + class_lenW/sizeof(WCHAR);
2579 RtlMultiByteToUnicodeN( ptr + class_lenW/sizeof(WCHAR), name_lenW, NULL,
2580 csA->lpszName, name_lenA );
2583 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2585 mdi_cs = *(MDICREATESTRUCTW *)csA->lpCreateParams;
2586 mdi_cs.szTitle = csW.lpszName;
2587 mdi_cs.szClass = csW.lpszClass;
2588 csW.lpCreateParams = &mdi_cs;
2591 ret = callback( hwnd, msg, wParam, (LPARAM)&csW, result, arg );
2592 free_buffer( buffer, ptr );
2598 WCHAR *ptr, buffer[512];
2599 DWORD title_lenA = 0, title_lenW = 0, class_lenA = 0, class_lenW = 0;
2600 MDICREATESTRUCTA *csA = (MDICREATESTRUCTA *)lParam;
2601 MDICREATESTRUCTW csW;
2603 memcpy( &csW, csA, sizeof(csW) );
2605 if (HIWORD(csA->szTitle))
2607 title_lenA = strlen(csA->szTitle) + 1;
2608 RtlMultiByteToUnicodeSize( &title_lenW, csA->szTitle, title_lenA );
2610 if (HIWORD(csA->szClass))
2612 class_lenA = strlen(csA->szClass) + 1;
2613 RtlMultiByteToUnicodeSize( &class_lenW, csA->szClass, class_lenA );
2616 if (!(ptr = get_buffer( buffer, sizeof(buffer), title_lenW + class_lenW ))) break;
2621 RtlMultiByteToUnicodeN( ptr, title_lenW, NULL, csA->szTitle, title_lenA );
2625 csW.szClass = ptr + title_lenW/sizeof(WCHAR);
2626 RtlMultiByteToUnicodeN( ptr + title_lenW/sizeof(WCHAR), class_lenW, NULL,
2627 csA->szClass, class_lenA );
2629 ret = callback( hwnd, msg, wParam, (LPARAM)&csW, result, arg );
2630 free_buffer( buffer, ptr );
2635 case WM_ASKCBFORMATNAME:
2637 WCHAR *ptr, buffer[512];
2638 LPSTR str = (LPSTR)lParam;
2639 DWORD len = wParam * sizeof(WCHAR);
2641 if (!(ptr = get_buffer( buffer, sizeof(buffer), len ))) break;
2642 ret = callback( hwnd, msg, wParam, (LPARAM)ptr, result, arg );
2643 if (*result && wParam)
2645 RtlUnicodeToMultiByteN( str, wParam - 1, &len, ptr, strlenW(ptr) * sizeof(WCHAR) );
2649 free_buffer( buffer, ptr );
2654 case LB_INSERTSTRING:
2656 case LB_FINDSTRINGEXACT:
2657 case LB_SELECTSTRING:
2659 case CB_INSERTSTRING:
2661 case CB_FINDSTRINGEXACT:
2662 case CB_SELECTSTRING:
2663 if (!lParam || !WINPROC_TestLBForStr( hwnd, msg ))
2665 ret = callback( hwnd, msg, wParam, lParam, result, arg );
2670 case WM_WININICHANGE:
2671 case WM_DEVMODECHANGE:
2676 if (!lParam) ret = callback( hwnd, msg, wParam, lParam, result, arg );
2679 WCHAR *ptr, buffer[512];
2680 LPCSTR strA = (LPCSTR)lParam;
2681 DWORD lenW, lenA = strlen(strA) + 1;
2683 RtlMultiByteToUnicodeSize( &lenW, strA, lenA );
2684 if ((ptr = get_buffer( buffer, sizeof(buffer), lenW )))
2686 RtlMultiByteToUnicodeN( ptr, lenW, NULL, strA, lenA );
2687 ret = callback( hwnd, msg, wParam, (LPARAM)ptr, result, arg );
2688 free_buffer( buffer, ptr );
2695 if (lParam && WINPROC_TestLBForStr( hwnd, msg ))
2697 WCHAR buffer[512]; /* FIXME: fixed sized buffer */
2699 ret = callback( hwnd, msg, wParam, (LPARAM)buffer, result, arg );
2703 RtlUnicodeToMultiByteN( (LPSTR)lParam, ~0u, &len,
2704 buffer, (strlenW(buffer) + 1) * sizeof(WCHAR) );
2708 else ret = callback( hwnd, msg, wParam, lParam, result, arg );
2712 if( (unmap = WINPROC_MapMsg32ATo32W( hwnd, msg, &wParam, &lParam )) == -1) {
2713 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2714 SPY_GetMsgName(msg, hwnd), wParam, lParam );
2717 ret = callback( hwnd, msg, wParam, lParam, result, arg );
2719 *result = WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, *result,
2720 (callback == call_window_proc) ? arg : NULL /*FIXME: hack*/ );
2727 /**********************************************************************
2728 * WINPROC_CallProcWtoA
2730 * Call a window procedure, translating args from Unicode to Ansi.
2732 static LRESULT WINPROC_CallProcWtoA( winproc_callback_t callback, HWND hwnd, UINT msg, WPARAM wParam,
2733 LPARAM lParam, LRESULT *result, void *arg )
2737 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2738 hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
2744 { /* csW->lpszName and csW->lpszClass are NOT supposed to be atoms
2747 char buffer[1024], *cls, *name;
2748 CREATESTRUCTW *csW = (CREATESTRUCTW *)lParam;
2749 CREATESTRUCTA csA = *(CREATESTRUCTA *)csW;
2750 MDICREATESTRUCTA mdi_cs;
2751 DWORD name_lenA, name_lenW, class_lenA, class_lenW;
2753 class_lenW = strlenW(csW->lpszClass) * sizeof(WCHAR);
2754 RtlUnicodeToMultiByteSize(&class_lenA, csW->lpszClass, class_lenW);
2758 name_lenW = strlenW(csW->lpszName) * sizeof(WCHAR);
2759 RtlUnicodeToMultiByteSize(&name_lenA, csW->lpszName, name_lenW);
2762 name_lenW = name_lenA = 0;
2764 if (!(cls = get_buffer( buffer, sizeof(buffer), class_lenA + name_lenA + 2 ))) break;
2766 RtlUnicodeToMultiByteN(cls, class_lenA, NULL, csW->lpszClass, class_lenW);
2767 cls[class_lenA] = 0;
2768 csA.lpszClass = cls;
2772 name = cls + class_lenA + 1;
2773 RtlUnicodeToMultiByteN(name, name_lenA, NULL, csW->lpszName, name_lenW);
2774 name[name_lenA] = 0;
2775 csA.lpszName = name;
2778 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2780 mdi_cs = *(MDICREATESTRUCTA *)csW->lpCreateParams;
2781 mdi_cs.szTitle = csA.lpszName;
2782 mdi_cs.szClass = csA.lpszClass;
2783 csA.lpCreateParams = &mdi_cs;
2786 ret = callback( hwnd, msg, wParam, (LPARAM)&csA, result, arg );
2787 free_buffer( buffer, cls );
2792 case WM_ASKCBFORMATNAME:
2794 char *ptr, buffer[512];
2795 DWORD len = wParam * 2;
2797 if (!(ptr = get_buffer( buffer, sizeof(buffer), len ))) break;
2798 ret = callback( hwnd, msg, wParam, (LPARAM)ptr, result, arg );
2801 RtlMultiByteToUnicodeN( (LPWSTR)lParam, wParam*sizeof(WCHAR), &len, ptr, strlen(ptr)+1 );
2802 *result = len/sizeof(WCHAR) - 1; /* do not count terminating null */
2803 ((LPWSTR)lParam)[*result] = 0;
2805 free_buffer( buffer, ptr );
2810 case LB_INSERTSTRING:
2812 case LB_FINDSTRINGEXACT:
2813 case LB_SELECTSTRING:
2815 case CB_INSERTSTRING:
2817 case CB_FINDSTRINGEXACT:
2818 case CB_SELECTSTRING:
2819 if (!lParam || !WINPROC_TestLBForStr( hwnd, msg ))
2821 ret = callback( hwnd, msg, wParam, lParam, result, arg );
2826 case WM_WININICHANGE:
2827 case WM_DEVMODECHANGE:
2832 if (!lParam) ret = callback( hwnd, msg, wParam, lParam, result, arg );
2835 char *ptr, buffer[512];
2836 LPCWSTR strW = (LPCWSTR)lParam;
2837 DWORD lenA, lenW = (strlenW(strW) + 1) * sizeof(WCHAR);
2839 RtlUnicodeToMultiByteSize( &lenA, strW, lenW );
2840 if ((ptr = get_buffer( buffer, sizeof(buffer), lenA )))
2842 RtlUnicodeToMultiByteN( ptr, lenA, NULL, strW, lenW );
2843 ret = callback( hwnd, msg, wParam, (LPARAM)ptr, result, arg );
2844 free_buffer( buffer, ptr );
2851 char *ptr, buffer[1024];
2852 DWORD title_lenA = 0, title_lenW = 0, class_lenA = 0, class_lenW = 0;
2853 MDICREATESTRUCTW *csW = (MDICREATESTRUCTW *)lParam;
2854 MDICREATESTRUCTA csA;
2856 memcpy( &csA, csW, sizeof(csA) );
2858 if (HIWORD(csW->szTitle))
2860 title_lenW = (strlenW(csW->szTitle) + 1) * sizeof(WCHAR);
2861 RtlUnicodeToMultiByteSize( &title_lenA, csW->szTitle, title_lenW );
2863 if (HIWORD(csW->szClass))
2865 class_lenW = (strlenW(csW->szClass) + 1) * sizeof(WCHAR);
2866 RtlUnicodeToMultiByteSize( &class_lenA, csW->szClass, class_lenW );
2869 if (!(ptr = get_buffer( buffer, sizeof(buffer), title_lenA + class_lenA ))) break;
2873 RtlUnicodeToMultiByteN( ptr, title_lenA, NULL, csW->szTitle, title_lenW );
2878 RtlUnicodeToMultiByteN( ptr + title_lenA, class_lenA, NULL, csW->szClass, class_lenW );
2879 csA.szClass = ptr + title_lenA;
2881 ret = callback( hwnd, msg, wParam, (LPARAM)&csA, result, arg );
2882 free_buffer( buffer, ptr );
2888 if (lParam && WINPROC_TestLBForStr( hwnd, msg ))
2890 char buffer[512]; /* FIXME: fixed sized buffer */
2892 ret = callback( hwnd, msg, wParam, (LPARAM)buffer, result, arg );
2896 RtlMultiByteToUnicodeN( (LPWSTR)lParam, ~0u, &len, buffer, strlen(buffer) + 1 );
2897 *result = len / sizeof(WCHAR) - 1;
2900 else ret = callback( hwnd, msg, wParam, lParam, result, arg );
2905 char *ptr, buffer[512];
2906 WORD len = *(WORD *)lParam;
2908 if (!(ptr = get_buffer( buffer, sizeof(buffer), len * 2 ))) break;
2909 *((WORD *)ptr) = len * 2; /* store the length */
2910 ret = callback( hwnd, msg, wParam, (LPARAM)ptr, result, arg );
2914 RtlMultiByteToUnicodeN( (LPWSTR)lParam, len*sizeof(WCHAR), &reslen, buffer, *result );
2915 *result = reslen / sizeof(WCHAR);
2916 if (*result < len) ((LPWSTR)lParam)[*result] = 0;
2918 free_buffer( buffer, ptr );
2927 case WM_SYSDEADCHAR:
2928 case EM_SETPASSWORDCHAR:
2929 ret = callback( hwnd, msg, map_wparam_char_WtoA(wParam,1), lParam, result, arg );
2933 ret = callback( hwnd, msg, map_wparam_char_WtoA(wParam,2), lParam, result, arg );
2936 case WM_PAINTCLIPBOARD:
2937 case WM_SIZECLIPBOARD:
2938 FIXME_(msg)( "message %s (%04x) needs translation, please report\n",
2939 SPY_GetMsgName(msg, hwnd), msg );
2943 ret = callback( hwnd, msg, wParam, lParam, result, arg );
2951 /**********************************************************************
2952 * WINPROC_CallProc16To32A
2954 LRESULT WINPROC_CallProc16To32A( winproc_callback_t callback, HWND16 hwnd, UINT16 msg,
2955 WPARAM16 wParam, LPARAM lParam, LRESULT *result, void *arg )
2960 HWND hwnd32 = WIN_Handle32( hwnd );
2962 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2963 hwnd32, SPY_GetMsgName(msg, hwnd32), wParam, lParam);
2965 if (WINPROC_MapMsg16To32A( hwnd32, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2968 ret = callback( hwnd32, msg32, wParam32, lParam, result, arg );
2969 *result = WINPROC_UnmapMsg16To32A( hwnd32, msg32, wParam32, lParam, *result );
2974 /**********************************************************************
2975 * WINPROC_CallProc16To32W
2977 static LRESULT WINPROC_CallProc16To32W( winproc_callback_t callback, HWND16 hwnd, UINT16 msg,
2978 WPARAM16 wParam, LPARAM lParam, LRESULT *result, void *arg )
2983 HWND hwnd32 = WIN_Handle32( hwnd );
2985 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2986 hwnd32, SPY_GetMsgName(msg, hwnd32), wParam, lParam);
2988 if (WINPROC_MapMsg16To32W( hwnd32, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2991 ret = callback( hwnd32, msg32, wParam32, lParam, result, arg );
2992 *result = WINPROC_UnmapMsg16To32W( hwnd32, msg32, wParam32, lParam, *result,
2993 (callback == call_window_proc) ? arg : NULL /*FIXME: hack*/ );
2998 /**********************************************************************
2999 * __wine_call_wndproc (USER.1010)
3001 LRESULT WINAPI __wine_call_wndproc( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam,
3007 WINPROC_CallProc16To32A( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procA );
3009 WINPROC_CallProc16To32W( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procW );
3014 /**********************************************************************
3015 * WINPROC_CallProc32ATo16
3017 * Call a 16-bit window procedure, translating the 32-bit args.
3019 LRESULT WINPROC_CallProc32ATo16( winproc_callback16_t callback, HWND hwnd, UINT msg,
3020 WPARAM wParam, LPARAM lParam, LRESULT *result, void *arg )
3027 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3028 hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
3031 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam, &msg16, &wParam16, &lParam16 ) == -1)
3033 ret = callback( HWND_16(hwnd), msg16, wParam16, lParam16, result, arg );
3034 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, wParam16, lParam16, result );
3039 /**********************************************************************
3040 * WINPROC_CallProc32WTo16
3042 * Call a 16-bit window procedure, translating the 32-bit args.
3044 static LRESULT WINPROC_CallProc32WTo16( winproc_callback16_t callback, HWND hwnd, UINT msg,
3045 WPARAM wParam, LPARAM lParam, LRESULT *result, void *arg )
3052 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3053 hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
3056 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &wParam16, &lParam16 ) == -1)
3058 ret = callback( HWND_16(hwnd), msg16, wParam16, lParam16, result, arg );
3059 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, wParam16, lParam16, result );
3064 /**********************************************************************
3065 * CallWindowProc (USER.122)
3067 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
3068 WPARAM16 wParam, LPARAM lParam )
3073 if (!func) return 0;
3075 if (!(proc = handle16_to_proc( func )))
3076 call_window_proc16( hwnd, msg, wParam, lParam, &result, func );
3077 else if (proc->procA)
3078 WINPROC_CallProc16To32A( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procA );
3079 else if (proc->procW)
3080 WINPROC_CallProc16To32W( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procW );
3082 call_window_proc16( hwnd, msg, wParam, lParam, &result, proc->proc16 );
3088 /**********************************************************************
3089 * CallWindowProcA (USER32.@)
3091 * The CallWindowProc() function invokes the windows procedure _func_,
3092 * with _hwnd_ as the target window, the message specified by _msg_, and
3093 * the message parameters _wParam_ and _lParam_.
3095 * Some kinds of argument conversion may be done, I'm not sure what.
3097 * CallWindowProc() may be used for windows subclassing. Use
3098 * SetWindowLong() to set a new windows procedure for windows of the
3099 * subclass, and handle subclassed messages in the new windows
3100 * procedure. The new windows procedure may then use CallWindowProc()
3101 * with _func_ set to the parent class's windows procedure to dispatch
3102 * the message to the superclass.
3106 * The return value is message dependent.
3112 LRESULT WINAPI CallWindowProcA(
3113 WNDPROC func, /* [in] window procedure */
3114 HWND hwnd, /* [in] target window */
3115 UINT msg, /* [in] message */
3116 WPARAM wParam, /* [in] message dependent parameter */
3117 LPARAM lParam /* [in] message dependent parameter */
3122 if (!func) return 0;
3124 if (!(proc = handle_to_proc( func )))
3125 call_window_proc( hwnd, msg, wParam, lParam, &result, func );
3126 else if (proc->procA)
3127 call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
3128 else if (proc->procW)
3129 WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procW );
3131 WINPROC_CallProc32ATo16( call_window_proc16, hwnd, msg, wParam, lParam, &result, proc->proc16 );
3136 /**********************************************************************
3137 * CallWindowProcW (USER32.@)
3139 * See CallWindowProcA.
3141 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
3142 WPARAM wParam, LPARAM lParam )
3147 if (!func) return 0;
3149 if (!(proc = handle_to_proc( func )))
3150 call_window_proc( hwnd, msg, wParam, lParam, &result, func );
3151 else if (proc->procW)
3152 call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procW );
3153 else if (proc->procA)
3154 WINPROC_CallProcWtoA( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procA );
3156 WINPROC_CallProc32WTo16( call_window_proc16, hwnd, msg, wParam, lParam, &result, proc->proc16 );
3161 /**********************************************************************
3162 * WINPROC_CallDlgProc16
3164 INT_PTR WINPROC_CallDlgProc16( DLGPROC16 func, HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
3170 if (!func) return 0;
3172 if (!(proc = handle16_to_proc( (WNDPROC16)func )))
3174 ret = call_dialog_proc16( hwnd, msg, wParam, lParam, &result, func );
3176 else if (proc->procA)
3178 ret = WINPROC_CallProc16To32A( call_dialog_proc, hwnd, msg, wParam, lParam,
3179 &result, proc->procA );
3180 SetWindowLongPtrW( WIN_Handle32(hwnd), DWLP_MSGRESULT, result );
3182 else if (proc->procW)
3184 ret = WINPROC_CallProc16To32W( call_dialog_proc, hwnd, msg, wParam, lParam,
3185 &result, proc->procW );
3186 SetWindowLongPtrW( WIN_Handle32(hwnd), DWLP_MSGRESULT, result );
3190 ret = call_dialog_proc16( hwnd, msg, wParam, lParam, &result, proc->proc16 );
3196 /**********************************************************************
3197 * WINPROC_CallDlgProcA
3199 INT_PTR WINPROC_CallDlgProcA( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
3205 if (!func) return 0;
3207 if (!(proc = handle_to_proc( (WNDPROC)func )))
3208 ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, func );
3209 else if (proc->procA)
3210 ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
3211 else if (proc->procW)
3213 ret = WINPROC_CallProcAtoW( call_dialog_proc, hwnd, msg, wParam, lParam, &result, proc->procW );
3214 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result );
3218 ret = WINPROC_CallProc32ATo16( call_dialog_proc16, hwnd, msg, wParam, lParam, &result, proc->proc16 );
3219 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result );
3225 /**********************************************************************
3226 * WINPROC_CallDlgProcW
3228 INT_PTR WINPROC_CallDlgProcW( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
3234 if (!func) return 0;
3236 if (!(proc = handle_to_proc( (WNDPROC)func )))
3237 ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, func );
3238 else if (proc->procW)
3239 ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procW );
3240 else if (proc->procA)
3242 ret = WINPROC_CallProcWtoA( call_dialog_proc, hwnd, msg, wParam, lParam, &result, proc->procA );
3243 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result );
3247 ret = WINPROC_CallProc32WTo16( call_dialog_proc16, hwnd, msg, wParam, lParam, &result, proc->proc16 );
3248 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result );