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 /* find an existing winproc for a given 16-bit function and type */
71 /* FIXME: probably should do something more clever than a linear search */
72 static inline WINDOWPROC *find_winproc16( WNDPROC16 func )
76 for (i = 0; i < winproc_used; i++)
78 if (winproc_array[i].proc16 == func) return &winproc_array[i];
83 /* find an existing winproc for a given function and type */
84 /* FIXME: probably should do something more clever than a linear search */
85 static inline WINDOWPROC *find_winproc( WNDPROC funcA, WNDPROC funcW )
89 for (i = 0; i < winproc_used; i++)
91 if (funcA && winproc_array[i].procA != funcA) continue;
92 if (funcW && winproc_array[i].procW != funcW) continue;
93 return &winproc_array[i];
98 /* return the window proc for a given handle, or NULL for an invalid handle */
99 static inline WINDOWPROC *handle_to_proc( WNDPROC handle )
101 UINT index = LOWORD(handle);
102 if ((ULONG_PTR)handle >> 16 != WINPROC_HANDLE) return NULL;
103 if (index >= winproc_used) return NULL;
104 return &winproc_array[index];
107 /* create a handle for a given window proc */
108 static inline WNDPROC proc_to_handle( WINDOWPROC *proc )
110 return (WNDPROC)(ULONG_PTR)((proc - winproc_array) | (WINPROC_HANDLE << 16));
113 /* allocate and initialize a new winproc */
114 static inline WINDOWPROC *alloc_winproc( WNDPROC funcA, WNDPROC funcW )
118 /* check if the function is already a win proc */
119 if (funcA && (proc = handle_to_proc( funcA ))) return proc;
120 if (funcW && (proc = handle_to_proc( funcW ))) return proc;
121 if (!funcA && !funcW) return NULL;
123 EnterCriticalSection( &winproc_cs );
125 /* check if we already have a winproc for that function */
126 if (!(proc = find_winproc( funcA, funcW )))
128 if (winproc_used < MAX_WINPROCS)
130 proc = &winproc_array[winproc_used++];
133 TRACE( "allocated %p for %p/%p (%d/%d used)\n",
134 proc_to_handle(proc), funcA, funcW, winproc_used, MAX_WINPROCS );
136 else FIXME( "too many winprocs, cannot allocate one for %p/%p\n", funcA, funcW );
138 else TRACE( "reusing %p for %p/%p\n", proc_to_handle(proc), funcA, funcW );
140 LeaveCriticalSection( &winproc_cs );
147 #include "pshpack1.h"
149 /* Window procedure 16-to-32-bit thunk */
152 BYTE popl_eax; /* popl %eax (return address) */
153 BYTE pushl_func; /* pushl $proc */
155 BYTE pushl_eax; /* pushl %eax */
156 BYTE ljmp; /* ljmp relay*/
157 DWORD relay_offset; /* __wine_call_wndproc */
163 #define MAX_THUNKS (0x10000 / sizeof(WINPROC_THUNK))
165 static WINPROC_THUNK *thunk_array;
166 static UINT thunk_selector;
167 static UINT thunk_used;
169 /* return the window proc for a given handle, or NULL for an invalid handle */
170 static inline WINDOWPROC *handle16_to_proc( WNDPROC16 handle )
172 if (HIWORD(handle) == thunk_selector)
174 UINT index = LOWORD(handle) / sizeof(WINPROC_THUNK);
175 /* check alignment */
176 if (index * sizeof(WINPROC_THUNK) != LOWORD(handle)) return NULL;
177 /* check array limits */
178 if (index >= thunk_used) return NULL;
179 return thunk_array[index].proc;
181 return handle_to_proc( (WNDPROC)handle );
184 /* allocate a 16-bit thunk for an existing window proc */
185 static WNDPROC16 alloc_win16_thunk( WINDOWPROC *proc )
187 static FARPROC16 relay;
190 if (proc->proc16) return proc->proc16;
192 EnterCriticalSection( &winproc_cs );
194 if (!thunk_array) /* allocate the array and its selector */
198 if (!(thunk_selector = wine_ldt_alloc_entries(1))) goto done;
199 if (!(thunk_array = VirtualAlloc( NULL, MAX_THUNKS * sizeof(WINPROC_THUNK), MEM_COMMIT,
200 PAGE_EXECUTE_READWRITE ))) goto done;
201 wine_ldt_set_base( &entry, thunk_array );
202 wine_ldt_set_limit( &entry, MAX_THUNKS * sizeof(WINPROC_THUNK) - 1 );
203 wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT );
204 wine_ldt_set_entry( thunk_selector, &entry );
205 relay = GetProcAddress16( GetModuleHandle16("user"), "__wine_call_wndproc" );
208 /* check if it already exists */
209 for (i = 0; i < thunk_used; i++) if (thunk_array[i].proc == proc) break;
211 if (i == thunk_used) /* create a new one */
213 WINPROC_THUNK *thunk;
215 if (thunk_used >= MAX_THUNKS) goto done;
216 thunk = &thunk_array[thunk_used++];
217 thunk->popl_eax = 0x58; /* popl %eax */
218 thunk->pushl_func = 0x68; /* pushl $proc */
220 thunk->pushl_eax = 0x50; /* pushl %eax */
221 thunk->ljmp = 0xea; /* ljmp relay*/
222 thunk->relay_offset = OFFSETOF(relay);
223 thunk->relay_sel = SELECTOROF(relay);
225 proc->proc16 = (WNDPROC16)MAKESEGPTR( thunk_selector, i * sizeof(WINPROC_THUNK) );
227 LeaveCriticalSection( &winproc_cs );
233 static inline WINDOWPROC *handle16_to_proc( WNDPROC16 handle )
235 return handle_to_proc( (WNDPROC)handle );
238 static inline WNDPROC16 alloc_win16_thunk( WINDOWPROC *proc )
243 #endif /* __i386__ */
247 /* Some window procedures modify register they shouldn't, or are not
248 * properly declared stdcall; so we need a small assembly wrapper to
250 extern LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
251 WPARAM wParam, LPARAM lParam );
252 __ASM_GLOBAL_FUNC( WINPROC_wrapper,
263 "movl 8(%ebp),%eax\n\t"
265 "leal -12(%ebp),%esp\n\t"
272 static inline LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
273 WPARAM wParam, LPARAM lParam )
275 return proc( hwnd, msg, wParam, lParam );
277 #endif /* __i386__ */
280 static void MINMAXINFO32to16( const MINMAXINFO *from, MINMAXINFO16 *to )
282 to->ptReserved.x = from->ptReserved.x;
283 to->ptReserved.y = from->ptReserved.y;
284 to->ptMaxSize.x = from->ptMaxSize.x;
285 to->ptMaxSize.y = from->ptMaxSize.y;
286 to->ptMaxPosition.x = from->ptMaxPosition.x;
287 to->ptMaxPosition.y = from->ptMaxPosition.y;
288 to->ptMinTrackSize.x = from->ptMinTrackSize.x;
289 to->ptMinTrackSize.y = from->ptMinTrackSize.y;
290 to->ptMaxTrackSize.x = from->ptMaxTrackSize.x;
291 to->ptMaxTrackSize.y = from->ptMaxTrackSize.y;
294 static void MINMAXINFO16to32( const MINMAXINFO16 *from, MINMAXINFO *to )
296 to->ptReserved.x = from->ptReserved.x;
297 to->ptReserved.y = from->ptReserved.y;
298 to->ptMaxSize.x = from->ptMaxSize.x;
299 to->ptMaxSize.y = from->ptMaxSize.y;
300 to->ptMaxPosition.x = from->ptMaxPosition.x;
301 to->ptMaxPosition.y = from->ptMaxPosition.y;
302 to->ptMinTrackSize.x = from->ptMinTrackSize.x;
303 to->ptMinTrackSize.y = from->ptMinTrackSize.y;
304 to->ptMaxTrackSize.x = from->ptMaxTrackSize.x;
305 to->ptMaxTrackSize.y = from->ptMaxTrackSize.y;
308 static void WINDOWPOS32to16( const WINDOWPOS* from, WINDOWPOS16* to )
310 to->hwnd = HWND_16(from->hwnd);
311 to->hwndInsertAfter = HWND_16(from->hwndInsertAfter);
316 to->flags = from->flags;
319 static void WINDOWPOS16to32( const WINDOWPOS16* from, WINDOWPOS* to )
321 to->hwnd = WIN_Handle32(from->hwnd);
322 to->hwndInsertAfter = (from->hwndInsertAfter == (HWND16)-1) ?
323 HWND_TOPMOST : WIN_Handle32(from->hwndInsertAfter);
328 to->flags = from->flags;
331 /* The strings are not copied */
332 static void CREATESTRUCT32Ato16( const CREATESTRUCTA* from, CREATESTRUCT16* to )
334 to->lpCreateParams = (SEGPTR)from->lpCreateParams;
335 to->hInstance = HINSTANCE_16(from->hInstance);
336 to->hMenu = HMENU_16(from->hMenu);
337 to->hwndParent = HWND_16(from->hwndParent);
342 to->style = from->style;
343 to->dwExStyle = from->dwExStyle;
346 static void CREATESTRUCT16to32A( const CREATESTRUCT16* from, CREATESTRUCTA *to )
349 to->lpCreateParams = (LPVOID)from->lpCreateParams;
350 to->hInstance = HINSTANCE_32(from->hInstance);
351 to->hMenu = HMENU_32(from->hMenu);
352 to->hwndParent = WIN_Handle32(from->hwndParent);
357 to->style = from->style;
358 to->dwExStyle = from->dwExStyle;
361 /* The strings are not copied */
362 static void MDICREATESTRUCT32Ato16( const MDICREATESTRUCTA* from, MDICREATESTRUCT16* to )
364 to->hOwner = HINSTANCE_16(from->hOwner);
369 to->style = from->style;
370 to->lParam = from->lParam;
373 static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16* from, MDICREATESTRUCTA *to )
375 to->hOwner = HINSTANCE_32(from->hOwner);
380 to->style = from->style;
381 to->lParam = from->lParam;
384 /**********************************************************************
385 * WINPROC_CallWndProc32
387 * Call a 32-bit WndProc.
389 static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
390 WPARAM wParam, LPARAM lParam )
396 hwnd = WIN_GetFullHandle( hwnd );
398 DPRINTF( "%04lx:Call window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
399 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam );
401 retvalue = WINPROC_wrapper( proc, hwnd, msg, wParam, lParam );
404 DPRINTF( "%04lx:Ret window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
405 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam, retvalue );
409 /***********************************************************************
410 * WINPROC_CallWndProc16
412 * Call a 16-bit window procedure
414 static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
415 UINT16 msg, WPARAM16 wParam,
426 DRAWITEMSTRUCT16 dis16;
427 COMPAREITEMSTRUCT16 cis16;
433 /* Window procedures want ax = hInstance, ds = es = ss */
435 memset(&context, 0, sizeof(context));
436 context.SegDs = context.SegEs = SELECTOROF(NtCurrentTeb()->WOW32Reserved);
437 context.SegFs = wine_get_fs();
438 context.SegGs = wine_get_gs();
439 if (!(context.Eax = GetWindowWord( HWND_32(hwnd), GWLP_HINSTANCE ))) context.Eax = context.SegDs;
440 context.SegCs = SELECTOROF(proc);
441 context.Eip = OFFSETOF(proc);
442 context.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + (WORD)&((STACK16FRAME*)0)->bp;
446 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
447 work if structures passed in lParam are placed in the stack/data
448 segment. Programmers easily make the mistake of converting lParam
449 to a near rather than a far pointer, since Windows apparently
450 allows this. We copy the structures to the 16 bit stack; this is
451 ugly but makes these programs work. */
456 size = sizeof(CREATESTRUCT16); break;
458 size = sizeof(DRAWITEMSTRUCT16); break;
460 size = sizeof(COMPAREITEMSTRUCT16); break;
464 memcpy( &args.u, MapSL(lParam), size );
465 lParam = (SEGPTR)NtCurrentTeb()->WOW32Reserved - size;
469 args.params[4] = hwnd;
470 args.params[3] = msg;
471 args.params[2] = wParam;
472 args.params[1] = HIWORD(lParam);
473 args.params[0] = LOWORD(lParam);
474 WOWCallback16Ex( 0, WCB16_REGS, sizeof(args.params) + size, &args, (DWORD *)&context );
475 return MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) );
479 /**********************************************************************
482 * Get a window procedure pointer that can be passed to the Windows program.
484 WNDPROC16 WINPROC_GetProc16( WNDPROC proc, BOOL unicode )
488 if (unicode) ptr = alloc_winproc( NULL, proc );
489 else ptr = alloc_winproc( proc, NULL );
492 return alloc_win16_thunk( ptr );
496 /**********************************************************************
499 * Get a window procedure pointer that can be passed to the Windows program.
501 WNDPROC WINPROC_GetProc( WNDPROC proc, BOOL unicode )
503 WINDOWPROC *ptr = handle_to_proc( proc );
505 if (!ptr) return proc;
508 if (ptr->procW) return ptr->procW;
513 if (ptr->procA) return ptr->procA;
519 /**********************************************************************
520 * WINPROC_AllocProc16
522 * Allocate a window procedure for a window or class.
524 * Note that allocated winprocs are never freed; the idea is that even if an app creates a
525 * lot of windows, it will usually only have a limited number of window procedures, so the
526 * array won't grow too large, and this way we avoid the need to track allocations per window.
528 WNDPROC WINPROC_AllocProc16( WNDPROC16 func )
532 if (!func) return NULL;
534 /* check if the function is already a win proc */
535 if (!(proc = handle16_to_proc( func )))
537 EnterCriticalSection( &winproc_cs );
539 /* then check if we already have a winproc for that function */
540 if (!(proc = find_winproc16( func )))
542 if (winproc_used < MAX_WINPROCS)
544 proc = &winproc_array[winproc_used++];
546 TRACE( "allocated %p for %p/16-bit (%d/%d used)\n",
547 proc_to_handle(proc), func, winproc_used, MAX_WINPROCS );
549 else FIXME( "too many winprocs, cannot allocate one for 16-bit %p\n", func );
551 else TRACE( "reusing %p for %p/16-bit\n", proc_to_handle(proc), func );
553 LeaveCriticalSection( &winproc_cs );
555 return proc_to_handle( proc );
559 /**********************************************************************
562 * Allocate a window procedure for a window or class.
564 * Note that allocated winprocs are never freed; the idea is that even if an app creates a
565 * lot of windows, it will usually only have a limited number of window procedures, so the
566 * array won't grow too large, and this way we avoid the need to track allocations per window.
568 WNDPROC WINPROC_AllocProc( WNDPROC funcA, WNDPROC funcW )
572 if (!(proc = alloc_winproc( funcA, funcW ))) return NULL;
573 return proc_to_handle( proc );
577 /**********************************************************************
580 * Return the window procedure type, or the default value if not a winproc handle.
582 BOOL WINPROC_IsUnicode( WNDPROC proc, BOOL def_val )
584 WINDOWPROC *ptr = handle_to_proc( proc );
586 if (!ptr) return def_val;
587 if (ptr->procA && ptr->procW) return def_val; /* can be both */
588 return (ptr->procW != NULL);
592 /**********************************************************************
593 * WINPROC_TestCBForStr
595 * Return TRUE if the lparam is a string
597 inline static BOOL WINPROC_TestCBForStr( HWND hwnd )
599 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
600 return (!(style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) || (style & CBS_HASSTRINGS));
602 /**********************************************************************
603 * WINPROC_TestLBForStr
605 * Return TRUE if the lparam is a string
607 inline static BOOL WINPROC_TestLBForStr( HWND hwnd )
609 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
610 return (!(style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) || (style & LBS_HASSTRINGS));
613 /**********************************************************************
614 * WINPROC_MapMsg32ATo32W
616 * Map a message from Ansi to Unicode.
617 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
620 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
621 * the first four bytes are the handle of the icon
622 * when the WM_SETTEXT message has been used to set the icon
624 INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
629 case WM_ASKCBFORMATNAME:
631 LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0,
632 *pwparam * sizeof(WCHAR) + sizeof(LPARAM) );
634 *ptr++ = *plparam; /* Store previous lParam */
635 *plparam = (LPARAM)ptr;
638 /* lparam is string (0-terminated) */
640 case WM_WININICHANGE:
641 case WM_DEVMODECHANGE:
646 if (!*plparam) return 0;
649 DWORD len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)*plparam, -1, NULL, 0);
650 WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
651 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)*plparam, -1, buf, len);
652 *plparam = (LPARAM)buf;
653 return (*plparam ? 1 : -1);
655 case WM_GETTEXTLENGTH:
656 case CB_GETLBTEXTLEN:
658 return 1; /* need to map result */
662 UNICODE_STRING usBuffer;
664 { CREATESTRUCTW cs; /* new structure */
665 LPCWSTR lpszName; /* allocated Name */
666 LPCWSTR lpszClass; /* allocated Class */
669 struct s *xs = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct s));
671 xs->cs = *(CREATESTRUCTW *)*plparam;
672 if (HIWORD(xs->cs.lpszName))
674 RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)xs->cs.lpszName);
675 xs->lpszName = xs->cs.lpszName = usBuffer.Buffer;
677 if (HIWORD(xs->cs.lpszClass))
679 RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)xs->cs.lpszClass);
680 xs->lpszClass = xs->cs.lpszClass = usBuffer.Buffer;
683 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
685 MDICREATESTRUCTW *mdi_cs = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs));
686 *mdi_cs = *(MDICREATESTRUCTW *)xs->cs.lpCreateParams;
687 if (HIWORD(mdi_cs->szTitle))
689 RtlCreateUnicodeStringFromAsciiz(&usBuffer, (LPCSTR)mdi_cs->szTitle);
690 mdi_cs->szTitle = usBuffer.Buffer;
692 if (HIWORD(mdi_cs->szClass))
694 RtlCreateUnicodeStringFromAsciiz(&usBuffer, (LPCSTR)mdi_cs->szClass);
695 mdi_cs->szClass = usBuffer.Buffer;
697 xs->cs.lpCreateParams = mdi_cs;
700 *plparam = (LPARAM)xs;
705 MDICREATESTRUCTW *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
707 *cs = *(MDICREATESTRUCTW *)*plparam;
708 if (HIWORD(cs->szClass))
710 UNICODE_STRING usBuffer;
711 RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)cs->szClass);
712 cs->szClass = usBuffer.Buffer;
714 if (HIWORD(cs->szTitle))
716 UNICODE_STRING usBuffer;
717 RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)cs->szTitle);
718 cs->szTitle = usBuffer.Buffer;
720 *plparam = (LPARAM)cs;
726 case LB_INSERTSTRING:
728 case LB_FINDSTRINGEXACT:
729 case LB_SELECTSTRING:
730 if(!*plparam) return 0;
731 if ( WINPROC_TestLBForStr( hwnd ))
733 UNICODE_STRING usBuffer;
734 RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)*plparam);
735 *plparam = (LPARAM)usBuffer.Buffer;
737 return (*plparam ? 1 : -1);
739 case LB_GETTEXT: /* FIXME: fixed sized buffer */
740 { if ( WINPROC_TestLBForStr( hwnd ))
741 { LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0, 512 * sizeof(WCHAR) + sizeof(LPARAM) );
743 *ptr++ = *plparam; /* Store previous lParam */
744 *plparam = (LPARAM)ptr;
751 case CB_INSERTSTRING:
752 case CB_FINDSTRINGEXACT:
754 case CB_SELECTSTRING:
755 if(!*plparam) return 0;
756 if ( WINPROC_TestCBForStr( hwnd ))
758 UNICODE_STRING usBuffer;
759 RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)*plparam);
760 *plparam = (LPARAM)usBuffer.Buffer;
762 return (*plparam ? 1 : -1);
764 case CB_GETLBTEXT: /* FIXME: fixed sized buffer */
765 { if ( WINPROC_TestCBForStr( hwnd ))
766 { LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0, 512 * sizeof(WCHAR) + sizeof(LPARAM) );
768 *ptr++ = *plparam; /* Store previous lParam */
769 *plparam = (LPARAM)ptr;
776 { WORD len = (WORD)*plparam;
777 LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
779 *ptr++ = *plparam; /* Store previous lParam */
780 *((WORD *) ptr) = len; /* Store the length */
781 *plparam = (LPARAM)ptr;
791 case EM_SETPASSWORDCHAR:
793 CHAR ch = LOWORD(*pwparam);
795 MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1);
796 *pwparam = MAKEWPARAM( wch, HIWORD(*pwparam) );
804 ch[0] = (*pwparam >> 8);
805 ch[1] = *pwparam & 0xff;
807 MultiByteToWideChar(CP_ACP, 0, ch, 2, &wch, 1);
809 MultiByteToWideChar(CP_ACP, 0, &ch[1], 1, &wch, 1);
810 *pwparam = MAKEWPARAM( wch, HIWORD(*pwparam) );
814 case WM_PAINTCLIPBOARD:
815 case WM_SIZECLIPBOARD:
816 FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg, hwnd), msg );
818 default: /* No translation needed */
824 /**********************************************************************
825 * WINPROC_UnmapMsg32ATo32W
827 * Unmap a message that was mapped from Ansi to Unicode.
829 LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
830 LRESULT result, WNDPROC dispatch )
835 case WM_ASKCBFORMATNAME:
837 LPARAM *ptr = (LPARAM *)lParam - 1;
838 if (!wParam) result = 0;
839 else if (!(result = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
840 (LPSTR)*ptr, wParam, NULL, NULL )))
842 ((LPSTR)*ptr)[wParam-1] = 0;
845 else result--; /* do not count terminating null */
846 HeapFree( GetProcessHeap(), 0, ptr );
849 case WM_GETTEXTLENGTH:
850 case CB_GETLBTEXTLEN:
854 /* Determine respective GETTEXT message */
856 (msg == WM_GETTEXTLENGTH) ? WM_GETTEXT :
857 ((msg == CB_GETLBTEXTLEN) ? CB_GETLBTEXT : LB_GETTEXT);
858 /* wParam differs between the messages */
859 WPARAM wp = (msg == WM_GETTEXTLENGTH) ? (WPARAM)(result + 1) : wParam;
861 WCHAR* p = HeapAlloc (GetProcessHeap(), 0, (result + 1) * sizeof(WCHAR));
868 n = WINPROC_CallWndProc(dispatch, hwnd, msgGetText, wp, (LPARAM)p);
870 n = SendMessageW (hwnd, msgGetText, wp, (LPARAM)p);
872 result = WideCharToMultiByte( CP_ACP, 0, p, n, NULL, 0, 0, NULL );
873 HeapFree (GetProcessHeap(), 0, p);
881 { CREATESTRUCTW cs; /* new structure */
882 LPWSTR lpszName; /* allocated Name */
883 LPWSTR lpszClass; /* allocated Class */
885 struct s *xs = (struct s *)lParam;
886 HeapFree( GetProcessHeap(), 0, xs->lpszName );
887 HeapFree( GetProcessHeap(), 0, xs->lpszClass );
889 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
891 MDICREATESTRUCTW *mdi_cs = (MDICREATESTRUCTW *)xs->cs.lpCreateParams;
892 if (HIWORD(mdi_cs->szTitle))
893 HeapFree(GetProcessHeap(), 0, (LPVOID)mdi_cs->szTitle);
894 if (HIWORD(mdi_cs->szClass))
895 HeapFree(GetProcessHeap(), 0, (LPVOID)mdi_cs->szClass);
896 HeapFree(GetProcessHeap(), 0, mdi_cs);
898 HeapFree( GetProcessHeap(), 0, xs );
904 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
905 if (HIWORD(cs->szTitle))
906 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
907 if (HIWORD(cs->szClass))
908 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
909 HeapFree( GetProcessHeap(), 0, cs );
914 case WM_WININICHANGE:
915 case WM_DEVMODECHANGE:
920 HeapFree( GetProcessHeap(), 0, (void *)lParam );
925 case LB_INSERTSTRING:
927 case LB_FINDSTRINGEXACT:
928 case LB_SELECTSTRING:
929 if ( WINPROC_TestLBForStr( hwnd ))
930 HeapFree( GetProcessHeap(), 0, (void *)lParam );
934 if ( WINPROC_TestLBForStr( hwnd ))
936 LPARAM *ptr = (LPARAM *)lParam - 1;
938 result = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
939 (LPSTR)*ptr, 0x7fffffff, NULL, NULL ) - 1;
940 HeapFree( GetProcessHeap(), 0, ptr );
946 case CB_INSERTSTRING:
948 case CB_FINDSTRINGEXACT:
949 case CB_SELECTSTRING:
950 if ( WINPROC_TestCBForStr( hwnd ))
951 HeapFree( GetProcessHeap(), 0, (void *)lParam );
955 if ( result < 0) /* CB_ERR and CB_ERRSPACE */
957 LPARAM *ptr = (LPARAM *)lParam - 1;
958 HeapFree( GetProcessHeap(), 0, ptr );
960 else if ( WINPROC_TestCBForStr( hwnd ))
962 LPARAM *ptr = (LPARAM *)lParam - 1;
963 result = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
964 (LPSTR)*ptr, 0x7fffffff, NULL, NULL ) - 1;
965 HeapFree( GetProcessHeap(), 0, ptr );
972 LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
973 WORD len = *(WORD *) lParam;
974 result = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, result,
975 (LPSTR)*ptr, len, NULL, NULL );
976 if (result < len) ((LPSTR)*ptr)[result] = 0;
977 HeapFree( GetProcessHeap(), 0, ptr );
985 /**********************************************************************
986 * WINPROC_MapMsg32WTo32A
988 * Map a message from Unicode to Ansi.
989 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
991 static INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
996 case LB_GETTEXT: /* FIXME: fixed sized buffer */
997 { if ( WINPROC_TestLBForStr( hwnd ))
998 { LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0, 512 + sizeof(LPARAM) );
1000 *ptr++ = *plparam; /* Store previous lParam */
1001 *plparam = (LPARAM)ptr;
1007 case CB_GETLBTEXT: /* FIXME: fixed sized buffer */
1008 { if ( WINPROC_TestCBForStr( hwnd ))
1009 { LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0, 512 + sizeof(LPARAM) );
1010 if (!ptr) return -1;
1011 *ptr++ = *plparam; /* Store previous lParam */
1012 *plparam = (LPARAM)ptr;
1017 /* Multiline edit */
1019 { WORD len = (WORD)*plparam;
1020 LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
1021 if (!ptr) return -1;
1022 *ptr++ = *plparam; /* Store previous lParam */
1023 *((WORD *) ptr) = len; /* Store the length */
1024 *plparam = (LPARAM)ptr;
1033 case WM_SYSDEADCHAR:
1034 case EM_SETPASSWORDCHAR:
1036 WCHAR wch = LOWORD(*pwparam);
1038 WideCharToMultiByte( CP_ACP, 0, &wch, 1, (LPSTR)&ch, 1, NULL, NULL );
1039 *pwparam = MAKEWPARAM( ch, HIWORD(*pwparam) );
1045 WCHAR wch = LOWORD(*pwparam);
1048 if (WideCharToMultiByte( CP_ACP, 0, &wch, 1, (LPSTR)ch, 2, NULL, NULL ) == 2)
1049 *pwparam = MAKEWPARAM( (ch[0] << 8) | ch[1], HIWORD(*pwparam) );
1051 *pwparam = MAKEWPARAM( ch[0], HIWORD(*pwparam) );
1055 case WM_PAINTCLIPBOARD:
1056 case WM_SIZECLIPBOARD:
1057 FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg, hwnd),msg );
1059 default: /* No translation needed */
1065 /**********************************************************************
1066 * WINPROC_UnmapMsg32WTo32A
1068 * Unmap a message that was mapped from Unicode to Ansi.
1070 static LRESULT WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT result )
1076 if ( WINPROC_TestLBForStr( hwnd ))
1078 LPARAM *ptr = (LPARAM *)lParam - 1;
1080 result = MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, 0x7fffffff ) - 1;
1081 HeapFree( GetProcessHeap(), 0, ptr );
1087 if ( result < 0) /* CB_ERR and CB_ERRSPACE */
1089 LPARAM *ptr = (LPARAM *)lParam - 1;
1090 HeapFree( GetProcessHeap(), 0, ptr );
1092 else if ( WINPROC_TestCBForStr( hwnd ))
1094 LPARAM *ptr = (LPARAM *)lParam - 1;
1095 result = MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, 0x7fffffff ) - 1;
1096 HeapFree( GetProcessHeap(), 0, ptr );
1100 /* Multiline edit */
1103 LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lparam */
1104 WORD len = *(WORD *)ptr;
1107 result = MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, result, (LPWSTR)*ptr, len );
1108 if (result < len) ((LPWSTR)*ptr)[result] = 0;
1110 HeapFree( GetProcessHeap(), 0, ptr );
1117 static UINT convert_handle_16_to_32(HANDLE16 src, unsigned int flags)
1120 UINT sz = GlobalSize16(src);
1123 if (!(dst = GlobalAlloc(flags, sz)))
1125 ptr16 = GlobalLock16(src);
1126 ptr32 = GlobalLock(dst);
1127 if (ptr16 != NULL && ptr32 != NULL) memcpy(ptr32, ptr16, sz);
1128 GlobalUnlock16(src);
1134 /**********************************************************************
1135 * WINPROC_MapMsg16To32A
1137 * Map a message from 16- to 32-bit Ansi.
1138 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1140 INT WINPROC_MapMsg16To32A( HWND hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1141 WPARAM *pwparam32, LPARAM *plparam )
1143 *pmsg32 = (UINT)msg16;
1144 *pwparam32 = (WPARAM)wParam16;
1151 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1152 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1156 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1157 *plparam = (LPARAM)WIN_Handle32( HIWORD(*plparam) );
1160 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
1161 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
1162 *pwparam32 = (WPARAM)HDC_32(wParam16);
1163 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1165 case WM_COMPAREITEM:
1167 COMPAREITEMSTRUCT16* cis16 = MapSL(*plparam);
1168 COMPAREITEMSTRUCT *cis = HeapAlloc(GetProcessHeap(), 0, sizeof(*cis));
1169 if (!cis) return -1;
1170 cis->CtlType = cis16->CtlType;
1171 cis->CtlID = cis16->CtlID;
1172 cis->hwndItem = WIN_Handle32( cis16->hwndItem );
1173 cis->itemID1 = cis16->itemID1;
1174 cis->itemData1 = cis16->itemData1;
1175 cis->itemID2 = cis16->itemID2;
1176 cis->itemData2 = cis16->itemData2;
1177 cis->dwLocaleId = 0; /* FIXME */
1178 *plparam = (LPARAM)cis;
1183 PCOPYDATASTRUCT16 pcds16 = MapSL(*plparam);
1184 PCOPYDATASTRUCT pcds = HeapAlloc ( GetProcessHeap(), 0, sizeof(*pcds));
1185 pcds->dwData = pcds16->dwData;
1186 pcds->cbData = pcds16->cbData;
1187 pcds->lpData = MapSL( pcds16->lpData);
1188 *plparam = (LPARAM)pcds;
1193 DELETEITEMSTRUCT16* dis16 = MapSL(*plparam);
1194 DELETEITEMSTRUCT *dis = HeapAlloc(GetProcessHeap(), 0, sizeof(*dis));
1195 if (!dis) return -1;
1196 dis->CtlType = dis16->CtlType;
1197 dis->CtlID = dis16->CtlID;
1198 dis->hwndItem = WIN_Handle32( dis16->hwndItem );
1199 dis->itemData = dis16->itemData;
1200 *plparam = (LPARAM)dis;
1203 case WM_MEASUREITEM:
1205 MEASUREITEMSTRUCT16* mis16 = MapSL(*plparam);
1206 MEASUREITEMSTRUCT *mis = HeapAlloc(GetProcessHeap(), 0,
1207 sizeof(*mis) + sizeof(LPARAM));
1208 if (!mis) return -1;
1209 mis->CtlType = mis16->CtlType;
1210 mis->CtlID = mis16->CtlID;
1211 mis->itemID = mis16->itemID;
1212 mis->itemWidth = mis16->itemWidth;
1213 mis->itemHeight = mis16->itemHeight;
1214 mis->itemData = mis16->itemData;
1215 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1216 *plparam = (LPARAM)mis;
1221 DRAWITEMSTRUCT16* dis16 = MapSL(*plparam);
1222 DRAWITEMSTRUCT *dis = HeapAlloc(GetProcessHeap(), 0, sizeof(*dis));
1223 if (!dis) return -1;
1224 dis->CtlType = dis16->CtlType;
1225 dis->CtlID = dis16->CtlID;
1226 dis->itemID = dis16->itemID;
1227 dis->itemAction = dis16->itemAction;
1228 dis->itemState = dis16->itemState;
1229 dis->hwndItem = (dis->CtlType == ODT_MENU) ? (HWND)HMENU_32(dis16->hwndItem)
1230 : WIN_Handle32( dis16->hwndItem );
1231 dis->hDC = HDC_32(dis16->hDC);
1232 dis->itemData = dis16->itemData;
1233 dis->rcItem.left = dis16->rcItem.left;
1234 dis->rcItem.top = dis16->rcItem.top;
1235 dis->rcItem.right = dis16->rcItem.right;
1236 dis->rcItem.bottom = dis16->rcItem.bottom;
1237 *plparam = (LPARAM)dis;
1240 case WM_GETMINMAXINFO:
1242 MINMAXINFO *mmi = HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi) + sizeof(LPARAM));
1243 if (!mmi) return -1;
1244 MINMAXINFO16to32( MapSL(*plparam), mmi );
1245 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1246 *plparam = (LPARAM)mmi;
1251 case WM_WININICHANGE:
1252 case WM_DEVMODECHANGE:
1253 case WM_ASKCBFORMATNAME:
1254 *plparam = (LPARAM)MapSL(*plparam);
1258 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1259 MDICREATESTRUCTA *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1261 MDICREATESTRUCT16to32A( cs16, cs );
1262 cs->szTitle = MapSL(cs16->szTitle);
1263 cs->szClass = MapSL(cs16->szClass);
1264 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1265 *plparam = (LPARAM)cs;
1268 case WM_MDIGETACTIVE:
1269 *plparam = (LPARAM)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL) );
1270 *(BOOL*)(*plparam) = 0;
1273 if(wParam16) *pmsg32=WM_MDIREFRESHMENU;
1274 *pwparam32 = (WPARAM)HMENU_32(LOWORD(*plparam));
1275 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1278 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1279 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1282 if((LOWORD(*plparam) & MF_POPUP) && (LOWORD(*plparam) != 0xFFFF))
1284 HMENU hmenu=HMENU_32(HIWORD(*plparam));
1285 UINT Pos=MENU_FindSubMenu( &hmenu, HMENU_32(wParam16));
1286 if(Pos==0xFFFF) Pos=0; /* NO_SELECTED_ITEM */
1287 *pwparam32 = MAKEWPARAM( Pos, LOWORD(*plparam) );
1289 else *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1290 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1292 case WM_MDIACTIVATE:
1295 *pwparam32 = (WPARAM)WIN_Handle32( HIWORD(*plparam) );
1296 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1298 else /* message sent to MDI client */
1299 *pwparam32 = wParam16;
1303 NCCALCSIZE_PARAMS16 *nc16;
1304 NCCALCSIZE_PARAMS *nc;
1306 nc = HeapAlloc( GetProcessHeap(), 0, sizeof(*nc) + sizeof(LPARAM) );
1308 nc16 = MapSL(*plparam);
1309 nc->rgrc[0].left = nc16->rgrc[0].left;
1310 nc->rgrc[0].top = nc16->rgrc[0].top;
1311 nc->rgrc[0].right = nc16->rgrc[0].right;
1312 nc->rgrc[0].bottom = nc16->rgrc[0].bottom;
1315 nc->lppos = HeapAlloc( GetProcessHeap(), 0, sizeof(*nc->lppos) );
1316 nc->rgrc[1].left = nc16->rgrc[1].left;
1317 nc->rgrc[1].top = nc16->rgrc[1].top;
1318 nc->rgrc[1].right = nc16->rgrc[1].right;
1319 nc->rgrc[1].bottom = nc16->rgrc[1].bottom;
1320 nc->rgrc[2].left = nc16->rgrc[2].left;
1321 nc->rgrc[2].top = nc16->rgrc[2].top;
1322 nc->rgrc[2].right = nc16->rgrc[2].right;
1323 nc->rgrc[2].bottom = nc16->rgrc[2].bottom;
1324 if (nc->lppos) WINDOWPOS16to32( MapSL(nc16->lppos), nc->lppos );
1326 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1327 *plparam = (LPARAM)nc;
1333 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1334 CREATESTRUCTA *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1336 CREATESTRUCT16to32A( cs16, cs );
1337 cs->lpszName = MapSL(cs16->lpszName);
1338 cs->lpszClass = MapSL(cs16->lpszClass);
1340 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1342 MDICREATESTRUCT16 *mdi_cs16;
1343 MDICREATESTRUCTA *mdi_cs = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs));
1346 HeapFree(GetProcessHeap(), 0, cs);
1349 mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs16->lpCreateParams);
1350 MDICREATESTRUCT16to32A(mdi_cs16, mdi_cs);
1351 mdi_cs->szTitle = MapSL(mdi_cs16->szTitle);
1352 mdi_cs->szClass = MapSL(mdi_cs16->szClass);
1354 cs->lpCreateParams = mdi_cs;
1356 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1357 *plparam = (LPARAM)cs;
1360 case WM_PARENTNOTIFY:
1361 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1363 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1364 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1367 case WM_WINDOWPOSCHANGING:
1368 case WM_WINDOWPOSCHANGED:
1370 WINDOWPOS *wp = HeapAlloc( GetProcessHeap(), 0, sizeof(*wp) + sizeof(LPARAM) );
1372 WINDOWPOS16to32( MapSL(*plparam), wp );
1373 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1374 *plparam = (LPARAM)wp;
1380 LPMSG16 msg16 = MapSL(*plparam);
1381 LPMSG msg32 = HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1383 if (!msg32) return -1;
1384 msg32->hwnd = WIN_Handle32( msg16->hwnd );
1385 msg32->lParam = msg16->lParam;
1386 msg32->time = msg16->time;
1387 msg32->pt.x = msg16->pt.x;
1388 msg32->pt.y = msg16->pt.y;
1389 /* this is right, right? */
1390 if (WINPROC_MapMsg16To32A( msg32->hwnd, msg16->message,msg16->wParam,
1391 &msg32->message,&msg32->wParam,
1392 &msg32->lParam)<0) {
1393 HeapFree( GetProcessHeap(), 0, msg32 );
1396 *plparam = (LPARAM)msg32;
1401 *plparam = (LPARAM)MapSL(*plparam);
1403 case WM_ACTIVATEAPP:
1404 /* We need this when SetActiveWindow sends a Sendmessage16() to
1405 * a 32bit window. Might be superflous with 32bit interprocess
1406 * message queues. */
1407 if (*plparam) *plparam = HTASK_32( *plparam );
1411 MDINEXTMENU *next = HeapAlloc( GetProcessHeap(), 0, sizeof(*next) );
1412 if (!next) return -1;
1413 next->hmenuIn = (HMENU)*plparam;
1414 next->hmenuNext = 0;
1416 *plparam = (LPARAM)next;
1419 case WM_PAINTCLIPBOARD:
1420 case WM_SIZECLIPBOARD:
1421 FIXME_(msg)("message %04x needs translation\n",msg16 );
1423 case WM_DDE_INITIATE:
1424 case WM_DDE_TERMINATE:
1425 case WM_DDE_UNADVISE:
1426 case WM_DDE_REQUEST:
1427 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1437 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1438 lo16 = LOWORD(*plparam);
1439 hi = HIWORD(*plparam);
1440 if (lo16 && !(lo32 = convert_handle_16_to_32(lo16, GMEM_DDESHARE)))
1442 *plparam = PackDDElParam(msg16, lo32, hi);
1444 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1451 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1453 lo = LOWORD(*plparam);
1454 hi = HIWORD(*plparam);
1456 if (GlobalGetAtomNameA(hi, buf, 2) > 0) flag |= 1;
1457 if (GlobalSize16(hi) != 0) flag |= 2;
1463 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1468 break; /* atom, nothing to do */
1470 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi);
1473 hi = convert_handle_16_to_32(hi, GMEM_DDESHARE);
1476 *plparam = PackDDElParam(WM_DDE_ACK, lo, hi);
1478 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1479 case WM_DDE_EXECUTE:
1480 *plparam = convert_handle_16_to_32(*plparam, GMEM_DDESHARE);
1481 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1482 default: /* No translation needed */
1488 /**********************************************************************
1489 * WINPROC_UnmapMsg16To32A
1491 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1493 LRESULT WINPROC_UnmapMsg16To32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1498 case WM_COMPAREITEM:
1502 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
1504 case WM_MEASUREITEM:
1506 MEASUREITEMSTRUCT16 *mis16;
1507 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1508 lParam = *(LPARAM *)(mis + 1);
1509 mis16 = MapSL(lParam);
1510 mis16->itemWidth = (UINT16)mis->itemWidth;
1511 mis16->itemHeight = (UINT16)mis->itemHeight;
1512 HeapFree( GetProcessHeap(), 0, mis );
1515 case WM_GETMINMAXINFO:
1517 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1518 lParam = *(LPARAM *)(mmi + 1);
1519 MINMAXINFO32to16( mmi, MapSL(lParam));
1520 HeapFree( GetProcessHeap(), 0, mmi );
1525 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1526 lParam = *(LPARAM *)(cs + 1);
1527 MDICREATESTRUCT32Ato16( cs, MapSL(lParam) );
1528 HeapFree( GetProcessHeap(), 0, cs );
1531 case WM_MDIGETACTIVE:
1532 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1533 HeapFree( GetProcessHeap(), 0, (BOOL *)lParam );
1537 NCCALCSIZE_PARAMS16 *nc16;
1538 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1539 lParam = *(LPARAM *)(nc + 1);
1540 nc16 = MapSL(lParam);
1541 nc16->rgrc[0].left = nc->rgrc[0].left;
1542 nc16->rgrc[0].top = nc->rgrc[0].top;
1543 nc16->rgrc[0].right = nc->rgrc[0].right;
1544 nc16->rgrc[0].bottom = nc->rgrc[0].bottom;
1547 nc16->rgrc[1].left = nc->rgrc[1].left;
1548 nc16->rgrc[1].top = nc->rgrc[1].top;
1549 nc16->rgrc[1].right = nc->rgrc[1].right;
1550 nc16->rgrc[1].bottom = nc->rgrc[1].bottom;
1551 nc16->rgrc[2].left = nc->rgrc[2].left;
1552 nc16->rgrc[2].top = nc->rgrc[2].top;
1553 nc16->rgrc[2].right = nc->rgrc[2].right;
1554 nc16->rgrc[2].bottom = nc->rgrc[2].bottom;
1557 WINDOWPOS32to16( nc->lppos, MapSL(nc16->lppos));
1558 HeapFree( GetProcessHeap(), 0, nc->lppos );
1561 HeapFree( GetProcessHeap(), 0, nc );
1567 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1568 lParam = *(LPARAM *)(cs + 1);
1569 CREATESTRUCT32Ato16( cs, MapSL(lParam) );
1571 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1572 HeapFree(GetProcessHeap(), 0, cs->lpCreateParams);
1574 HeapFree( GetProcessHeap(), 0, cs );
1577 case WM_WINDOWPOSCHANGING:
1578 case WM_WINDOWPOSCHANGED:
1580 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1581 lParam = *(LPARAM *)(wp + 1);
1582 WINDOWPOS32to16(wp, MapSL(lParam));
1583 HeapFree( GetProcessHeap(), 0, wp );
1589 LPMSG msg32 = (LPMSG)lParam;
1591 WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1593 HeapFree( GetProcessHeap(), 0, msg32 );
1598 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
1599 result = MAKELONG( HMENU_16(next->hmenuNext), HWND_16(next->hwndNext) );
1600 HeapFree( GetProcessHeap(), 0, next );
1608 /**********************************************************************
1609 * WINPROC_MapMsg16To32W
1611 * Map a message from 16- to 32-bit Unicode.
1612 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1614 INT WINPROC_MapMsg16To32W( HWND hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1615 WPARAM *pwparam32, LPARAM *plparam )
1620 *pmsg32=(UINT)msg16;
1621 *pwparam32 = (WPARAM)wParam16;
1626 case WM_WININICHANGE:
1627 case WM_DEVMODECHANGE:
1628 case WM_ASKCBFORMATNAME:
1629 *plparam = (LPARAM)MapSL(*plparam);
1630 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, pwparam32, plparam );
1631 case WM_GETTEXTLENGTH:
1632 case CB_GETLBTEXTLEN:
1634 return 1; /* need to map result */
1638 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1639 CREATESTRUCTW *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1641 CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1642 cs->lpszName = map_str_16_to_32W(cs16->lpszName);
1643 cs->lpszClass = map_str_16_to_32W(cs16->lpszClass);
1645 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1647 MDICREATESTRUCT16 *mdi_cs16;
1648 MDICREATESTRUCTW *mdi_cs = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs));
1651 HeapFree(GetProcessHeap(), 0, cs);
1654 mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs16->lpCreateParams);
1655 MDICREATESTRUCT16to32A(mdi_cs16, (MDICREATESTRUCTA *)mdi_cs);
1656 mdi_cs->szTitle = map_str_16_to_32W(mdi_cs16->szTitle);
1657 mdi_cs->szClass = map_str_16_to_32W(mdi_cs16->szClass);
1659 cs->lpCreateParams = mdi_cs;
1661 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1662 *plparam = (LPARAM)cs;
1667 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1668 MDICREATESTRUCTW *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1670 MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1671 cs->szTitle = map_str_16_to_32W(cs16->szTitle);
1672 cs->szClass = map_str_16_to_32W(cs16->szClass);
1673 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1674 *plparam = (LPARAM)cs;
1680 LPMSG16 msg16 = MapSL(*plparam);
1681 LPMSG msg32 = HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1683 if (!msg32) return -1;
1684 msg32->hwnd = WIN_Handle32( msg16->hwnd );
1685 msg32->lParam = msg16->lParam;
1686 msg32->time = msg16->time;
1687 msg32->pt.x = msg16->pt.x;
1688 msg32->pt.y = msg16->pt.y;
1689 /* this is right, right? */
1690 if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
1691 &msg32->message,&msg32->wParam,
1692 &msg32->lParam)<0) {
1693 HeapFree( GetProcessHeap(), 0, msg32 );
1696 *plparam = (LPARAM)msg32;
1703 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1704 *pwparam32 = MAKEWPARAM( wch, HIWORD(*plparam) );
1705 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1709 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1710 *pwparam32 = MAKEWPARAM( wch, LOWORD(*plparam) );
1711 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1716 case WM_SYSDEADCHAR:
1718 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1722 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, pwparam32, plparam );
1724 default: /* No Unicode translation needed */
1725 return WINPROC_MapMsg16To32A( hwnd, msg16, wParam16, pmsg32,
1726 pwparam32, plparam );
1731 /**********************************************************************
1732 * WINPROC_UnmapMsg16To32W
1734 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1736 LRESULT WINPROC_UnmapMsg16To32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1737 LRESULT result, WNDPROC dispatch )
1743 case WM_GETTEXTLENGTH:
1744 case CB_GETLBTEXTLEN:
1746 case WM_ASKCBFORMATNAME:
1747 return WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result, dispatch );
1751 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1752 lParam = *(LPARAM *)(cs + 1);
1753 CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs, MapSL(lParam) );
1754 unmap_str_16_to_32W( cs->lpszName );
1755 unmap_str_16_to_32W( cs->lpszClass );
1757 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1759 MDICREATESTRUCTW *mdi_cs = (MDICREATESTRUCTW *)cs->lpCreateParams;
1760 unmap_str_16_to_32W( mdi_cs->szTitle );
1761 unmap_str_16_to_32W( mdi_cs->szClass );
1762 HeapFree(GetProcessHeap(), 0, cs->lpCreateParams);
1764 HeapFree( GetProcessHeap(), 0, cs );
1769 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1770 lParam = *(LPARAM *)(cs + 1);
1771 MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs, MapSL(lParam) );
1772 unmap_str_16_to_32W( cs->szTitle );
1773 unmap_str_16_to_32W( cs->szClass );
1774 HeapFree( GetProcessHeap(), 0, cs );
1780 LPMSG msg32 = (LPMSG)lParam;
1782 WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1784 HeapFree( GetProcessHeap(), 0, msg32 );
1788 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1793 static HANDLE16 convert_handle_32_to_16(UINT src, unsigned int flags)
1796 UINT sz = GlobalSize((HANDLE)src);
1799 if (!(dst = GlobalAlloc16(flags, sz)))
1801 ptr32 = GlobalLock((HANDLE)src);
1802 ptr16 = GlobalLock16(dst);
1803 if (ptr16 != NULL && ptr32 != NULL) memcpy(ptr16, ptr32, sz);
1804 GlobalUnlock((HANDLE)src);
1805 GlobalUnlock16(dst);
1811 /**********************************************************************
1812 * WINPROC_MapMsg32ATo16
1814 * Map a message from 32-bit Ansi to 16-bit.
1815 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1817 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1818 UINT16 *pmsg16, WPARAM16 *pwparam16,
1821 *pmsg16 = (UINT16)msg32;
1822 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1826 *pmsg16 = SBM_SETRANGE16;
1827 *plparam = MAKELPARAM(wParam32, *plparam);
1832 *pmsg16 = SBM_GETRANGE16;
1840 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1849 case EM_SCROLLCARET:
1852 case EM_GETLINECOUNT:
1864 case EM_LINEFROMCHAR:
1865 case EM_SETTABSTOPS:
1866 case EM_SETPASSWORDCHAR:
1867 case EM_EMPTYUNDOBUFFER:
1868 case EM_GETFIRSTVISIBLELINE:
1869 case EM_SETREADONLY:
1870 case EM_SETWORDBREAKPROC:
1871 case EM_GETWORDBREAKPROC:
1872 case EM_GETPASSWORDCHAR:
1873 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1878 case LB_DELETESTRING:
1879 case LB_GETANCHORINDEX:
1880 case LB_GETCARETINDEX:
1883 case LB_GETHORIZONTALEXTENT:
1884 case LB_GETITEMDATA:
1885 case LB_GETITEMHEIGHT:
1887 case LB_GETSELCOUNT:
1889 case LB_GETTOPINDEX:
1890 case LB_RESETCONTENT:
1891 case LB_SELITEMRANGE:
1892 case LB_SELITEMRANGEEX:
1893 case LB_SETANCHORINDEX:
1894 case LB_SETCARETINDEX:
1895 case LB_SETCOLUMNWIDTH:
1897 case LB_SETHORIZONTALEXTENT:
1898 case LB_SETITEMDATA:
1899 case LB_SETITEMHEIGHT:
1901 case LB_SETTOPINDEX:
1902 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1904 case CB_DELETESTRING:
1906 case CB_GETLBTEXTLEN:
1908 case CB_RESETCONTENT:
1912 case CB_SHOWDROPDOWN:
1913 case CB_SETITEMDATA:
1914 case CB_SETITEMHEIGHT:
1915 case CB_GETITEMHEIGHT:
1916 case CB_SETEXTENDEDUI:
1917 case CB_GETEXTENDEDUI:
1918 case CB_GETDROPPEDSTATE:
1919 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1922 *pmsg16 = CB_GETEDITSEL16;
1927 case LB_FINDSTRINGEXACT:
1928 case LB_INSERTSTRING:
1929 case LB_SELECTSTRING:
1932 *plparam = (LPARAM)MapLS( (LPSTR)*plparam );
1933 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1938 case CB_FINDSTRINGEXACT:
1939 case CB_INSERTSTRING:
1940 case CB_SELECTSTRING:
1942 *plparam = (LPARAM)MapLS( (LPSTR)*plparam );
1943 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1946 case LB_GETITEMRECT:
1948 RECT16 *rect = HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16) + sizeof(LPARAM) );
1949 if (!rect) return -1;
1950 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1951 *plparam = MapLS( rect );
1953 *pmsg16 = LB_GETITEMRECT16;
1955 case LB_GETSELITEMS:
1957 LPARAM *items; /* old LPARAM first, then *pwparam16 x INT16 entries */
1959 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1960 if (!(items = HeapAlloc( GetProcessHeap(), 0,
1961 *pwparam16 * sizeof(INT16) + sizeof(LPARAM)))) return -1;
1962 *items++ = *plparam; /* Store the previous lParam */
1963 *plparam = MapLS( items );
1965 *pmsg16 = LB_GETSELITEMS16;
1967 case LB_SETTABSTOPS:
1972 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1973 if (!(stops = HeapAlloc( GetProcessHeap(), 0,
1974 *pwparam16 * sizeof(INT16) + sizeof(LPARAM)))) return -1;
1975 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1976 *plparam = MapLS( stops );
1979 *pmsg16 = LB_SETTABSTOPS16;
1982 case CB_GETDROPPEDCONTROLRECT:
1984 RECT16 *rect = HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16) + sizeof(LPARAM) );
1985 if (!rect) return -1;
1986 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1987 *plparam = (LPARAM)MapLS(rect);
1989 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1993 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1994 *pmsg16 = LB_GETTEXT16;
1998 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1999 *pmsg16 = CB_GETLBTEXT16;
2004 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
2005 *pmsg16 = EM_SETSEL16;
2012 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
2016 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
2020 PCOPYDATASTRUCT pcds32 = (PCOPYDATASTRUCT) *plparam;
2021 PCOPYDATASTRUCT16 pcds = HeapAlloc( GetProcessHeap(), 0, sizeof( *pcds));
2022 pcds->dwData = pcds32->dwData;
2023 pcds->cbData = pcds32->cbData;
2024 pcds->lpData = MapLS( pcds32->lpData);
2025 *plparam = MapLS( pcds );
2028 case WM_CTLCOLORMSGBOX:
2029 case WM_CTLCOLOREDIT:
2030 case WM_CTLCOLORLISTBOX:
2031 case WM_CTLCOLORBTN:
2032 case WM_CTLCOLORDLG:
2033 case WM_CTLCOLORSCROLLBAR:
2034 case WM_CTLCOLORSTATIC:
2035 *pmsg16 = WM_CTLCOLOR;
2036 *plparam = MAKELPARAM( (HWND16)*plparam,
2037 (WORD)msg32 - WM_CTLCOLORMSGBOX );
2039 case WM_COMPAREITEM:
2041 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
2042 COMPAREITEMSTRUCT16 *cis = HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16));
2043 if (!cis) return -1;
2044 cis->CtlType = (UINT16)cis32->CtlType;
2045 cis->CtlID = (UINT16)cis32->CtlID;
2046 cis->hwndItem = HWND_16( cis32->hwndItem );
2047 cis->itemID1 = (UINT16)cis32->itemID1;
2048 cis->itemData1 = cis32->itemData1;
2049 cis->itemID2 = (UINT16)cis32->itemID2;
2050 cis->itemData2 = cis32->itemData2;
2051 *plparam = MapLS( cis );
2056 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
2057 DELETEITEMSTRUCT16 *dis = HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16) );
2058 if (!dis) return -1;
2059 dis->CtlType = (UINT16)dis32->CtlType;
2060 dis->CtlID = (UINT16)dis32->CtlID;
2061 dis->itemID = (UINT16)dis32->itemID;
2062 dis->hwndItem = (dis->CtlType == ODT_MENU) ? (HWND16)LOWORD(dis32->hwndItem)
2063 : HWND_16( dis32->hwndItem );
2064 dis->itemData = dis32->itemData;
2065 *plparam = MapLS( dis );
2070 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
2071 DRAWITEMSTRUCT16 *dis = HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16) );
2072 if (!dis) return -1;
2073 dis->CtlType = (UINT16)dis32->CtlType;
2074 dis->CtlID = (UINT16)dis32->CtlID;
2075 dis->itemID = (UINT16)dis32->itemID;
2076 dis->itemAction = (UINT16)dis32->itemAction;
2077 dis->itemState = (UINT16)dis32->itemState;
2078 dis->hwndItem = HWND_16( dis32->hwndItem );
2079 dis->hDC = HDC_16(dis32->hDC);
2080 dis->itemData = dis32->itemData;
2081 dis->rcItem.left = dis32->rcItem.left;
2082 dis->rcItem.top = dis32->rcItem.top;
2083 dis->rcItem.right = dis32->rcItem.right;
2084 dis->rcItem.bottom = dis32->rcItem.bottom;
2085 *plparam = MapLS( dis );
2088 case WM_MEASUREITEM:
2090 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
2091 MEASUREITEMSTRUCT16 *mis = HeapAlloc( GetProcessHeap(), 0, sizeof(*mis)+sizeof(LPARAM));
2092 if (!mis) return -1;
2093 mis->CtlType = (UINT16)mis32->CtlType;
2094 mis->CtlID = (UINT16)mis32->CtlID;
2095 mis->itemID = (UINT16)mis32->itemID;
2096 mis->itemWidth = (UINT16)mis32->itemWidth;
2097 mis->itemHeight = (UINT16)mis32->itemHeight;
2098 mis->itemData = mis32->itemData;
2099 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
2100 *plparam = MapLS( mis );
2103 case WM_GETMINMAXINFO:
2105 MINMAXINFO16 *mmi = HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi) + sizeof(LPARAM) );
2106 if (!mmi) return -1;
2107 MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
2108 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
2109 *plparam = MapLS( mmi );
2113 case WM_ASKCBFORMATNAME:
2115 LPARAM *str; /* store LPARAM, then *pwparam16 char space */
2116 *pwparam16 = (WPARAM16)min( wParam32, 0xff80 ); /* Must be < 64K */
2117 if (!(str = HeapAlloc( GetProcessHeap(), 0, *pwparam16 + sizeof(LPARAM)))) return -1;
2118 *str++ = *plparam; /* Store the previous lParam */
2119 *plparam = MapLS( str );
2124 MDICREATESTRUCT16 *cs;
2125 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
2127 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16) ))) return -1;
2128 MDICREATESTRUCT32Ato16( cs32, cs );
2129 cs->szTitle = MapLS( cs32->szTitle );
2130 cs->szClass = MapLS( cs32->szClass );
2131 *plparam = MapLS( cs );
2134 case WM_MDIGETACTIVE:
2137 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
2138 (HMENU16)LOWORD(*plparam) );
2139 *pwparam16 = (*plparam == 0);
2142 if(HIWORD(wParam32) & MF_POPUP)
2145 if (((UINT)HIWORD(wParam32) != 0xFFFF) || (*plparam))
2147 if((hmenu = GetSubMenu((HMENU)*plparam, *pwparam16)))
2148 *pwparam16=HMENU_16(hmenu);
2153 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
2155 case WM_MDIACTIVATE:
2156 if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_MDICHILD)
2158 *pwparam16 = ((HWND)*plparam == hwnd);
2159 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
2160 (HWND16)LOWORD(wParam32) );
2164 *pwparam16 = HWND_16( (HWND)wParam32 );
2170 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
2171 NCCALCSIZE_PARAMS16 *nc = HeapAlloc( GetProcessHeap(), 0, sizeof(*nc) + sizeof(LPARAM));
2174 nc->rgrc[0].left = nc32->rgrc[0].left;
2175 nc->rgrc[0].top = nc32->rgrc[0].top;
2176 nc->rgrc[0].right = nc32->rgrc[0].right;
2177 nc->rgrc[0].bottom = nc32->rgrc[0].bottom;
2181 nc->rgrc[1].left = nc32->rgrc[1].left;
2182 nc->rgrc[1].top = nc32->rgrc[1].top;
2183 nc->rgrc[1].right = nc32->rgrc[1].right;
2184 nc->rgrc[1].bottom = nc32->rgrc[1].bottom;
2185 nc->rgrc[2].left = nc32->rgrc[2].left;
2186 nc->rgrc[2].top = nc32->rgrc[2].top;
2187 nc->rgrc[2].right = nc32->rgrc[2].right;
2188 nc->rgrc[2].bottom = nc32->rgrc[2].bottom;
2189 if (!(wp = HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16) )))
2191 HeapFree( GetProcessHeap(), 0, nc );
2194 WINDOWPOS32to16( nc32->lppos, wp );
2195 nc->lppos = MapLS( wp );
2197 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
2198 *plparam = MapLS( nc );
2205 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
2207 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16) ))) return -1;
2208 CREATESTRUCT32Ato16( cs32, cs );
2209 cs->lpszName = MapLS( cs32->lpszName );
2210 cs->lpszClass = MapLS( cs32->lpszClass );
2212 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2214 MDICREATESTRUCT16 *mdi_cs16;
2215 MDICREATESTRUCTA *mdi_cs = (MDICREATESTRUCTA *)cs32->lpCreateParams;
2216 mdi_cs16 = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs16));
2219 HeapFree(GetProcessHeap(), 0, cs);
2222 MDICREATESTRUCT32Ato16(mdi_cs, mdi_cs16);
2223 mdi_cs16->szTitle = MapLS( mdi_cs->szTitle );
2224 mdi_cs16->szClass = MapLS( mdi_cs->szClass );
2225 cs->lpCreateParams = MapLS( mdi_cs16 );
2227 *plparam = MapLS( cs );
2230 case WM_PARENTNOTIFY:
2231 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
2232 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
2233 /* else nothing to do */
2236 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
2239 case WM_WININICHANGE:
2240 case WM_DEVMODECHANGE:
2241 *plparam = MapLS( (LPSTR)*plparam );
2243 case WM_WINDOWPOSCHANGING:
2244 case WM_WINDOWPOSCHANGED:
2246 WINDOWPOS16 *wp = HeapAlloc( GetProcessHeap(), 0, sizeof(*wp) + sizeof(LPARAM) );
2248 WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
2249 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
2250 *plparam = MapLS( wp );
2255 LPMSG msg32 = (LPMSG) *plparam;
2256 LPMSG16 msg16 = HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16) );
2258 if (!msg16) return -1;
2259 msg16->hwnd = HWND_16( msg32->hwnd );
2260 msg16->lParam = msg32->lParam;
2261 msg16->time = msg32->time;
2262 msg16->pt.x = msg32->pt.x;
2263 msg16->pt.y = msg32->pt.y;
2264 /* this is right, right? */
2265 if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
2266 &msg16->message,&msg16->wParam, &msg16->lParam)<0)
2268 HeapFree( GetProcessHeap(), 0, msg16 );
2271 *plparam = MapLS( msg16 );
2276 case WM_ACTIVATEAPP:
2277 if (*plparam) *plparam = HTASK_16( (HANDLE)*plparam );
2281 MDINEXTMENU *next = (MDINEXTMENU *)*plparam;
2282 *plparam = (LPARAM)next->hmenuIn;
2286 if (IsIconic( hwnd ) && GetClassLongPtrW( hwnd, GCLP_HICON ))
2288 *pmsg16 = WM_PAINTICON;
2293 if (IsIconic( hwnd ) && GetClassLongPtrW( hwnd, GCLP_HICON ))
2294 *pmsg16 = WM_ICONERASEBKGND;
2296 case WM_PAINTCLIPBOARD:
2297 case WM_SIZECLIPBOARD:
2298 FIXME_(msg)("message %04x needs translation\n", msg32 );
2300 /* following messages should not be sent to 16-bit apps */
2303 case WM_CAPTURECHANGED:
2304 case WM_STYLECHANGING:
2305 case WM_STYLECHANGED:
2307 case WM_DDE_INITIATE:
2308 case WM_DDE_TERMINATE:
2309 case WM_DDE_UNADVISE:
2310 case WM_DDE_REQUEST:
2311 *pwparam16 = HWND_16((HWND)wParam32);
2320 *pwparam16 = HWND_16((HWND)wParam32);
2321 UnpackDDElParam(msg32, *plparam, &lo32, &hi);
2322 if (lo32 && !(lo16 = convert_handle_32_to_16(lo32, GMEM_DDESHARE)))
2324 *plparam = MAKELPARAM(lo16, hi);
2326 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2333 *pwparam16 = HWND_16((HWND)wParam32);
2335 UnpackDDElParam(msg32, *plparam, &lo, &hi);
2337 if (GlobalGetAtomNameA((ATOM)hi, buf, sizeof(buf)) > 0) flag |= 1;
2338 if (GlobalSize((HANDLE)hi) != 0) flag |= 2;
2344 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
2349 break; /* atom, nothing to do */
2351 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi);
2354 hi = convert_handle_32_to_16(hi, GMEM_DDESHARE);
2357 *plparam = MAKELPARAM(lo, hi);
2359 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2360 case WM_DDE_EXECUTE:
2361 *plparam = convert_handle_32_to_16(*plparam, GMEM_DDESHARE);
2362 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2363 default: /* No translation needed */
2369 /**********************************************************************
2370 * WINPROC_UnmapMsg32ATo16
2372 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2374 void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2380 *(LPINT)wParam = LOWORD(p16->lResult);
2381 *(LPINT)lParam = HIWORD(p16->lResult);
2388 case LB_FINDSTRINGEXACT:
2389 case LB_INSERTSTRING:
2390 case LB_SELECTSTRING:
2394 case CB_FINDSTRINGEXACT:
2395 case CB_INSERTSTRING:
2396 case CB_SELECTSTRING:
2400 case WM_WININICHANGE:
2401 case WM_DEVMODECHANGE:
2402 UnMapLS( (SEGPTR)p16->lParam );
2404 case LB_SETTABSTOPS:
2405 case WM_COMPAREITEM:
2409 void *ptr = MapSL( p16->lParam );
2410 UnMapLS( p16->lParam );
2411 HeapFree( GetProcessHeap(), 0, ptr );
2416 PCOPYDATASTRUCT16 pcds = MapSL( p16->lParam );
2417 UnMapLS( p16->lParam );
2418 UnMapLS( pcds->lpData );
2419 HeapFree( GetProcessHeap(), 0, pcds );
2422 case CB_GETDROPPEDCONTROLRECT:
2423 case LB_GETITEMRECT:
2426 RECT16 *rect = MapSL(p16->lParam);
2427 UnMapLS( p16->lParam );
2428 p16->lParam = *(LPARAM *)(rect + 1);
2429 r32 = (RECT *)p16->lParam;
2430 r32->left = rect->left;
2431 r32->top = rect->top;
2432 r32->right = rect->right;
2433 r32->bottom = rect->bottom;
2434 HeapFree( GetProcessHeap(), 0, rect );
2437 case LB_GETSELITEMS:
2440 LPINT16 items = MapSL(p16->lParam);
2441 UnMapLS( p16->lParam );
2442 p16->lParam = *((LPARAM *)items - 1);
2443 for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
2444 HeapFree( GetProcessHeap(), 0, (LPARAM *)items - 1 );
2450 *((PUINT)(wParam)) = LOWORD(p16->lResult);
2452 *((PUINT)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
2455 case WM_MEASUREITEM:
2457 MEASUREITEMSTRUCT16 *mis = MapSL(p16->lParam);
2458 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
2459 mis32->itemWidth = mis->itemWidth;
2460 mis32->itemHeight = mis->itemHeight;
2461 UnMapLS( p16->lParam );
2462 HeapFree( GetProcessHeap(), 0, mis );
2465 case WM_GETMINMAXINFO:
2467 MINMAXINFO16 *mmi = MapSL(p16->lParam);
2468 UnMapLS( p16->lParam );
2469 p16->lParam = *(LPARAM *)(mmi + 1);
2470 MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
2471 HeapFree( GetProcessHeap(), 0, mmi );
2475 case WM_ASKCBFORMATNAME:
2477 LPSTR str = MapSL(p16->lParam);
2478 UnMapLS( p16->lParam );
2479 p16->lParam = *((LPARAM *)str - 1);
2480 lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
2481 HeapFree( GetProcessHeap(), 0, (LPARAM *)str - 1 );
2486 MDICREATESTRUCT16 *cs = MapSL(p16->lParam);
2487 UnMapLS( cs->szTitle );
2488 UnMapLS( cs->szClass );
2489 UnMapLS( p16->lParam );
2490 HeapFree( GetProcessHeap(), 0, cs );
2493 case WM_MDIGETACTIVE:
2494 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
2495 p16->lResult = (LRESULT)WIN_Handle32( LOWORD(p16->lResult) );
2499 NCCALCSIZE_PARAMS *nc32;
2500 NCCALCSIZE_PARAMS16 *nc = MapSL(p16->lParam);
2501 UnMapLS( p16->lParam );
2502 p16->lParam = *(LPARAM *)(nc + 1);
2503 nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
2504 nc32->rgrc[0].left = nc->rgrc[0].left;
2505 nc32->rgrc[0].top = nc->rgrc[0].top;
2506 nc32->rgrc[0].right = nc->rgrc[0].right;
2507 nc32->rgrc[0].bottom = nc->rgrc[0].bottom;
2510 WINDOWPOS16 *pos = MapSL(nc->lppos);
2511 UnMapLS( nc->lppos );
2512 nc32->rgrc[1].left = nc->rgrc[1].left;
2513 nc32->rgrc[1].top = nc->rgrc[1].top;
2514 nc32->rgrc[1].right = nc->rgrc[1].right;
2515 nc32->rgrc[1].bottom = nc->rgrc[1].bottom;
2516 nc32->rgrc[2].left = nc->rgrc[2].left;
2517 nc32->rgrc[2].top = nc->rgrc[2].top;
2518 nc32->rgrc[2].right = nc->rgrc[2].right;
2519 nc32->rgrc[2].bottom = nc->rgrc[2].bottom;
2520 WINDOWPOS16to32( pos, nc32->lppos );
2521 HeapFree( GetProcessHeap(), 0, pos );
2523 HeapFree( GetProcessHeap(), 0, nc );
2529 CREATESTRUCT16 *cs = MapSL(p16->lParam);
2530 UnMapLS( p16->lParam );
2531 UnMapLS( cs->lpszName );
2532 UnMapLS( cs->lpszClass );
2533 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2535 MDICREATESTRUCT16 *mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs->lpCreateParams);
2536 UnMapLS( cs->lpCreateParams );
2537 UnMapLS( mdi_cs16->szTitle );
2538 UnMapLS( mdi_cs16->szClass );
2539 HeapFree(GetProcessHeap(), 0, mdi_cs16);
2541 HeapFree( GetProcessHeap(), 0, cs );
2544 case WM_WINDOWPOSCHANGING:
2545 case WM_WINDOWPOSCHANGED:
2547 WINDOWPOS16 *wp = MapSL(p16->lParam);
2548 UnMapLS( p16->lParam );
2549 p16->lParam = *(LPARAM *)(wp + 1);
2550 WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
2551 HeapFree( GetProcessHeap(), 0, wp );
2555 UnMapLS(p16->lParam);
2560 LPMSG16 msg16 = MapSL(p16->lParam);
2562 UnMapLS( p16->lParam );
2563 msgp16.wParam=msg16->wParam;
2564 msgp16.lParam=msg16->lParam;
2565 WINPROC_UnmapMsg32ATo16(((LPMSG)lParam)->hwnd, ((LPMSG)lParam)->message,
2566 ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam,
2568 HeapFree( GetProcessHeap(), 0, msg16 );
2573 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
2574 next->hmenuNext = HMENU_32( LOWORD(p16->lResult) );
2575 next->hwndNext = WIN_Handle32( HIWORD(p16->lResult) );
2583 /**********************************************************************
2584 * WINPROC_MapMsg32WTo16
2586 * Map a message from 32-bit Unicode to 16-bit.
2587 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2589 INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
2590 UINT16 *pmsg16, WPARAM16 *pwparam16,
2596 *pmsg16 = LOWORD(msg32);
2597 *pwparam16 = LOWORD(wParam32);
2602 case LB_FINDSTRINGEXACT:
2603 case LB_INSERTSTRING:
2604 case LB_SELECTSTRING:
2607 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2608 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2613 case CB_FINDSTRINGEXACT:
2614 case CB_INSERTSTRING:
2615 case CB_SELECTSTRING:
2617 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2618 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2625 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2627 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16) ))) return -1;
2628 CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2629 cs->lpszName = map_str_32W_to_16( cs32->lpszName );
2630 cs->lpszClass = map_str_32W_to_16( cs32->lpszClass );
2632 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2634 MDICREATESTRUCT16 *mdi_cs16;
2635 MDICREATESTRUCTW *mdi_cs = (MDICREATESTRUCTW *)cs32->lpCreateParams;
2636 mdi_cs16 = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs16));
2639 HeapFree(GetProcessHeap(), 0, cs);
2642 MDICREATESTRUCT32Ato16((MDICREATESTRUCTA *)mdi_cs, mdi_cs16);
2643 mdi_cs16->szTitle = map_str_32W_to_16(mdi_cs->szTitle);
2644 mdi_cs16->szClass = map_str_32W_to_16(mdi_cs->szClass);
2645 cs->lpCreateParams = MapLS(mdi_cs16);
2647 *plparam = MapLS(cs);
2652 MDICREATESTRUCT16 *cs;
2653 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2655 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16) ))) return -1;
2656 MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2657 cs->szTitle = map_str_32W_to_16( cs32->szTitle );
2658 cs->szClass = map_str_32W_to_16( cs32->szClass );
2659 *plparam = MapLS(cs);
2663 case WM_WININICHANGE:
2664 case WM_DEVMODECHANGE:
2665 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2668 if ( WINPROC_TestLBForStr( hwnd ))
2670 LPSTR str = HeapAlloc( GetProcessHeap(), 0, 512 ); /* FIXME: fixed sized buffer */
2671 if (!str) return -1;
2672 *pmsg16 = LB_GETTEXT16;
2673 *plparam = (LPARAM)MapLS(str);
2677 if ( WINPROC_TestCBForStr( hwnd ))
2679 LPSTR str = HeapAlloc( GetProcessHeap(), 0, 512 ); /* FIXME: fixed sized buffer */
2680 if (!str) return -1;
2681 *pmsg16 = CB_GETLBTEXT16;
2682 *plparam = (LPARAM)MapLS(str);
2687 wch = LOWORD(wParam32);
2688 WideCharToMultiByte( CP_ACP, 0, &wch, 1, (LPSTR)&ch, 1, NULL, NULL);
2690 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
2693 wch = LOWORD(wParam32);
2694 WideCharToMultiByte( CP_ACP, 0, &wch, 1, (LPSTR)&ch, 1, NULL, NULL);
2696 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
2701 case WM_SYSDEADCHAR:
2703 WideCharToMultiByte( CP_ACP, 0, &wch, 1, (LPSTR)&ch, 1, NULL, NULL);
2711 if (WideCharToMultiByte( CP_ACP, 0, &wch, 1, (LPSTR)ch, 2, NULL, NULL ) == 2)
2712 *pwparam16 = (ch[0] << 8) | ch[1];
2718 default: /* No Unicode translation needed (?) */
2719 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2720 pwparam16, plparam );
2725 /**********************************************************************
2726 * WINPROC_UnmapMsg32WTo16
2728 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2730 void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2737 case LB_FINDSTRINGEXACT:
2738 case LB_INSERTSTRING:
2739 case LB_SELECTSTRING:
2744 case CB_FINDSTRINGEXACT:
2745 case CB_INSERTSTRING:
2746 case CB_SELECTSTRING:
2749 case WM_WININICHANGE:
2750 case WM_DEVMODECHANGE:
2751 unmap_str_32W_to_16( p16->lParam );
2756 CREATESTRUCT16 *cs = MapSL(p16->lParam);
2757 UnMapLS( p16->lParam );
2758 unmap_str_32W_to_16( cs->lpszName );
2759 unmap_str_32W_to_16( cs->lpszClass );
2761 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2763 MDICREATESTRUCT16 *mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs->lpCreateParams);
2764 UnMapLS( cs->lpCreateParams );
2765 unmap_str_32W_to_16(mdi_cs16->szTitle);
2766 unmap_str_32W_to_16(mdi_cs16->szClass);
2767 HeapFree(GetProcessHeap(), 0, mdi_cs16);
2769 HeapFree( GetProcessHeap(), 0, cs );
2774 MDICREATESTRUCT16 *cs = MapSL(p16->lParam);
2775 UnMapLS( p16->lParam );
2776 unmap_str_32W_to_16( cs->szTitle );
2777 unmap_str_32W_to_16( cs->szClass );
2778 HeapFree( GetProcessHeap(), 0, cs );
2782 case WM_ASKCBFORMATNAME:
2784 LPSTR str = MapSL(p16->lParam);
2785 UnMapLS( p16->lParam );
2786 p16->lParam = *((LPARAM *)str - 1);
2787 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)p16->lParam, 0x7fffffff );
2788 p16->lResult = strlenW( (LPWSTR)p16->lParam );
2789 HeapFree( GetProcessHeap(), 0, (LPARAM *)str - 1 );
2793 if ( WINPROC_TestLBForStr( hwnd ))
2795 LPSTR str = MapSL(p16->lParam);
2796 UnMapLS( p16->lParam );
2797 p16->lResult = MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)lParam, 0x7fffffff ) - 1;
2798 HeapFree( GetProcessHeap(), 0, (LPARAM *)str );
2802 if ( WINPROC_TestCBForStr( hwnd ))
2804 LPSTR str = MapSL(p16->lParam);
2805 UnMapLS( p16->lParam );
2806 p16->lResult = MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)lParam, 0x7fffffff ) - 1;
2807 HeapFree( GetProcessHeap(), 0, (LPARAM *)str );
2811 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2817 /**********************************************************************
2818 * WINPROC_CallProc32ATo32W
2820 * Call a window procedure, translating args from Ansi to Unicode.
2822 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd, UINT msg, WPARAM wParam,
2823 LPARAM lParam, BOOL dialog )
2828 TRACE_(msg)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2829 func, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
2831 if( (unmap = WINPROC_MapMsg32ATo32W( hwnd, msg, &wParam, &lParam )) == -1) {
2832 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2833 SPY_GetMsgName(msg, hwnd), wParam, lParam );
2836 ret = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2841 LRESULT result = GetWindowLongPtrW( hwnd, DWLP_MSGRESULT );
2842 result = WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result, NULL );
2843 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result );
2845 else ret = WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, ret, func );
2851 static inline void *get_buffer( void *static_buffer, size_t size, size_t need )
2853 if (size >= need) return static_buffer;
2854 return HeapAlloc( GetProcessHeap(), 0, need );
2857 static inline void free_buffer( void *static_buffer, void *buffer )
2859 if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
2862 /**********************************************************************
2863 * WINPROC_CallProc32WTo32A
2865 * Call a window procedure, translating args from Unicode to Ansi.
2867 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd, UINT msg, WPARAM wParam,
2868 LPARAM lParam, BOOL dialog )
2873 TRACE_(msg)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2874 func, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
2880 { /* csW->lpszName and csW->lpszClass are NOT supposed to be atoms
2883 char buffer[1024], *cls, *name;
2884 CREATESTRUCTW *csW = (CREATESTRUCTW *)lParam;
2885 CREATESTRUCTA csA = *(CREATESTRUCTA *)csW;
2886 MDICREATESTRUCTA mdi_cs;
2887 DWORD name_lenA, name_lenW, class_lenA, class_lenW;
2889 class_lenW = strlenW(csW->lpszClass) * sizeof(WCHAR);
2890 RtlUnicodeToMultiByteSize(&class_lenA, csW->lpszClass, class_lenW);
2894 name_lenW = strlenW(csW->lpszName) * sizeof(WCHAR);
2895 RtlUnicodeToMultiByteSize(&name_lenA, csW->lpszName, name_lenW);
2898 name_lenW = name_lenA = 0;
2900 if (!(cls = get_buffer( buffer, sizeof(buffer), class_lenA + name_lenA + 2 ))) break;
2902 RtlUnicodeToMultiByteN(cls, class_lenA, NULL, csW->lpszClass, class_lenW);
2903 cls[class_lenA] = 0;
2904 csA.lpszClass = cls;
2908 name = cls + class_lenA + 1;
2909 RtlUnicodeToMultiByteN(name, name_lenA, NULL, csW->lpszName, name_lenW);
2910 name[name_lenA] = 0;
2911 csA.lpszName = name;
2914 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2916 mdi_cs = *(MDICREATESTRUCTA *)csW->lpCreateParams;
2917 mdi_cs.szTitle = csA.lpszName;
2918 mdi_cs.szClass = csA.lpszClass;
2919 csA.lpCreateParams = &mdi_cs;
2922 ret = WINPROC_CallWndProc(func, hwnd, msg, wParam, (LPARAM)&csA);
2923 free_buffer( buffer, cls );
2928 case WM_ASKCBFORMATNAME:
2930 char *ptr, buffer[512];
2931 DWORD len = wParam * 2;
2933 if (!(ptr = get_buffer( buffer, sizeof(buffer), len ))) break;
2934 ret = WINPROC_CallWndProc( func, hwnd, msg, len, (LPARAM)ptr );
2937 RtlMultiByteToUnicodeN( (LPWSTR)lParam, wParam*sizeof(WCHAR), &len, ptr, strlen(ptr)+1 );
2938 ret = len/sizeof(WCHAR) - 1; /* do not count terminating null */
2939 ((LPWSTR)lParam)[ret] = 0;
2942 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, ret );
2946 free_buffer( buffer, ptr );
2951 case WM_WININICHANGE:
2952 case WM_DEVMODECHANGE:
2958 if (!lParam) ret = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2961 char *ptr, buffer[512];
2962 LPCWSTR strW = (LPCWSTR)lParam;
2963 DWORD lenA, lenW = (strlenW(strW) + 1) * sizeof(WCHAR);
2965 RtlUnicodeToMultiByteSize( &lenA, strW, lenW );
2966 if ((ptr = get_buffer( buffer, sizeof(buffer), lenA )))
2968 RtlUnicodeToMultiByteN( ptr, lenA, NULL, strW, lenW );
2969 ret = WINPROC_CallWndProc( func, hwnd, msg, wParam, (LPARAM)ptr );
2970 free_buffer( buffer, ptr );
2977 char *ptr, buffer[1024];
2978 DWORD title_lenA = 0, title_lenW = 0, class_lenA = 0, class_lenW = 0;
2979 MDICREATESTRUCTW *csW = (MDICREATESTRUCTW *)lParam;
2980 MDICREATESTRUCTA csA;
2982 memcpy( &csA, csW, sizeof(csA) );
2984 if (HIWORD(csW->szTitle))
2986 title_lenW = (strlenW(csW->szTitle) + 1) * sizeof(WCHAR);
2987 RtlUnicodeToMultiByteSize( &title_lenA, csW->szTitle, title_lenW );
2989 if (HIWORD(csW->szClass))
2991 class_lenW = (strlenW(csW->szClass) + 1) * sizeof(WCHAR);
2992 RtlUnicodeToMultiByteSize( &class_lenA, csW->szClass, class_lenW );
2995 if (!(ptr = get_buffer( buffer, sizeof(buffer), title_lenA + class_lenA ))) break;
2999 RtlUnicodeToMultiByteN( ptr, title_lenA, NULL, csW->szTitle, title_lenW );
3004 RtlUnicodeToMultiByteN( ptr + title_lenA, class_lenA, NULL, csW->szClass, class_lenW );
3005 csA.szClass = ptr + title_lenA;
3007 ret = WINPROC_CallWndProc( func, hwnd, msg, wParam, (LPARAM)&csA );
3008 free_buffer( buffer, ptr );
3014 case LB_INSERTSTRING:
3016 case LB_FINDSTRINGEXACT:
3017 case LB_SELECTSTRING:
3018 if (lParam && WINPROC_TestLBForStr( hwnd )) goto handle_wm_settext;
3019 ret = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
3024 case CB_INSERTSTRING:
3026 case CB_FINDSTRINGEXACT:
3027 case CB_SELECTSTRING:
3028 if (lParam && WINPROC_TestCBForStr( hwnd )) goto handle_wm_settext;
3029 ret = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
3033 if ((unmap = WINPROC_MapMsg32WTo32A( hwnd, msg, &wParam, &lParam )) == -1) {
3034 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
3035 SPY_GetMsgName(msg, hwnd), wParam, lParam );
3038 ret = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
3042 LRESULT result = GetWindowLongPtrW( hwnd, DWLP_MSGRESULT );
3043 result = WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam, result );
3044 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result );
3046 else ret = WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam, ret );
3054 /**********************************************************************
3055 * WINPROC_CallProc16To32A
3057 static LRESULT WINPROC_CallProc16To32A( WNDPROC func, HWND16 hwnd, UINT16 msg,
3058 WPARAM16 wParam, LPARAM lParam, BOOL dialog )
3063 HWND hwnd32 = WIN_Handle32( hwnd );
3065 TRACE_(msg)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3066 func, hwnd32, SPY_GetMsgName(msg, hwnd32), wParam, lParam);
3068 if (WINPROC_MapMsg16To32A( hwnd32, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
3070 ret = WINPROC_CallWndProc( func, hwnd32, msg32, wParam32, lParam );
3073 LRESULT result = GetWindowLongPtrW( hwnd32, DWLP_MSGRESULT );
3074 result = WINPROC_UnmapMsg16To32A( hwnd32, msg32, wParam32, lParam, result );
3075 SetWindowLongPtrW( hwnd32, DWLP_MSGRESULT, result );
3077 else ret = WINPROC_UnmapMsg16To32A( hwnd32, msg32, wParam32, lParam, ret );
3083 /**********************************************************************
3084 * WINPROC_CallProc16To32W
3086 static LRESULT WINPROC_CallProc16To32W( WNDPROC func, HWND16 hwnd, UINT16 msg,
3087 WPARAM16 wParam, LPARAM lParam, BOOL dialog )
3092 HWND hwnd32 = WIN_Handle32( hwnd );
3094 TRACE_(msg)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3095 func, hwnd32, SPY_GetMsgName(msg, hwnd32), wParam, lParam);
3097 if (WINPROC_MapMsg16To32W( hwnd32, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
3100 ret = WINPROC_CallWndProc( func, hwnd32, msg32, wParam32, lParam );
3103 LRESULT result = GetWindowLongPtrW( hwnd32, DWLP_MSGRESULT );
3104 result = WINPROC_UnmapMsg16To32W( hwnd32, msg32, wParam32, lParam, result, NULL );
3105 SetWindowLongPtrW( hwnd32, DWLP_MSGRESULT, result );
3107 else ret = WINPROC_UnmapMsg16To32W( hwnd32, msg32, wParam32, lParam, ret, func );
3113 /**********************************************************************
3114 * __wine_call_wndproc (USER.1010)
3116 LRESULT WINAPI __wine_call_wndproc( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam,
3119 if (proc->procA) return WINPROC_CallProc16To32A( proc->procA, hwnd, msg, wParam, lParam, FALSE );
3120 else return WINPROC_CallProc16To32W( proc->procW, hwnd, msg, wParam, lParam, FALSE );
3124 /**********************************************************************
3125 * WINPROC_CallProc32ATo16
3127 * Call a 16-bit window procedure, translating the 32-bit args.
3129 static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd, UINT msg,
3130 WPARAM wParam, LPARAM lParam, BOOL dialog )
3136 TRACE_(msg)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3137 func, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
3139 mp16.lParam = lParam;
3140 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1)
3142 ret = WINPROC_CallWndProc16( func, HWND_16(hwnd), msg16, mp16.wParam, mp16.lParam );
3145 mp16.lResult = GetWindowLongPtrW( hwnd, DWLP_MSGRESULT );
3146 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
3147 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, mp16.lResult );
3153 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
3160 /**********************************************************************
3161 * WINPROC_CallProc32WTo16
3163 * Call a 16-bit window procedure, translating the 32-bit args.
3165 static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd, UINT msg,
3166 WPARAM wParam, LPARAM lParam, BOOL dialog )
3172 TRACE_(msg)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3173 func, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
3175 mp16.lParam = lParam;
3176 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1)
3178 ret = WINPROC_CallWndProc16( func, HWND_16(hwnd), msg16, mp16.wParam, mp16.lParam );
3181 mp16.lResult = GetWindowLongPtrW( hwnd, DWLP_MSGRESULT );
3182 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
3183 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, mp16.lResult );
3189 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
3196 /**********************************************************************
3197 * CallWindowProc (USER.122)
3199 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
3200 WPARAM16 wParam, LPARAM lParam )
3204 if (!func) return 0;
3206 if (!(proc = handle16_to_proc( func )))
3207 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
3209 if (proc->procA) return WINPROC_CallProc16To32A( proc->procA, hwnd, msg, wParam, lParam, FALSE );
3210 if (proc->procW) return WINPROC_CallProc16To32W( proc->procW, hwnd, msg, wParam, lParam, FALSE );
3211 return WINPROC_CallWndProc16( proc->proc16, hwnd, msg, wParam, lParam );
3215 /**********************************************************************
3216 * CallWindowProcA (USER32.@)
3218 * The CallWindowProc() function invokes the windows procedure _func_,
3219 * with _hwnd_ as the target window, the message specified by _msg_, and
3220 * the message parameters _wParam_ and _lParam_.
3222 * Some kinds of argument conversion may be done, I'm not sure what.
3224 * CallWindowProc() may be used for windows subclassing. Use
3225 * SetWindowLong() to set a new windows procedure for windows of the
3226 * subclass, and handle subclassed messages in the new windows
3227 * procedure. The new windows procedure may then use CallWindowProc()
3228 * with _func_ set to the parent class's windows procedure to dispatch
3229 * the message to the superclass.
3233 * The return value is message dependent.
3239 LRESULT WINAPI CallWindowProcA(
3240 WNDPROC func, /* [in] window procedure */
3241 HWND hwnd, /* [in] target window */
3242 UINT msg, /* [in] message */
3243 WPARAM wParam, /* [in] message dependent parameter */
3244 LPARAM lParam /* [in] message dependent parameter */
3248 if (!func) return 0;
3250 if (!(proc = handle_to_proc( func )))
3251 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
3253 if (proc->procA) return WINPROC_CallWndProc( proc->procA, hwnd, msg, wParam, lParam );
3254 if (proc->procW) return WINPROC_CallProc32ATo32W( proc->procW, hwnd, msg, wParam, lParam, FALSE );
3255 return WINPROC_CallProc32ATo16( proc->proc16, hwnd, msg, wParam, lParam, FALSE );
3259 /**********************************************************************
3260 * CallWindowProcW (USER32.@)
3262 * See CallWindowProcA.
3264 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
3265 WPARAM wParam, LPARAM lParam )
3269 if (!func) return 0;
3271 if (!(proc = handle_to_proc( func )))
3272 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
3274 if (proc->procW) return WINPROC_CallWndProc( proc->procW, hwnd, msg, wParam, lParam );
3275 if (proc->procA) return WINPROC_CallProc32WTo32A( proc->procA, hwnd, msg, wParam, lParam, FALSE );
3276 return WINPROC_CallProc32WTo16( proc->proc16, hwnd, msg, wParam, lParam, FALSE );
3280 /**********************************************************************
3281 * WINPROC_CallDlgProc16
3283 INT_PTR WINPROC_CallDlgProc16( DLGPROC16 func, HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
3287 if (!func) return 0;
3289 if (!(proc = handle16_to_proc( (WNDPROC16)func )))
3290 return LOWORD( WINPROC_CallWndProc16( (WNDPROC16)func, hwnd, msg, wParam, lParam ) );
3292 if (proc->procA) return WINPROC_CallProc16To32A( proc->procA, hwnd, msg, wParam, lParam, TRUE );
3293 if (proc->procW) return WINPROC_CallProc16To32W( proc->procW, hwnd, msg, wParam, lParam, TRUE );
3294 return LOWORD( WINPROC_CallWndProc16( proc->proc16, hwnd, msg, wParam, lParam ) );
3298 /**********************************************************************
3299 * WINPROC_CallDlgProcA
3301 INT_PTR WINPROC_CallDlgProcA( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
3305 if (!func) return 0;
3307 if (!(proc = handle_to_proc( (WNDPROC)func )))
3308 return WINPROC_CallWndProc( (WNDPROC)func, hwnd, msg, wParam, lParam );
3310 if (proc->procA) return WINPROC_CallWndProc( proc->procA, hwnd, msg, wParam, lParam );
3311 if (proc->procW) return WINPROC_CallProc32ATo32W( proc->procW, hwnd, msg, wParam, lParam, TRUE );
3312 return WINPROC_CallProc32ATo16( proc->proc16, hwnd, msg, wParam, lParam, TRUE );
3316 /**********************************************************************
3317 * WINPROC_CallDlgProcW
3319 INT_PTR WINPROC_CallDlgProcW( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
3323 if (!func) return 0;
3325 if (!(proc = handle_to_proc( (WNDPROC)func )))
3326 return WINPROC_CallWndProc( (WNDPROC)func, hwnd, msg, wParam, lParam );
3328 if (proc->procW) return WINPROC_CallWndProc( proc->procW, hwnd, msg, wParam, lParam );
3329 if (proc->procA) return WINPROC_CallProc32WTo32A( proc->procA, hwnd, msg, wParam, lParam, TRUE );
3330 return WINPROC_CallProc32WTo16( proc->proc16, hwnd, msg, wParam, lParam, TRUE );