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 static WPARAM map_wparam_char_AtoW( WPARAM wParam, DWORD len )
389 ch[0] = (wParam >> 8);
390 ch[1] = wParam & 0xff;
391 if (len > 1 && ch[0])
392 RtlMultiByteToUnicodeN( &wch, sizeof(wch), NULL, ch, 2 );
394 RtlMultiByteToUnicodeN( &wch, sizeof(wch), NULL, ch + 1, 1 );
395 return MAKEWPARAM( wch, HIWORD(wParam) );
398 static WPARAM map_wparam_char_WtoA( WPARAM wParam, DWORD len )
403 RtlUnicodeToMultiByteN( (LPSTR)ch, len, &len, &wch, sizeof(wch) );
405 return MAKEWPARAM( (ch[0] << 8) | ch[1], HIWORD(wParam) );
407 return MAKEWPARAM( ch[0], HIWORD(wParam) );
410 /* call a 32-bit window procedure */
411 static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result, void *arg )
417 hwnd = WIN_GetFullHandle( hwnd );
419 DPRINTF( "%04lx:Call window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
420 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wp, lp );
422 *result = WINPROC_wrapper( proc, hwnd, msg, wp, lp );
425 DPRINTF( "%04lx:Ret window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
426 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wp, lp, *result );
430 /* call a 32-bit dialog procedure */
431 static LRESULT call_dialog_proc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result, void *arg )
438 hwnd = WIN_GetFullHandle( hwnd );
440 DPRINTF( "%04lx:Call dialog proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
441 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wp, lp );
443 ret = WINPROC_wrapper( proc, hwnd, msg, wp, lp );
444 *result = GetWindowLongPtrW( hwnd, DWLP_MSGRESULT );
447 DPRINTF( "%04lx:Ret dialog proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx result=%08lx\n",
448 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wp, lp, ret, *result );
452 /**********************************************************************
453 * WINPROC_CallWndProc32
455 * Call a 32-bit WndProc.
457 static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
458 WPARAM wParam, LPARAM lParam )
464 hwnd = WIN_GetFullHandle( hwnd );
466 DPRINTF( "%04lx:Call window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
467 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam );
469 retvalue = WINPROC_wrapper( proc, hwnd, msg, wParam, lParam );
472 DPRINTF( "%04lx:Ret window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
473 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam, retvalue );
477 /* call a 16-bit window procedure */
478 static LRESULT call_window_proc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam,
479 LRESULT *result, void *arg )
481 WNDPROC16 proc = arg;
490 DRAWITEMSTRUCT16 dis16;
491 COMPAREITEMSTRUCT16 cis16;
497 /* Window procedures want ax = hInstance, ds = es = ss */
499 memset(&context, 0, sizeof(context));
500 context.SegDs = context.SegEs = SELECTOROF(NtCurrentTeb()->WOW32Reserved);
501 context.SegFs = wine_get_fs();
502 context.SegGs = wine_get_gs();
503 if (!(context.Eax = GetWindowWord( HWND_32(hwnd), GWLP_HINSTANCE ))) context.Eax = context.SegDs;
504 context.SegCs = SELECTOROF(proc);
505 context.Eip = OFFSETOF(proc);
506 context.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + (WORD)&((STACK16FRAME*)0)->bp;
510 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
511 work if structures passed in lParam are placed in the stack/data
512 segment. Programmers easily make the mistake of converting lParam
513 to a near rather than a far pointer, since Windows apparently
514 allows this. We copy the structures to the 16 bit stack; this is
515 ugly but makes these programs work. */
520 size = sizeof(CREATESTRUCT16); break;
522 size = sizeof(DRAWITEMSTRUCT16); break;
524 size = sizeof(COMPAREITEMSTRUCT16); break;
528 memcpy( &args.u, MapSL(lParam), size );
529 lParam = (SEGPTR)NtCurrentTeb()->WOW32Reserved - size;
533 args.params[4] = hwnd;
534 args.params[3] = msg;
535 args.params[2] = wParam;
536 args.params[1] = HIWORD(lParam);
537 args.params[0] = LOWORD(lParam);
538 WOWCallback16Ex( 0, WCB16_REGS, sizeof(args.params) + size, &args, (DWORD *)&context );
539 *result = MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) );
543 /* call a 16-bit dialog procedure */
544 static LRESULT call_dialog_proc16( HWND16 hwnd, UINT16 msg, WPARAM16 wp, LPARAM lp,
545 LRESULT *result, void *arg )
547 LRESULT ret = call_window_proc16( hwnd, msg, wp, lp, result, arg );
548 *result = GetWindowLongPtrW( WIN_Handle32(hwnd), DWLP_MSGRESULT );
553 /**********************************************************************
556 * Get a window procedure pointer that can be passed to the Windows program.
558 WNDPROC16 WINPROC_GetProc16( WNDPROC proc, BOOL unicode )
562 if (unicode) ptr = alloc_winproc( NULL, proc );
563 else ptr = alloc_winproc( proc, NULL );
566 return alloc_win16_thunk( ptr );
570 /**********************************************************************
573 * Get a window procedure pointer that can be passed to the Windows program.
575 WNDPROC WINPROC_GetProc( WNDPROC proc, BOOL unicode )
577 WINDOWPROC *ptr = handle_to_proc( proc );
579 if (!ptr) return proc;
582 if (ptr->procW) return ptr->procW;
587 if (ptr->procA) return ptr->procA;
593 /**********************************************************************
594 * WINPROC_AllocProc16
596 * Allocate a window procedure for a window or class.
598 * Note that allocated winprocs are never freed; the idea is that even if an app creates a
599 * lot of windows, it will usually only have a limited number of window procedures, so the
600 * array won't grow too large, and this way we avoid the need to track allocations per window.
602 WNDPROC WINPROC_AllocProc16( WNDPROC16 func )
606 if (!func) return NULL;
608 /* check if the function is already a win proc */
609 if (!(proc = handle16_to_proc( func )))
611 EnterCriticalSection( &winproc_cs );
613 /* then check if we already have a winproc for that function */
614 if (!(proc = find_winproc16( func )))
616 if (winproc_used < MAX_WINPROCS)
618 proc = &winproc_array[winproc_used++];
620 TRACE( "allocated %p for %p/16-bit (%d/%d used)\n",
621 proc_to_handle(proc), func, winproc_used, MAX_WINPROCS );
623 else FIXME( "too many winprocs, cannot allocate one for 16-bit %p\n", func );
625 else TRACE( "reusing %p for %p/16-bit\n", proc_to_handle(proc), func );
627 LeaveCriticalSection( &winproc_cs );
629 return proc_to_handle( proc );
633 /**********************************************************************
636 * Allocate a window procedure for a window or class.
638 * Note that allocated winprocs are never freed; the idea is that even if an app creates a
639 * lot of windows, it will usually only have a limited number of window procedures, so the
640 * array won't grow too large, and this way we avoid the need to track allocations per window.
642 WNDPROC WINPROC_AllocProc( WNDPROC funcA, WNDPROC funcW )
646 if (!(proc = alloc_winproc( funcA, funcW ))) return NULL;
647 return proc_to_handle( proc );
651 /**********************************************************************
654 * Return the window procedure type, or the default value if not a winproc handle.
656 BOOL WINPROC_IsUnicode( WNDPROC proc, BOOL def_val )
658 WINDOWPROC *ptr = handle_to_proc( proc );
660 if (!ptr) return def_val;
661 if (ptr->procA && ptr->procW) return def_val; /* can be both */
662 return (ptr->procW != NULL);
666 /**********************************************************************
667 * WINPROC_TestLBForStr
669 * Return TRUE if the lparam is a string
671 inline static BOOL WINPROC_TestLBForStr( HWND hwnd, UINT msg )
673 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
674 if (msg <= CB_MSGMAX)
675 return (!(style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) || (style & CBS_HASSTRINGS));
677 return (!(style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) || (style & LBS_HASSTRINGS));
680 /**********************************************************************
681 * WINPROC_MapMsg32ATo32W
683 * Map a message from Ansi to Unicode.
684 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
687 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
688 * the first four bytes are the handle of the icon
689 * when the WM_SETTEXT message has been used to set the icon
691 static INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
696 case WM_ASKCBFORMATNAME:
698 LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0,
699 *pwparam * sizeof(WCHAR) + sizeof(LPARAM) );
701 *ptr++ = *plparam; /* Store previous lParam */
702 *plparam = (LPARAM)ptr;
705 /* lparam is string (0-terminated) */
707 case WM_WININICHANGE:
708 case WM_DEVMODECHANGE:
713 if (!*plparam) return 0;
716 DWORD len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)*plparam, -1, NULL, 0);
717 WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
718 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)*plparam, -1, buf, len);
719 *plparam = (LPARAM)buf;
720 return (*plparam ? 1 : -1);
722 case WM_GETTEXTLENGTH:
723 case CB_GETLBTEXTLEN:
725 return 1; /* need to map result */
729 UNICODE_STRING usBuffer;
731 { CREATESTRUCTW cs; /* new structure */
732 LPCWSTR lpszName; /* allocated Name */
733 LPCWSTR lpszClass; /* allocated Class */
736 struct s *xs = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct s));
738 xs->cs = *(CREATESTRUCTW *)*plparam;
739 if (HIWORD(xs->cs.lpszName))
741 RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)xs->cs.lpszName);
742 xs->lpszName = xs->cs.lpszName = usBuffer.Buffer;
744 if (HIWORD(xs->cs.lpszClass))
746 RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)xs->cs.lpszClass);
747 xs->lpszClass = xs->cs.lpszClass = usBuffer.Buffer;
750 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
752 MDICREATESTRUCTW *mdi_cs = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs));
753 *mdi_cs = *(MDICREATESTRUCTW *)xs->cs.lpCreateParams;
754 if (HIWORD(mdi_cs->szTitle))
756 RtlCreateUnicodeStringFromAsciiz(&usBuffer, (LPCSTR)mdi_cs->szTitle);
757 mdi_cs->szTitle = usBuffer.Buffer;
759 if (HIWORD(mdi_cs->szClass))
761 RtlCreateUnicodeStringFromAsciiz(&usBuffer, (LPCSTR)mdi_cs->szClass);
762 mdi_cs->szClass = usBuffer.Buffer;
764 xs->cs.lpCreateParams = mdi_cs;
767 *plparam = (LPARAM)xs;
772 MDICREATESTRUCTW *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
774 *cs = *(MDICREATESTRUCTW *)*plparam;
775 if (HIWORD(cs->szClass))
777 UNICODE_STRING usBuffer;
778 RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)cs->szClass);
779 cs->szClass = usBuffer.Buffer;
781 if (HIWORD(cs->szTitle))
783 UNICODE_STRING usBuffer;
784 RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)cs->szTitle);
785 cs->szTitle = usBuffer.Buffer;
787 *plparam = (LPARAM)cs;
791 /* Listbox / Combobox */
793 case LB_INSERTSTRING:
795 case LB_FINDSTRINGEXACT:
796 case LB_SELECTSTRING:
798 case CB_INSERTSTRING:
799 case CB_FINDSTRINGEXACT:
801 case CB_SELECTSTRING:
802 if(!*plparam) return 0;
803 if ( WINPROC_TestLBForStr( hwnd, msg ))
805 UNICODE_STRING usBuffer;
806 RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)*plparam);
807 *plparam = (LPARAM)usBuffer.Buffer;
809 return (*plparam ? 1 : -1);
811 case LB_GETTEXT: /* FIXME: fixed sized buffer */
813 if ( WINPROC_TestLBForStr( hwnd, msg ))
815 LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0, 512 * sizeof(WCHAR) + sizeof(LPARAM) );
817 *ptr++ = *plparam; /* Store previous lParam */
818 *plparam = (LPARAM)ptr;
824 { WORD len = (WORD)*plparam;
825 LPARAM *ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
827 *ptr++ = *plparam; /* Store previous lParam */
828 *((WORD *) ptr) = len; /* Store the length */
829 *plparam = (LPARAM)ptr;
839 case EM_SETPASSWORDCHAR:
840 *pwparam = map_wparam_char_AtoW( *pwparam, 1 );
844 *pwparam = map_wparam_char_AtoW( *pwparam, 2 );
847 case WM_PAINTCLIPBOARD:
848 case WM_SIZECLIPBOARD:
849 FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg, hwnd), msg );
851 default: /* No translation needed */
857 /**********************************************************************
858 * WINPROC_UnmapMsg32ATo32W
860 * Unmap a message that was mapped from Ansi to Unicode.
862 static LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
863 LRESULT result, WNDPROC dispatch )
868 case WM_ASKCBFORMATNAME:
870 LPARAM *ptr = (LPARAM *)lParam - 1;
871 if (!wParam) result = 0;
872 else if (!(result = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
873 (LPSTR)*ptr, wParam, NULL, NULL )))
875 ((LPSTR)*ptr)[wParam-1] = 0;
878 else result--; /* do not count terminating null */
879 HeapFree( GetProcessHeap(), 0, ptr );
882 case WM_GETTEXTLENGTH:
883 case CB_GETLBTEXTLEN:
887 /* Determine respective GETTEXT message */
889 (msg == WM_GETTEXTLENGTH) ? WM_GETTEXT :
890 ((msg == CB_GETLBTEXTLEN) ? CB_GETLBTEXT : LB_GETTEXT);
891 /* wParam differs between the messages */
892 WPARAM wp = (msg == WM_GETTEXTLENGTH) ? (WPARAM)(result + 1) : wParam;
894 WCHAR* p = HeapAlloc (GetProcessHeap(), 0, (result + 1) * sizeof(WCHAR));
901 n = WINPROC_CallWndProc(dispatch, hwnd, msgGetText, wp, (LPARAM)p);
903 n = SendMessageW (hwnd, msgGetText, wp, (LPARAM)p);
905 result = WideCharToMultiByte( CP_ACP, 0, p, n, NULL, 0, 0, NULL );
906 HeapFree (GetProcessHeap(), 0, p);
914 { CREATESTRUCTW cs; /* new structure */
915 LPWSTR lpszName; /* allocated Name */
916 LPWSTR lpszClass; /* allocated Class */
918 struct s *xs = (struct s *)lParam;
919 HeapFree( GetProcessHeap(), 0, xs->lpszName );
920 HeapFree( GetProcessHeap(), 0, xs->lpszClass );
922 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
924 MDICREATESTRUCTW *mdi_cs = (MDICREATESTRUCTW *)xs->cs.lpCreateParams;
925 if (HIWORD(mdi_cs->szTitle))
926 HeapFree(GetProcessHeap(), 0, (LPVOID)mdi_cs->szTitle);
927 if (HIWORD(mdi_cs->szClass))
928 HeapFree(GetProcessHeap(), 0, (LPVOID)mdi_cs->szClass);
929 HeapFree(GetProcessHeap(), 0, mdi_cs);
931 HeapFree( GetProcessHeap(), 0, xs );
937 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
938 if (HIWORD(cs->szTitle))
939 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
940 if (HIWORD(cs->szClass))
941 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
942 HeapFree( GetProcessHeap(), 0, cs );
947 case WM_WININICHANGE:
948 case WM_DEVMODECHANGE:
953 HeapFree( GetProcessHeap(), 0, (void *)lParam );
956 /* Listbox / Combobox */
958 case LB_INSERTSTRING:
960 case LB_FINDSTRINGEXACT:
961 case LB_SELECTSTRING:
963 case CB_INSERTSTRING:
965 case CB_FINDSTRINGEXACT:
966 case CB_SELECTSTRING:
967 if ( WINPROC_TestLBForStr( hwnd, msg ))
968 HeapFree( GetProcessHeap(), 0, (void *)lParam );
973 if ( WINPROC_TestLBForStr( hwnd, msg ))
975 LPARAM *ptr = (LPARAM *)lParam - 1;
977 result = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
978 (LPSTR)*ptr, 0x7fffffff, NULL, NULL ) - 1;
979 HeapFree( GetProcessHeap(), 0, ptr );
986 LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
987 WORD len = *(WORD *) lParam;
988 result = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, result,
989 (LPSTR)*ptr, len, NULL, NULL );
990 if (result < len) ((LPSTR)*ptr)[result] = 0;
991 HeapFree( GetProcessHeap(), 0, ptr );
999 static UINT convert_handle_16_to_32(HANDLE16 src, unsigned int flags)
1002 UINT sz = GlobalSize16(src);
1005 if (!(dst = GlobalAlloc(flags, sz)))
1007 ptr16 = GlobalLock16(src);
1008 ptr32 = GlobalLock(dst);
1009 if (ptr16 != NULL && ptr32 != NULL) memcpy(ptr32, ptr16, sz);
1010 GlobalUnlock16(src);
1016 /**********************************************************************
1017 * WINPROC_MapMsg16To32A
1019 * Map a message from 16- to 32-bit Ansi.
1020 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1022 INT WINPROC_MapMsg16To32A( HWND hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1023 WPARAM *pwparam32, LPARAM *plparam )
1025 *pmsg32 = (UINT)msg16;
1026 *pwparam32 = (WPARAM)wParam16;
1033 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1034 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1038 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1039 *plparam = (LPARAM)WIN_Handle32( HIWORD(*plparam) );
1042 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
1043 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
1044 *pwparam32 = (WPARAM)HDC_32(wParam16);
1045 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1047 case WM_COMPAREITEM:
1049 COMPAREITEMSTRUCT16* cis16 = MapSL(*plparam);
1050 COMPAREITEMSTRUCT *cis = HeapAlloc(GetProcessHeap(), 0, sizeof(*cis));
1051 if (!cis) return -1;
1052 cis->CtlType = cis16->CtlType;
1053 cis->CtlID = cis16->CtlID;
1054 cis->hwndItem = WIN_Handle32( cis16->hwndItem );
1055 cis->itemID1 = cis16->itemID1;
1056 cis->itemData1 = cis16->itemData1;
1057 cis->itemID2 = cis16->itemID2;
1058 cis->itemData2 = cis16->itemData2;
1059 cis->dwLocaleId = 0; /* FIXME */
1060 *plparam = (LPARAM)cis;
1065 PCOPYDATASTRUCT16 pcds16 = MapSL(*plparam);
1066 PCOPYDATASTRUCT pcds = HeapAlloc ( GetProcessHeap(), 0, sizeof(*pcds));
1067 pcds->dwData = pcds16->dwData;
1068 pcds->cbData = pcds16->cbData;
1069 pcds->lpData = MapSL( pcds16->lpData);
1070 *plparam = (LPARAM)pcds;
1075 DELETEITEMSTRUCT16* dis16 = MapSL(*plparam);
1076 DELETEITEMSTRUCT *dis = HeapAlloc(GetProcessHeap(), 0, sizeof(*dis));
1077 if (!dis) return -1;
1078 dis->CtlType = dis16->CtlType;
1079 dis->CtlID = dis16->CtlID;
1080 dis->hwndItem = WIN_Handle32( dis16->hwndItem );
1081 dis->itemData = dis16->itemData;
1082 *plparam = (LPARAM)dis;
1085 case WM_MEASUREITEM:
1087 MEASUREITEMSTRUCT16* mis16 = MapSL(*plparam);
1088 MEASUREITEMSTRUCT *mis = HeapAlloc(GetProcessHeap(), 0,
1089 sizeof(*mis) + sizeof(LPARAM));
1090 if (!mis) return -1;
1091 mis->CtlType = mis16->CtlType;
1092 mis->CtlID = mis16->CtlID;
1093 mis->itemID = mis16->itemID;
1094 mis->itemWidth = mis16->itemWidth;
1095 mis->itemHeight = mis16->itemHeight;
1096 mis->itemData = mis16->itemData;
1097 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1098 *plparam = (LPARAM)mis;
1103 DRAWITEMSTRUCT16* dis16 = MapSL(*plparam);
1104 DRAWITEMSTRUCT *dis = HeapAlloc(GetProcessHeap(), 0, sizeof(*dis));
1105 if (!dis) return -1;
1106 dis->CtlType = dis16->CtlType;
1107 dis->CtlID = dis16->CtlID;
1108 dis->itemID = dis16->itemID;
1109 dis->itemAction = dis16->itemAction;
1110 dis->itemState = dis16->itemState;
1111 dis->hwndItem = (dis->CtlType == ODT_MENU) ? (HWND)HMENU_32(dis16->hwndItem)
1112 : WIN_Handle32( dis16->hwndItem );
1113 dis->hDC = HDC_32(dis16->hDC);
1114 dis->itemData = dis16->itemData;
1115 dis->rcItem.left = dis16->rcItem.left;
1116 dis->rcItem.top = dis16->rcItem.top;
1117 dis->rcItem.right = dis16->rcItem.right;
1118 dis->rcItem.bottom = dis16->rcItem.bottom;
1119 *plparam = (LPARAM)dis;
1122 case WM_GETMINMAXINFO:
1124 MINMAXINFO *mmi = HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi) + sizeof(LPARAM));
1125 if (!mmi) return -1;
1126 MINMAXINFO16to32( MapSL(*plparam), mmi );
1127 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1128 *plparam = (LPARAM)mmi;
1133 case WM_WININICHANGE:
1134 case WM_DEVMODECHANGE:
1135 case WM_ASKCBFORMATNAME:
1136 *plparam = (LPARAM)MapSL(*plparam);
1140 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1141 MDICREATESTRUCTA *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1143 MDICREATESTRUCT16to32A( cs16, cs );
1144 cs->szTitle = MapSL(cs16->szTitle);
1145 cs->szClass = MapSL(cs16->szClass);
1146 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1147 *plparam = (LPARAM)cs;
1150 case WM_MDIGETACTIVE:
1151 *plparam = (LPARAM)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL) );
1152 *(BOOL*)(*plparam) = 0;
1155 if(wParam16) *pmsg32=WM_MDIREFRESHMENU;
1156 *pwparam32 = (WPARAM)HMENU_32(LOWORD(*plparam));
1157 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1160 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1161 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1164 if((LOWORD(*plparam) & MF_POPUP) && (LOWORD(*plparam) != 0xFFFF))
1166 HMENU hmenu=HMENU_32(HIWORD(*plparam));
1167 UINT Pos=MENU_FindSubMenu( &hmenu, HMENU_32(wParam16));
1168 if(Pos==0xFFFF) Pos=0; /* NO_SELECTED_ITEM */
1169 *pwparam32 = MAKEWPARAM( Pos, LOWORD(*plparam) );
1171 else *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1172 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1174 case WM_MDIACTIVATE:
1177 *pwparam32 = (WPARAM)WIN_Handle32( HIWORD(*plparam) );
1178 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1180 else /* message sent to MDI client */
1181 *pwparam32 = wParam16;
1185 NCCALCSIZE_PARAMS16 *nc16;
1186 NCCALCSIZE_PARAMS *nc;
1188 nc = HeapAlloc( GetProcessHeap(), 0, sizeof(*nc) + sizeof(LPARAM) );
1190 nc16 = MapSL(*plparam);
1191 nc->rgrc[0].left = nc16->rgrc[0].left;
1192 nc->rgrc[0].top = nc16->rgrc[0].top;
1193 nc->rgrc[0].right = nc16->rgrc[0].right;
1194 nc->rgrc[0].bottom = nc16->rgrc[0].bottom;
1197 nc->lppos = HeapAlloc( GetProcessHeap(), 0, sizeof(*nc->lppos) );
1198 nc->rgrc[1].left = nc16->rgrc[1].left;
1199 nc->rgrc[1].top = nc16->rgrc[1].top;
1200 nc->rgrc[1].right = nc16->rgrc[1].right;
1201 nc->rgrc[1].bottom = nc16->rgrc[1].bottom;
1202 nc->rgrc[2].left = nc16->rgrc[2].left;
1203 nc->rgrc[2].top = nc16->rgrc[2].top;
1204 nc->rgrc[2].right = nc16->rgrc[2].right;
1205 nc->rgrc[2].bottom = nc16->rgrc[2].bottom;
1206 if (nc->lppos) WINDOWPOS16to32( MapSL(nc16->lppos), nc->lppos );
1208 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1209 *plparam = (LPARAM)nc;
1215 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1216 CREATESTRUCTA *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1218 CREATESTRUCT16to32A( cs16, cs );
1219 cs->lpszName = MapSL(cs16->lpszName);
1220 cs->lpszClass = MapSL(cs16->lpszClass);
1222 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1224 MDICREATESTRUCT16 *mdi_cs16;
1225 MDICREATESTRUCTA *mdi_cs = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs));
1228 HeapFree(GetProcessHeap(), 0, cs);
1231 mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs16->lpCreateParams);
1232 MDICREATESTRUCT16to32A(mdi_cs16, mdi_cs);
1233 mdi_cs->szTitle = MapSL(mdi_cs16->szTitle);
1234 mdi_cs->szClass = MapSL(mdi_cs16->szClass);
1236 cs->lpCreateParams = mdi_cs;
1238 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1239 *plparam = (LPARAM)cs;
1242 case WM_PARENTNOTIFY:
1243 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1245 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1246 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1249 case WM_WINDOWPOSCHANGING:
1250 case WM_WINDOWPOSCHANGED:
1252 WINDOWPOS *wp = HeapAlloc( GetProcessHeap(), 0, sizeof(*wp) + sizeof(LPARAM) );
1254 WINDOWPOS16to32( MapSL(*plparam), wp );
1255 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1256 *plparam = (LPARAM)wp;
1262 LPMSG16 msg16 = MapSL(*plparam);
1263 LPMSG msg32 = HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1265 if (!msg32) return -1;
1266 msg32->hwnd = WIN_Handle32( msg16->hwnd );
1267 msg32->message = msg16->message;
1268 msg32->wParam = msg16->wParam;
1269 msg32->lParam = msg16->lParam;
1270 msg32->time = msg16->time;
1271 msg32->pt.x = msg16->pt.x;
1272 msg32->pt.y = msg16->pt.y;
1273 *plparam = (LPARAM)msg32;
1278 *plparam = (LPARAM)MapSL(*plparam);
1280 case WM_ACTIVATEAPP:
1281 /* We need this when SetActiveWindow sends a Sendmessage16() to
1282 * a 32bit window. Might be superflous with 32bit interprocess
1283 * message queues. */
1284 if (*plparam) *plparam = HTASK_32( *plparam );
1288 MDINEXTMENU *next = HeapAlloc( GetProcessHeap(), 0, sizeof(*next) );
1289 if (!next) return -1;
1290 next->hmenuIn = (HMENU)*plparam;
1291 next->hmenuNext = 0;
1293 *plparam = (LPARAM)next;
1296 case WM_PAINTCLIPBOARD:
1297 case WM_SIZECLIPBOARD:
1298 FIXME_(msg)("message %04x needs translation\n",msg16 );
1300 case WM_DDE_INITIATE:
1301 case WM_DDE_TERMINATE:
1302 case WM_DDE_UNADVISE:
1303 case WM_DDE_REQUEST:
1304 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1314 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1315 lo16 = LOWORD(*plparam);
1316 hi = HIWORD(*plparam);
1317 if (lo16 && !(lo32 = convert_handle_16_to_32(lo16, GMEM_DDESHARE)))
1319 *plparam = PackDDElParam(msg16, lo32, hi);
1321 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1328 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1330 lo = LOWORD(*plparam);
1331 hi = HIWORD(*plparam);
1333 if (GlobalGetAtomNameA(hi, buf, 2) > 0) flag |= 1;
1334 if (GlobalSize16(hi) != 0) flag |= 2;
1340 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1345 break; /* atom, nothing to do */
1347 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi);
1350 hi = convert_handle_16_to_32(hi, GMEM_DDESHARE);
1353 *plparam = PackDDElParam(WM_DDE_ACK, lo, hi);
1355 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1356 case WM_DDE_EXECUTE:
1357 *plparam = convert_handle_16_to_32(*plparam, GMEM_DDESHARE);
1358 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1359 default: /* No translation needed */
1365 /**********************************************************************
1366 * WINPROC_UnmapMsg16To32A
1368 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1370 LRESULT WINPROC_UnmapMsg16To32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1375 case WM_COMPAREITEM:
1379 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
1381 case WM_MEASUREITEM:
1383 MEASUREITEMSTRUCT16 *mis16;
1384 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1385 lParam = *(LPARAM *)(mis + 1);
1386 mis16 = MapSL(lParam);
1387 mis16->itemWidth = (UINT16)mis->itemWidth;
1388 mis16->itemHeight = (UINT16)mis->itemHeight;
1389 HeapFree( GetProcessHeap(), 0, mis );
1392 case WM_GETMINMAXINFO:
1394 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1395 lParam = *(LPARAM *)(mmi + 1);
1396 MINMAXINFO32to16( mmi, MapSL(lParam));
1397 HeapFree( GetProcessHeap(), 0, mmi );
1402 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1403 lParam = *(LPARAM *)(cs + 1);
1404 MDICREATESTRUCT32Ato16( cs, MapSL(lParam) );
1405 HeapFree( GetProcessHeap(), 0, cs );
1408 case WM_MDIGETACTIVE:
1409 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1410 HeapFree( GetProcessHeap(), 0, (BOOL *)lParam );
1414 NCCALCSIZE_PARAMS16 *nc16;
1415 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1416 lParam = *(LPARAM *)(nc + 1);
1417 nc16 = MapSL(lParam);
1418 nc16->rgrc[0].left = nc->rgrc[0].left;
1419 nc16->rgrc[0].top = nc->rgrc[0].top;
1420 nc16->rgrc[0].right = nc->rgrc[0].right;
1421 nc16->rgrc[0].bottom = nc->rgrc[0].bottom;
1424 nc16->rgrc[1].left = nc->rgrc[1].left;
1425 nc16->rgrc[1].top = nc->rgrc[1].top;
1426 nc16->rgrc[1].right = nc->rgrc[1].right;
1427 nc16->rgrc[1].bottom = nc->rgrc[1].bottom;
1428 nc16->rgrc[2].left = nc->rgrc[2].left;
1429 nc16->rgrc[2].top = nc->rgrc[2].top;
1430 nc16->rgrc[2].right = nc->rgrc[2].right;
1431 nc16->rgrc[2].bottom = nc->rgrc[2].bottom;
1434 WINDOWPOS32to16( nc->lppos, MapSL(nc16->lppos));
1435 HeapFree( GetProcessHeap(), 0, nc->lppos );
1438 HeapFree( GetProcessHeap(), 0, nc );
1444 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1445 lParam = *(LPARAM *)(cs + 1);
1446 CREATESTRUCT32Ato16( cs, MapSL(lParam) );
1448 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1449 HeapFree(GetProcessHeap(), 0, cs->lpCreateParams);
1451 HeapFree( GetProcessHeap(), 0, cs );
1454 case WM_WINDOWPOSCHANGING:
1455 case WM_WINDOWPOSCHANGED:
1457 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1458 lParam = *(LPARAM *)(wp + 1);
1459 WINDOWPOS32to16(wp, MapSL(lParam));
1460 HeapFree( GetProcessHeap(), 0, wp );
1466 LPMSG msg32 = (LPMSG)lParam;
1467 HeapFree( GetProcessHeap(), 0, msg32 );
1472 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
1473 result = MAKELONG( HMENU_16(next->hmenuNext), HWND_16(next->hwndNext) );
1474 HeapFree( GetProcessHeap(), 0, next );
1482 /**********************************************************************
1483 * WINPROC_MapMsg16To32W
1485 * Map a message from 16- to 32-bit Unicode.
1486 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1488 INT WINPROC_MapMsg16To32W( HWND hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1489 WPARAM *pwparam32, LPARAM *plparam )
1491 *pmsg32=(UINT)msg16;
1492 *pwparam32 = (WPARAM)wParam16;
1497 case WM_WININICHANGE:
1498 case WM_DEVMODECHANGE:
1499 case WM_ASKCBFORMATNAME:
1500 *plparam = (LPARAM)MapSL(*plparam);
1501 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, pwparam32, plparam );
1502 case WM_GETTEXTLENGTH:
1503 case CB_GETLBTEXTLEN:
1505 return 1; /* need to map result */
1509 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1510 CREATESTRUCTW *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1512 CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1513 cs->lpszName = map_str_16_to_32W(cs16->lpszName);
1514 cs->lpszClass = map_str_16_to_32W(cs16->lpszClass);
1516 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1518 MDICREATESTRUCT16 *mdi_cs16;
1519 MDICREATESTRUCTW *mdi_cs = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs));
1522 HeapFree(GetProcessHeap(), 0, cs);
1525 mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs16->lpCreateParams);
1526 MDICREATESTRUCT16to32A(mdi_cs16, (MDICREATESTRUCTA *)mdi_cs);
1527 mdi_cs->szTitle = map_str_16_to_32W(mdi_cs16->szTitle);
1528 mdi_cs->szClass = map_str_16_to_32W(mdi_cs16->szClass);
1530 cs->lpCreateParams = mdi_cs;
1532 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1533 *plparam = (LPARAM)cs;
1538 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1539 MDICREATESTRUCTW *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1541 MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1542 cs->szTitle = map_str_16_to_32W(cs16->szTitle);
1543 cs->szClass = map_str_16_to_32W(cs16->szClass);
1544 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1545 *plparam = (LPARAM)cs;
1551 LPMSG16 msg16 = MapSL(*plparam);
1552 LPMSG msg32 = HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1554 if (!msg32) return -1;
1555 msg32->hwnd = WIN_Handle32( msg16->hwnd );
1556 msg32->message = msg16->message;
1557 msg32->wParam = msg16->wParam;
1558 msg32->lParam = msg16->lParam;
1559 msg32->time = msg16->time;
1560 msg32->pt.x = msg16->pt.x;
1561 msg32->pt.y = msg16->pt.y;
1562 switch(msg32->message)
1567 case WM_SYSDEADCHAR:
1568 msg32->wParam = map_wparam_char_AtoW( msg16->wParam, 1 );
1571 *plparam = (LPARAM)msg32;
1577 *pwparam32 = MAKEWPARAM( map_wparam_char_AtoW( wParam16, 1 ), HIWORD(*plparam) );
1578 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1581 *pwparam32 = MAKEWPARAM( map_wparam_char_AtoW( wParam16, 1 ), LOWORD(*plparam) );
1582 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1587 case WM_SYSDEADCHAR:
1588 *pwparam32 = map_wparam_char_AtoW( wParam16, 1 );
1591 *pwparam32 = map_wparam_char_AtoW( wParam16, 2 );
1594 default: /* No Unicode translation needed */
1595 return WINPROC_MapMsg16To32A( hwnd, msg16, wParam16, pmsg32,
1596 pwparam32, plparam );
1601 /**********************************************************************
1602 * WINPROC_UnmapMsg16To32W
1604 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1606 LRESULT WINPROC_UnmapMsg16To32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1607 LRESULT result, WNDPROC dispatch )
1613 case WM_GETTEXTLENGTH:
1614 case CB_GETLBTEXTLEN:
1616 case WM_ASKCBFORMATNAME:
1617 return WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result, dispatch );
1621 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1622 lParam = *(LPARAM *)(cs + 1);
1623 CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs, MapSL(lParam) );
1624 unmap_str_16_to_32W( cs->lpszName );
1625 unmap_str_16_to_32W( cs->lpszClass );
1627 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1629 MDICREATESTRUCTW *mdi_cs = (MDICREATESTRUCTW *)cs->lpCreateParams;
1630 unmap_str_16_to_32W( mdi_cs->szTitle );
1631 unmap_str_16_to_32W( mdi_cs->szClass );
1632 HeapFree(GetProcessHeap(), 0, cs->lpCreateParams);
1634 HeapFree( GetProcessHeap(), 0, cs );
1639 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1640 lParam = *(LPARAM *)(cs + 1);
1641 MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs, MapSL(lParam) );
1642 unmap_str_16_to_32W( cs->szTitle );
1643 unmap_str_16_to_32W( cs->szClass );
1644 HeapFree( GetProcessHeap(), 0, cs );
1650 LPMSG msg32 = (LPMSG)lParam;
1651 HeapFree( GetProcessHeap(), 0, msg32 );
1655 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1660 static HANDLE16 convert_handle_32_to_16(UINT src, unsigned int flags)
1663 UINT sz = GlobalSize((HANDLE)src);
1666 if (!(dst = GlobalAlloc16(flags, sz)))
1668 ptr32 = GlobalLock((HANDLE)src);
1669 ptr16 = GlobalLock16(dst);
1670 if (ptr16 != NULL && ptr32 != NULL) memcpy(ptr16, ptr32, sz);
1671 GlobalUnlock((HANDLE)src);
1672 GlobalUnlock16(dst);
1678 /**********************************************************************
1679 * WINPROC_MapMsg32ATo16
1681 * Map a message from 32-bit Ansi to 16-bit.
1682 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1684 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1685 UINT16 *pmsg16, WPARAM16 *pwparam16,
1688 *pmsg16 = (UINT16)msg32;
1689 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1693 *pmsg16 = SBM_SETRANGE16;
1694 *plparam = MAKELPARAM(wParam32, *plparam);
1699 *pmsg16 = SBM_GETRANGE16;
1707 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1716 case EM_SCROLLCARET:
1719 case EM_GETLINECOUNT:
1731 case EM_LINEFROMCHAR:
1732 case EM_SETTABSTOPS:
1733 case EM_SETPASSWORDCHAR:
1734 case EM_EMPTYUNDOBUFFER:
1735 case EM_GETFIRSTVISIBLELINE:
1736 case EM_SETREADONLY:
1737 case EM_SETWORDBREAKPROC:
1738 case EM_GETWORDBREAKPROC:
1739 case EM_GETPASSWORDCHAR:
1740 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1745 case LB_DELETESTRING:
1746 case LB_GETANCHORINDEX:
1747 case LB_GETCARETINDEX:
1750 case LB_GETHORIZONTALEXTENT:
1751 case LB_GETITEMDATA:
1752 case LB_GETITEMHEIGHT:
1754 case LB_GETSELCOUNT:
1756 case LB_GETTOPINDEX:
1757 case LB_RESETCONTENT:
1758 case LB_SELITEMRANGE:
1759 case LB_SELITEMRANGEEX:
1760 case LB_SETANCHORINDEX:
1761 case LB_SETCARETINDEX:
1762 case LB_SETCOLUMNWIDTH:
1764 case LB_SETHORIZONTALEXTENT:
1765 case LB_SETITEMDATA:
1766 case LB_SETITEMHEIGHT:
1768 case LB_SETTOPINDEX:
1769 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1771 case CB_DELETESTRING:
1773 case CB_GETLBTEXTLEN:
1775 case CB_RESETCONTENT:
1779 case CB_SHOWDROPDOWN:
1780 case CB_SETITEMDATA:
1781 case CB_SETITEMHEIGHT:
1782 case CB_GETITEMHEIGHT:
1783 case CB_SETEXTENDEDUI:
1784 case CB_GETEXTENDEDUI:
1785 case CB_GETDROPPEDSTATE:
1786 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1789 *pmsg16 = CB_GETEDITSEL16;
1794 case LB_FINDSTRINGEXACT:
1795 case LB_INSERTSTRING:
1796 case LB_SELECTSTRING:
1799 *plparam = (LPARAM)MapLS( (LPSTR)*plparam );
1800 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1805 case CB_FINDSTRINGEXACT:
1806 case CB_INSERTSTRING:
1807 case CB_SELECTSTRING:
1809 *plparam = (LPARAM)MapLS( (LPSTR)*plparam );
1810 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1813 case LB_GETITEMRECT:
1815 RECT16 *rect = HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16) + sizeof(LPARAM) );
1816 if (!rect) return -1;
1817 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1818 *plparam = MapLS( rect );
1820 *pmsg16 = LB_GETITEMRECT16;
1822 case LB_GETSELITEMS:
1824 LPARAM *items; /* old LPARAM first, then *pwparam16 x INT16 entries */
1826 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1827 if (!(items = HeapAlloc( GetProcessHeap(), 0,
1828 *pwparam16 * sizeof(INT16) + sizeof(LPARAM)))) return -1;
1829 *items++ = *plparam; /* Store the previous lParam */
1830 *plparam = MapLS( items );
1832 *pmsg16 = LB_GETSELITEMS16;
1834 case LB_SETTABSTOPS:
1839 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1840 if (!(stops = HeapAlloc( GetProcessHeap(), 0,
1841 *pwparam16 * sizeof(INT16) + sizeof(LPARAM)))) return -1;
1842 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1843 *plparam = MapLS( stops );
1846 *pmsg16 = LB_SETTABSTOPS16;
1849 case CB_GETDROPPEDCONTROLRECT:
1851 RECT16 *rect = HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16) + sizeof(LPARAM) );
1852 if (!rect) return -1;
1853 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1854 *plparam = (LPARAM)MapLS(rect);
1856 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1860 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1861 *pmsg16 = LB_GETTEXT16;
1865 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1866 *pmsg16 = CB_GETLBTEXT16;
1871 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
1872 *pmsg16 = EM_SETSEL16;
1879 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1883 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1887 PCOPYDATASTRUCT pcds32 = (PCOPYDATASTRUCT) *plparam;
1888 PCOPYDATASTRUCT16 pcds = HeapAlloc( GetProcessHeap(), 0, sizeof( *pcds));
1889 pcds->dwData = pcds32->dwData;
1890 pcds->cbData = pcds32->cbData;
1891 pcds->lpData = MapLS( pcds32->lpData);
1892 *plparam = MapLS( pcds );
1895 case WM_CTLCOLORMSGBOX:
1896 case WM_CTLCOLOREDIT:
1897 case WM_CTLCOLORLISTBOX:
1898 case WM_CTLCOLORBTN:
1899 case WM_CTLCOLORDLG:
1900 case WM_CTLCOLORSCROLLBAR:
1901 case WM_CTLCOLORSTATIC:
1902 *pmsg16 = WM_CTLCOLOR;
1903 *plparam = MAKELPARAM( (HWND16)*plparam,
1904 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1906 case WM_COMPAREITEM:
1908 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
1909 COMPAREITEMSTRUCT16 *cis = HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16));
1910 if (!cis) return -1;
1911 cis->CtlType = (UINT16)cis32->CtlType;
1912 cis->CtlID = (UINT16)cis32->CtlID;
1913 cis->hwndItem = HWND_16( cis32->hwndItem );
1914 cis->itemID1 = (UINT16)cis32->itemID1;
1915 cis->itemData1 = cis32->itemData1;
1916 cis->itemID2 = (UINT16)cis32->itemID2;
1917 cis->itemData2 = cis32->itemData2;
1918 *plparam = MapLS( cis );
1923 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
1924 DELETEITEMSTRUCT16 *dis = HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16) );
1925 if (!dis) return -1;
1926 dis->CtlType = (UINT16)dis32->CtlType;
1927 dis->CtlID = (UINT16)dis32->CtlID;
1928 dis->itemID = (UINT16)dis32->itemID;
1929 dis->hwndItem = (dis->CtlType == ODT_MENU) ? (HWND16)LOWORD(dis32->hwndItem)
1930 : HWND_16( dis32->hwndItem );
1931 dis->itemData = dis32->itemData;
1932 *plparam = MapLS( dis );
1937 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
1938 DRAWITEMSTRUCT16 *dis = HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16) );
1939 if (!dis) return -1;
1940 dis->CtlType = (UINT16)dis32->CtlType;
1941 dis->CtlID = (UINT16)dis32->CtlID;
1942 dis->itemID = (UINT16)dis32->itemID;
1943 dis->itemAction = (UINT16)dis32->itemAction;
1944 dis->itemState = (UINT16)dis32->itemState;
1945 dis->hwndItem = HWND_16( dis32->hwndItem );
1946 dis->hDC = HDC_16(dis32->hDC);
1947 dis->itemData = dis32->itemData;
1948 dis->rcItem.left = dis32->rcItem.left;
1949 dis->rcItem.top = dis32->rcItem.top;
1950 dis->rcItem.right = dis32->rcItem.right;
1951 dis->rcItem.bottom = dis32->rcItem.bottom;
1952 *plparam = MapLS( dis );
1955 case WM_MEASUREITEM:
1957 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
1958 MEASUREITEMSTRUCT16 *mis = HeapAlloc( GetProcessHeap(), 0, sizeof(*mis)+sizeof(LPARAM));
1959 if (!mis) return -1;
1960 mis->CtlType = (UINT16)mis32->CtlType;
1961 mis->CtlID = (UINT16)mis32->CtlID;
1962 mis->itemID = (UINT16)mis32->itemID;
1963 mis->itemWidth = (UINT16)mis32->itemWidth;
1964 mis->itemHeight = (UINT16)mis32->itemHeight;
1965 mis->itemData = mis32->itemData;
1966 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1967 *plparam = MapLS( mis );
1970 case WM_GETMINMAXINFO:
1972 MINMAXINFO16 *mmi = HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi) + sizeof(LPARAM) );
1973 if (!mmi) return -1;
1974 MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
1975 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1976 *plparam = MapLS( mmi );
1980 case WM_ASKCBFORMATNAME:
1982 LPARAM *str; /* store LPARAM, then *pwparam16 char space */
1983 *pwparam16 = (WPARAM16)min( wParam32, 0xff80 ); /* Must be < 64K */
1984 if (!(str = HeapAlloc( GetProcessHeap(), 0, *pwparam16 + sizeof(LPARAM)))) return -1;
1985 *str++ = *plparam; /* Store the previous lParam */
1986 *plparam = MapLS( str );
1991 MDICREATESTRUCT16 *cs;
1992 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
1994 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16) ))) return -1;
1995 MDICREATESTRUCT32Ato16( cs32, cs );
1996 cs->szTitle = MapLS( cs32->szTitle );
1997 cs->szClass = MapLS( cs32->szClass );
1998 *plparam = MapLS( cs );
2001 case WM_MDIGETACTIVE:
2004 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
2005 (HMENU16)LOWORD(*plparam) );
2006 *pwparam16 = (*plparam == 0);
2009 if(HIWORD(wParam32) & MF_POPUP)
2012 if (((UINT)HIWORD(wParam32) != 0xFFFF) || (*plparam))
2014 if((hmenu = GetSubMenu((HMENU)*plparam, *pwparam16)))
2015 *pwparam16=HMENU_16(hmenu);
2020 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
2022 case WM_MDIACTIVATE:
2023 if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_MDICHILD)
2025 *pwparam16 = ((HWND)*plparam == hwnd);
2026 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
2027 (HWND16)LOWORD(wParam32) );
2031 *pwparam16 = HWND_16( (HWND)wParam32 );
2037 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
2038 NCCALCSIZE_PARAMS16 *nc = HeapAlloc( GetProcessHeap(), 0, sizeof(*nc) + sizeof(LPARAM));
2041 nc->rgrc[0].left = nc32->rgrc[0].left;
2042 nc->rgrc[0].top = nc32->rgrc[0].top;
2043 nc->rgrc[0].right = nc32->rgrc[0].right;
2044 nc->rgrc[0].bottom = nc32->rgrc[0].bottom;
2048 nc->rgrc[1].left = nc32->rgrc[1].left;
2049 nc->rgrc[1].top = nc32->rgrc[1].top;
2050 nc->rgrc[1].right = nc32->rgrc[1].right;
2051 nc->rgrc[1].bottom = nc32->rgrc[1].bottom;
2052 nc->rgrc[2].left = nc32->rgrc[2].left;
2053 nc->rgrc[2].top = nc32->rgrc[2].top;
2054 nc->rgrc[2].right = nc32->rgrc[2].right;
2055 nc->rgrc[2].bottom = nc32->rgrc[2].bottom;
2056 if (!(wp = HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16) )))
2058 HeapFree( GetProcessHeap(), 0, nc );
2061 WINDOWPOS32to16( nc32->lppos, wp );
2062 nc->lppos = MapLS( wp );
2064 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
2065 *plparam = MapLS( nc );
2072 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
2074 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16) ))) return -1;
2075 CREATESTRUCT32Ato16( cs32, cs );
2076 cs->lpszName = MapLS( cs32->lpszName );
2077 cs->lpszClass = MapLS( cs32->lpszClass );
2079 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2081 MDICREATESTRUCT16 *mdi_cs16;
2082 MDICREATESTRUCTA *mdi_cs = (MDICREATESTRUCTA *)cs32->lpCreateParams;
2083 mdi_cs16 = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs16));
2086 HeapFree(GetProcessHeap(), 0, cs);
2089 MDICREATESTRUCT32Ato16(mdi_cs, mdi_cs16);
2090 mdi_cs16->szTitle = MapLS( mdi_cs->szTitle );
2091 mdi_cs16->szClass = MapLS( mdi_cs->szClass );
2092 cs->lpCreateParams = MapLS( mdi_cs16 );
2094 *plparam = MapLS( cs );
2097 case WM_PARENTNOTIFY:
2098 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
2099 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
2100 /* else nothing to do */
2103 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
2106 case WM_WININICHANGE:
2107 case WM_DEVMODECHANGE:
2108 *plparam = MapLS( (LPSTR)*plparam );
2110 case WM_WINDOWPOSCHANGING:
2111 case WM_WINDOWPOSCHANGED:
2113 WINDOWPOS16 *wp = HeapAlloc( GetProcessHeap(), 0, sizeof(*wp) + sizeof(LPARAM) );
2115 WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
2116 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
2117 *plparam = MapLS( wp );
2122 LPMSG msg32 = (LPMSG) *plparam;
2123 LPMSG16 msg16 = HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16) );
2125 if (!msg16) return -1;
2126 msg16->hwnd = HWND_16( msg32->hwnd );
2127 msg16->message = msg32->message;
2128 msg16->wParam = msg32->wParam;
2129 msg16->lParam = msg32->lParam;
2130 msg16->time = msg32->time;
2131 msg16->pt.x = msg32->pt.x;
2132 msg16->pt.y = msg32->pt.y;
2133 *plparam = MapLS( msg16 );
2138 case WM_ACTIVATEAPP:
2139 if (*plparam) *plparam = HTASK_16( (HANDLE)*plparam );
2143 MDINEXTMENU *next = (MDINEXTMENU *)*plparam;
2144 *plparam = (LPARAM)next->hmenuIn;
2148 if (IsIconic( hwnd ) && GetClassLongPtrW( hwnd, GCLP_HICON ))
2150 *pmsg16 = WM_PAINTICON;
2155 if (IsIconic( hwnd ) && GetClassLongPtrW( hwnd, GCLP_HICON ))
2156 *pmsg16 = WM_ICONERASEBKGND;
2158 case WM_PAINTCLIPBOARD:
2159 case WM_SIZECLIPBOARD:
2160 FIXME_(msg)("message %04x needs translation\n", msg32 );
2162 /* following messages should not be sent to 16-bit apps */
2165 case WM_CAPTURECHANGED:
2166 case WM_STYLECHANGING:
2167 case WM_STYLECHANGED:
2169 case WM_DDE_INITIATE:
2170 case WM_DDE_TERMINATE:
2171 case WM_DDE_UNADVISE:
2172 case WM_DDE_REQUEST:
2173 *pwparam16 = HWND_16((HWND)wParam32);
2182 *pwparam16 = HWND_16((HWND)wParam32);
2183 UnpackDDElParam(msg32, *plparam, &lo32, &hi);
2184 if (lo32 && !(lo16 = convert_handle_32_to_16(lo32, GMEM_DDESHARE)))
2186 *plparam = MAKELPARAM(lo16, hi);
2188 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2195 *pwparam16 = HWND_16((HWND)wParam32);
2197 UnpackDDElParam(msg32, *plparam, &lo, &hi);
2199 if (GlobalGetAtomNameA((ATOM)hi, buf, sizeof(buf)) > 0) flag |= 1;
2200 if (GlobalSize((HANDLE)hi) != 0) flag |= 2;
2206 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
2211 break; /* atom, nothing to do */
2213 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi);
2216 hi = convert_handle_32_to_16(hi, GMEM_DDESHARE);
2219 *plparam = MAKELPARAM(lo, hi);
2221 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2222 case WM_DDE_EXECUTE:
2223 *plparam = convert_handle_32_to_16(*plparam, GMEM_DDESHARE);
2224 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2225 default: /* No translation needed */
2231 /**********************************************************************
2232 * WINPROC_UnmapMsg32ATo16
2234 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2236 void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2242 *(LPINT)wParam = LOWORD(p16->lResult);
2243 *(LPINT)lParam = HIWORD(p16->lResult);
2250 case LB_FINDSTRINGEXACT:
2251 case LB_INSERTSTRING:
2252 case LB_SELECTSTRING:
2256 case CB_FINDSTRINGEXACT:
2257 case CB_INSERTSTRING:
2258 case CB_SELECTSTRING:
2262 case WM_WININICHANGE:
2263 case WM_DEVMODECHANGE:
2264 UnMapLS( (SEGPTR)p16->lParam );
2266 case LB_SETTABSTOPS:
2267 case WM_COMPAREITEM:
2271 void *ptr = MapSL( p16->lParam );
2272 UnMapLS( p16->lParam );
2273 HeapFree( GetProcessHeap(), 0, ptr );
2278 PCOPYDATASTRUCT16 pcds = MapSL( p16->lParam );
2279 UnMapLS( p16->lParam );
2280 UnMapLS( pcds->lpData );
2281 HeapFree( GetProcessHeap(), 0, pcds );
2284 case CB_GETDROPPEDCONTROLRECT:
2285 case LB_GETITEMRECT:
2288 RECT16 *rect = MapSL(p16->lParam);
2289 UnMapLS( p16->lParam );
2290 p16->lParam = *(LPARAM *)(rect + 1);
2291 r32 = (RECT *)p16->lParam;
2292 r32->left = rect->left;
2293 r32->top = rect->top;
2294 r32->right = rect->right;
2295 r32->bottom = rect->bottom;
2296 HeapFree( GetProcessHeap(), 0, rect );
2299 case LB_GETSELITEMS:
2302 LPINT16 items = MapSL(p16->lParam);
2303 UnMapLS( p16->lParam );
2304 p16->lParam = *((LPARAM *)items - 1);
2305 for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
2306 HeapFree( GetProcessHeap(), 0, (LPARAM *)items - 1 );
2312 *((PUINT)(wParam)) = LOWORD(p16->lResult);
2314 *((PUINT)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
2317 case WM_MEASUREITEM:
2319 MEASUREITEMSTRUCT16 *mis = MapSL(p16->lParam);
2320 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
2321 mis32->itemWidth = mis->itemWidth;
2322 mis32->itemHeight = mis->itemHeight;
2323 UnMapLS( p16->lParam );
2324 HeapFree( GetProcessHeap(), 0, mis );
2327 case WM_GETMINMAXINFO:
2329 MINMAXINFO16 *mmi = MapSL(p16->lParam);
2330 UnMapLS( p16->lParam );
2331 p16->lParam = *(LPARAM *)(mmi + 1);
2332 MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
2333 HeapFree( GetProcessHeap(), 0, mmi );
2337 case WM_ASKCBFORMATNAME:
2339 LPSTR str = MapSL(p16->lParam);
2340 UnMapLS( p16->lParam );
2341 p16->lParam = *((LPARAM *)str - 1);
2342 lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
2343 HeapFree( GetProcessHeap(), 0, (LPARAM *)str - 1 );
2348 MDICREATESTRUCT16 *cs = MapSL(p16->lParam);
2349 UnMapLS( cs->szTitle );
2350 UnMapLS( cs->szClass );
2351 UnMapLS( p16->lParam );
2352 HeapFree( GetProcessHeap(), 0, cs );
2355 case WM_MDIGETACTIVE:
2356 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
2357 p16->lResult = (LRESULT)WIN_Handle32( LOWORD(p16->lResult) );
2361 NCCALCSIZE_PARAMS *nc32;
2362 NCCALCSIZE_PARAMS16 *nc = MapSL(p16->lParam);
2363 UnMapLS( p16->lParam );
2364 p16->lParam = *(LPARAM *)(nc + 1);
2365 nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
2366 nc32->rgrc[0].left = nc->rgrc[0].left;
2367 nc32->rgrc[0].top = nc->rgrc[0].top;
2368 nc32->rgrc[0].right = nc->rgrc[0].right;
2369 nc32->rgrc[0].bottom = nc->rgrc[0].bottom;
2372 WINDOWPOS16 *pos = MapSL(nc->lppos);
2373 UnMapLS( nc->lppos );
2374 nc32->rgrc[1].left = nc->rgrc[1].left;
2375 nc32->rgrc[1].top = nc->rgrc[1].top;
2376 nc32->rgrc[1].right = nc->rgrc[1].right;
2377 nc32->rgrc[1].bottom = nc->rgrc[1].bottom;
2378 nc32->rgrc[2].left = nc->rgrc[2].left;
2379 nc32->rgrc[2].top = nc->rgrc[2].top;
2380 nc32->rgrc[2].right = nc->rgrc[2].right;
2381 nc32->rgrc[2].bottom = nc->rgrc[2].bottom;
2382 WINDOWPOS16to32( pos, nc32->lppos );
2383 HeapFree( GetProcessHeap(), 0, pos );
2385 HeapFree( GetProcessHeap(), 0, nc );
2391 CREATESTRUCT16 *cs = MapSL(p16->lParam);
2392 UnMapLS( p16->lParam );
2393 UnMapLS( cs->lpszName );
2394 UnMapLS( cs->lpszClass );
2395 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2397 MDICREATESTRUCT16 *mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs->lpCreateParams);
2398 UnMapLS( cs->lpCreateParams );
2399 UnMapLS( mdi_cs16->szTitle );
2400 UnMapLS( mdi_cs16->szClass );
2401 HeapFree(GetProcessHeap(), 0, mdi_cs16);
2403 HeapFree( GetProcessHeap(), 0, cs );
2406 case WM_WINDOWPOSCHANGING:
2407 case WM_WINDOWPOSCHANGED:
2409 WINDOWPOS16 *wp = MapSL(p16->lParam);
2410 UnMapLS( p16->lParam );
2411 p16->lParam = *(LPARAM *)(wp + 1);
2412 WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
2413 HeapFree( GetProcessHeap(), 0, wp );
2417 UnMapLS(p16->lParam);
2422 LPMSG16 msg16 = MapSL(p16->lParam);
2423 UnMapLS( p16->lParam );
2424 HeapFree( GetProcessHeap(), 0, msg16 );
2429 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
2430 next->hmenuNext = HMENU_32( LOWORD(p16->lResult) );
2431 next->hwndNext = WIN_Handle32( HIWORD(p16->lResult) );
2439 /**********************************************************************
2440 * WINPROC_MapMsg32WTo16
2442 * Map a message from 32-bit Unicode to 16-bit.
2443 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2445 INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
2446 UINT16 *pmsg16, WPARAM16 *pwparam16,
2449 *pmsg16 = LOWORD(msg32);
2450 *pwparam16 = LOWORD(wParam32);
2455 case LB_FINDSTRINGEXACT:
2456 case LB_INSERTSTRING:
2457 case LB_SELECTSTRING:
2460 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2461 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2466 case CB_FINDSTRINGEXACT:
2467 case CB_INSERTSTRING:
2468 case CB_SELECTSTRING:
2470 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2471 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2478 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2480 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16) ))) return -1;
2481 CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2482 cs->lpszName = map_str_32W_to_16( cs32->lpszName );
2483 cs->lpszClass = map_str_32W_to_16( cs32->lpszClass );
2485 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2487 MDICREATESTRUCT16 *mdi_cs16;
2488 MDICREATESTRUCTW *mdi_cs = (MDICREATESTRUCTW *)cs32->lpCreateParams;
2489 mdi_cs16 = HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs16));
2492 HeapFree(GetProcessHeap(), 0, cs);
2495 MDICREATESTRUCT32Ato16((MDICREATESTRUCTA *)mdi_cs, mdi_cs16);
2496 mdi_cs16->szTitle = map_str_32W_to_16(mdi_cs->szTitle);
2497 mdi_cs16->szClass = map_str_32W_to_16(mdi_cs->szClass);
2498 cs->lpCreateParams = MapLS(mdi_cs16);
2500 *plparam = MapLS(cs);
2505 MDICREATESTRUCT16 *cs;
2506 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2508 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16) ))) return -1;
2509 MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2510 cs->szTitle = map_str_32W_to_16( cs32->szTitle );
2511 cs->szClass = map_str_32W_to_16( cs32->szClass );
2512 *plparam = MapLS(cs);
2516 case WM_WININICHANGE:
2517 case WM_DEVMODECHANGE:
2518 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2522 if ( WINPROC_TestLBForStr( hwnd, msg32 ))
2524 LPSTR str = HeapAlloc( GetProcessHeap(), 0, 512 ); /* FIXME: fixed sized buffer */
2525 if (!str) return -1;
2526 *pmsg16 = (msg32 == LB_GETTEXT) ? LB_GETTEXT16 : CB_GETLBTEXT16;
2527 *plparam = (LPARAM)MapLS(str);
2532 *pwparam16 = map_wparam_char_WtoA( wParam32, 1 );
2533 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
2536 *pwparam16 = map_wparam_char_WtoA( wParam32, 1 );
2537 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
2542 case WM_SYSDEADCHAR:
2543 *pwparam16 = map_wparam_char_WtoA( wParam32, 1 );
2546 *pwparam16 = map_wparam_char_WtoA( wParam32, 2 );
2549 default: /* No Unicode translation needed (?) */
2550 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2551 pwparam16, plparam );
2556 /**********************************************************************
2557 * WINPROC_UnmapMsg32WTo16
2559 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2561 void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2568 case LB_FINDSTRINGEXACT:
2569 case LB_INSERTSTRING:
2570 case LB_SELECTSTRING:
2575 case CB_FINDSTRINGEXACT:
2576 case CB_INSERTSTRING:
2577 case CB_SELECTSTRING:
2580 case WM_WININICHANGE:
2581 case WM_DEVMODECHANGE:
2582 unmap_str_32W_to_16( p16->lParam );
2587 CREATESTRUCT16 *cs = MapSL(p16->lParam);
2588 UnMapLS( p16->lParam );
2589 unmap_str_32W_to_16( cs->lpszName );
2590 unmap_str_32W_to_16( cs->lpszClass );
2592 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2594 MDICREATESTRUCT16 *mdi_cs16 = (MDICREATESTRUCT16 *)MapSL(cs->lpCreateParams);
2595 UnMapLS( cs->lpCreateParams );
2596 unmap_str_32W_to_16(mdi_cs16->szTitle);
2597 unmap_str_32W_to_16(mdi_cs16->szClass);
2598 HeapFree(GetProcessHeap(), 0, mdi_cs16);
2600 HeapFree( GetProcessHeap(), 0, cs );
2605 MDICREATESTRUCT16 *cs = MapSL(p16->lParam);
2606 UnMapLS( p16->lParam );
2607 unmap_str_32W_to_16( cs->szTitle );
2608 unmap_str_32W_to_16( cs->szClass );
2609 HeapFree( GetProcessHeap(), 0, cs );
2613 case WM_ASKCBFORMATNAME:
2615 LPSTR str = MapSL(p16->lParam);
2616 UnMapLS( p16->lParam );
2617 p16->lParam = *((LPARAM *)str - 1);
2618 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)p16->lParam, 0x7fffffff );
2619 p16->lResult = strlenW( (LPWSTR)p16->lParam );
2620 HeapFree( GetProcessHeap(), 0, (LPARAM *)str - 1 );
2625 if ( WINPROC_TestLBForStr( hwnd, msg ))
2627 LPSTR str = MapSL(p16->lParam);
2628 UnMapLS( p16->lParam );
2629 p16->lResult = MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)lParam, 0x7fffffff ) - 1;
2630 HeapFree( GetProcessHeap(), 0, (LPARAM *)str );
2634 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2640 /**********************************************************************
2641 * WINPROC_CallProcAtoW
2643 * Call a window procedure, translating args from Ansi to Unicode.
2645 LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg, WPARAM wParam,
2646 LPARAM lParam, LRESULT *result, void *arg )
2651 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2652 hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
2654 if( (unmap = WINPROC_MapMsg32ATo32W( hwnd, msg, &wParam, &lParam )) == -1) {
2655 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2656 SPY_GetMsgName(msg, hwnd), wParam, lParam );
2659 ret = callback( hwnd, msg, wParam, lParam, result, arg );
2661 *result = WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, *result,
2662 (callback == call_window_proc) ? arg : NULL /*FIXME: hack*/ );
2667 static inline void *get_buffer( void *static_buffer, size_t size, size_t need )
2669 if (size >= need) return static_buffer;
2670 return HeapAlloc( GetProcessHeap(), 0, need );
2673 static inline void free_buffer( void *static_buffer, void *buffer )
2675 if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
2678 /**********************************************************************
2679 * WINPROC_CallProcWtoA
2681 * Call a window procedure, translating args from Unicode to Ansi.
2683 static LRESULT WINPROC_CallProcWtoA( winproc_callback_t callback, HWND hwnd, UINT msg, WPARAM wParam,
2684 LPARAM lParam, LRESULT *result, void *arg )
2688 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2689 hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
2695 { /* csW->lpszName and csW->lpszClass are NOT supposed to be atoms
2698 char buffer[1024], *cls, *name;
2699 CREATESTRUCTW *csW = (CREATESTRUCTW *)lParam;
2700 CREATESTRUCTA csA = *(CREATESTRUCTA *)csW;
2701 MDICREATESTRUCTA mdi_cs;
2702 DWORD name_lenA, name_lenW, class_lenA, class_lenW;
2704 class_lenW = strlenW(csW->lpszClass) * sizeof(WCHAR);
2705 RtlUnicodeToMultiByteSize(&class_lenA, csW->lpszClass, class_lenW);
2709 name_lenW = strlenW(csW->lpszName) * sizeof(WCHAR);
2710 RtlUnicodeToMultiByteSize(&name_lenA, csW->lpszName, name_lenW);
2713 name_lenW = name_lenA = 0;
2715 if (!(cls = get_buffer( buffer, sizeof(buffer), class_lenA + name_lenA + 2 ))) break;
2717 RtlUnicodeToMultiByteN(cls, class_lenA, NULL, csW->lpszClass, class_lenW);
2718 cls[class_lenA] = 0;
2719 csA.lpszClass = cls;
2723 name = cls + class_lenA + 1;
2724 RtlUnicodeToMultiByteN(name, name_lenA, NULL, csW->lpszName, name_lenW);
2725 name[name_lenA] = 0;
2726 csA.lpszName = name;
2729 if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
2731 mdi_cs = *(MDICREATESTRUCTA *)csW->lpCreateParams;
2732 mdi_cs.szTitle = csA.lpszName;
2733 mdi_cs.szClass = csA.lpszClass;
2734 csA.lpCreateParams = &mdi_cs;
2737 ret = callback( hwnd, msg, wParam, (LPARAM)&csA, result, arg );
2738 free_buffer( buffer, cls );
2743 case WM_ASKCBFORMATNAME:
2745 char *ptr, buffer[512];
2746 DWORD len = wParam * 2;
2748 if (!(ptr = get_buffer( buffer, sizeof(buffer), len ))) break;
2749 ret = callback( hwnd, msg, wParam, (LPARAM)ptr, result, arg );
2752 RtlMultiByteToUnicodeN( (LPWSTR)lParam, wParam*sizeof(WCHAR), &len, ptr, strlen(ptr)+1 );
2753 *result = len/sizeof(WCHAR) - 1; /* do not count terminating null */
2754 ((LPWSTR)lParam)[*result] = 0;
2756 free_buffer( buffer, ptr );
2761 case LB_INSERTSTRING:
2763 case LB_FINDSTRINGEXACT:
2764 case LB_SELECTSTRING:
2766 case CB_INSERTSTRING:
2768 case CB_FINDSTRINGEXACT:
2769 case CB_SELECTSTRING:
2770 if (!lParam || !WINPROC_TestLBForStr( hwnd, msg ))
2772 ret = callback( hwnd, msg, wParam, lParam, result, arg );
2777 case WM_WININICHANGE:
2778 case WM_DEVMODECHANGE:
2783 if (!lParam) ret = callback( hwnd, msg, wParam, lParam, result, arg );
2786 char *ptr, buffer[512];
2787 LPCWSTR strW = (LPCWSTR)lParam;
2788 DWORD lenA, lenW = (strlenW(strW) + 1) * sizeof(WCHAR);
2790 RtlUnicodeToMultiByteSize( &lenA, strW, lenW );
2791 if ((ptr = get_buffer( buffer, sizeof(buffer), lenA )))
2793 RtlUnicodeToMultiByteN( ptr, lenA, NULL, strW, lenW );
2794 ret = callback( hwnd, msg, wParam, (LPARAM)ptr, result, arg );
2795 free_buffer( buffer, ptr );
2802 char *ptr, buffer[1024];
2803 DWORD title_lenA = 0, title_lenW = 0, class_lenA = 0, class_lenW = 0;
2804 MDICREATESTRUCTW *csW = (MDICREATESTRUCTW *)lParam;
2805 MDICREATESTRUCTA csA;
2807 memcpy( &csA, csW, sizeof(csA) );
2809 if (HIWORD(csW->szTitle))
2811 title_lenW = (strlenW(csW->szTitle) + 1) * sizeof(WCHAR);
2812 RtlUnicodeToMultiByteSize( &title_lenA, csW->szTitle, title_lenW );
2814 if (HIWORD(csW->szClass))
2816 class_lenW = (strlenW(csW->szClass) + 1) * sizeof(WCHAR);
2817 RtlUnicodeToMultiByteSize( &class_lenA, csW->szClass, class_lenW );
2820 if (!(ptr = get_buffer( buffer, sizeof(buffer), title_lenA + class_lenA ))) break;
2824 RtlUnicodeToMultiByteN( ptr, title_lenA, NULL, csW->szTitle, title_lenW );
2829 RtlUnicodeToMultiByteN( ptr + title_lenA, class_lenA, NULL, csW->szClass, class_lenW );
2830 csA.szClass = ptr + title_lenA;
2832 ret = callback( hwnd, msg, wParam, (LPARAM)&csA, result, arg );
2833 free_buffer( buffer, ptr );
2839 if (lParam && WINPROC_TestLBForStr( hwnd, msg ))
2841 char buffer[512]; /* FIXME: fixed sized buffer */
2843 ret = callback( hwnd, msg, wParam, (LPARAM)buffer, result, arg );
2847 RtlMultiByteToUnicodeN( (LPWSTR)lParam, ~0u, &len, buffer, strlen(buffer) + 1 );
2848 *result = len / sizeof(WCHAR) - 1;
2851 else ret = callback( hwnd, msg, wParam, lParam, result, arg );
2856 char *ptr, buffer[512];
2857 WORD len = *(WORD *)lParam;
2859 if (!(ptr = get_buffer( buffer, sizeof(buffer), len * 2 ))) break;
2860 *((WORD *)ptr) = len * 2; /* store the length */
2861 ret = callback( hwnd, msg, wParam, (LPARAM)ptr, result, arg );
2865 RtlMultiByteToUnicodeN( (LPWSTR)lParam, len*sizeof(WCHAR), &reslen, buffer, *result );
2866 *result = reslen / sizeof(WCHAR);
2867 if (*result < len) ((LPWSTR)lParam)[*result] = 0;
2869 free_buffer( buffer, ptr );
2878 case WM_SYSDEADCHAR:
2879 case EM_SETPASSWORDCHAR:
2880 ret = callback( hwnd, msg, map_wparam_char_WtoA(wParam,1), lParam, result, arg );
2884 ret = callback( hwnd, msg, map_wparam_char_WtoA(wParam,2), lParam, result, arg );
2887 case WM_PAINTCLIPBOARD:
2888 case WM_SIZECLIPBOARD:
2889 FIXME_(msg)( "message %s (%04x) needs translation, please report\n",
2890 SPY_GetMsgName(msg, hwnd), msg );
2894 ret = callback( hwnd, msg, wParam, lParam, result, arg );
2902 /**********************************************************************
2903 * WINPROC_CallProc16To32A
2905 LRESULT WINPROC_CallProc16To32A( winproc_callback_t callback, HWND16 hwnd, UINT16 msg,
2906 WPARAM16 wParam, LPARAM lParam, LRESULT *result, void *arg )
2911 HWND hwnd32 = WIN_Handle32( hwnd );
2913 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2914 hwnd32, SPY_GetMsgName(msg, hwnd32), wParam, lParam);
2916 if (WINPROC_MapMsg16To32A( hwnd32, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2919 ret = callback( hwnd32, msg32, wParam32, lParam, result, arg );
2920 *result = WINPROC_UnmapMsg16To32A( hwnd32, msg32, wParam32, lParam, *result );
2925 /**********************************************************************
2926 * WINPROC_CallProc16To32W
2928 static LRESULT WINPROC_CallProc16To32W( winproc_callback_t callback, HWND16 hwnd, UINT16 msg,
2929 WPARAM16 wParam, LPARAM lParam, LRESULT *result, void *arg )
2934 HWND hwnd32 = WIN_Handle32( hwnd );
2936 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2937 hwnd32, SPY_GetMsgName(msg, hwnd32), wParam, lParam);
2939 if (WINPROC_MapMsg16To32W( hwnd32, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2942 ret = callback( hwnd32, msg32, wParam32, lParam, result, arg );
2943 *result = WINPROC_UnmapMsg16To32W( hwnd32, msg32, wParam32, lParam, *result,
2944 (callback == call_window_proc) ? arg : NULL /*FIXME: hack*/ );
2949 /**********************************************************************
2950 * __wine_call_wndproc (USER.1010)
2952 LRESULT WINAPI __wine_call_wndproc( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam,
2958 WINPROC_CallProc16To32A( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procA );
2960 WINPROC_CallProc16To32W( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procW );
2965 /**********************************************************************
2966 * WINPROC_CallProc32ATo16
2968 * Call a 16-bit window procedure, translating the 32-bit args.
2970 static LRESULT WINPROC_CallProc32ATo16( winproc_callback16_t callback, HWND hwnd, UINT msg,
2971 WPARAM wParam, LPARAM lParam, LRESULT *result, void *arg )
2977 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2978 hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
2980 mp16.lParam = lParam;
2981 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1)
2983 ret = callback( HWND_16(hwnd), msg16, mp16.wParam, mp16.lParam, result, arg );
2984 mp16.lResult = *result;
2985 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
2986 *result = mp16.lResult;
2991 /**********************************************************************
2992 * WINPROC_CallProc32WTo16
2994 * Call a 16-bit window procedure, translating the 32-bit args.
2996 static LRESULT WINPROC_CallProc32WTo16( winproc_callback16_t callback, HWND hwnd, UINT msg,
2997 WPARAM wParam, LPARAM lParam, LRESULT *result, void *arg )
3003 TRACE_(msg)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3004 hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
3006 mp16.lParam = lParam;
3007 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1)
3009 ret = callback( HWND_16(hwnd), msg16, mp16.wParam, mp16.lParam, result, arg );
3010 mp16.lResult = *result;
3011 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
3012 *result = mp16.lResult;
3017 /**********************************************************************
3018 * CallWindowProc (USER.122)
3020 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
3021 WPARAM16 wParam, LPARAM lParam )
3026 if (!func) return 0;
3028 if (!(proc = handle16_to_proc( func )))
3029 call_window_proc16( hwnd, msg, wParam, lParam, &result, func );
3030 else if (proc->procA)
3031 WINPROC_CallProc16To32A( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procA );
3032 else if (proc->procW)
3033 WINPROC_CallProc16To32W( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procW );
3035 call_window_proc16( hwnd, msg, wParam, lParam, &result, proc->proc16 );
3041 /**********************************************************************
3042 * CallWindowProcA (USER32.@)
3044 * The CallWindowProc() function invokes the windows procedure _func_,
3045 * with _hwnd_ as the target window, the message specified by _msg_, and
3046 * the message parameters _wParam_ and _lParam_.
3048 * Some kinds of argument conversion may be done, I'm not sure what.
3050 * CallWindowProc() may be used for windows subclassing. Use
3051 * SetWindowLong() to set a new windows procedure for windows of the
3052 * subclass, and handle subclassed messages in the new windows
3053 * procedure. The new windows procedure may then use CallWindowProc()
3054 * with _func_ set to the parent class's windows procedure to dispatch
3055 * the message to the superclass.
3059 * The return value is message dependent.
3065 LRESULT WINAPI CallWindowProcA(
3066 WNDPROC func, /* [in] window procedure */
3067 HWND hwnd, /* [in] target window */
3068 UINT msg, /* [in] message */
3069 WPARAM wParam, /* [in] message dependent parameter */
3070 LPARAM lParam /* [in] message dependent parameter */
3075 if (!func) return 0;
3077 if (!(proc = handle_to_proc( func )))
3078 call_window_proc( hwnd, msg, wParam, lParam, &result, func );
3079 else if (proc->procA)
3080 call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
3081 else if (proc->procW)
3082 WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procW );
3084 WINPROC_CallProc32ATo16( call_window_proc16, hwnd, msg, wParam, lParam, &result, proc->proc16 );
3089 /**********************************************************************
3090 * CallWindowProcW (USER32.@)
3092 * See CallWindowProcA.
3094 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
3095 WPARAM wParam, LPARAM lParam )
3100 if (!func) return 0;
3102 if (!(proc = handle_to_proc( func )))
3103 call_window_proc( hwnd, msg, wParam, lParam, &result, func );
3104 else if (proc->procW)
3105 call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procW );
3106 else if (proc->procA)
3107 WINPROC_CallProcWtoA( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procA );
3109 WINPROC_CallProc32WTo16( call_window_proc16, hwnd, msg, wParam, lParam, &result, proc->proc16 );
3114 /**********************************************************************
3115 * WINPROC_CallDlgProc16
3117 INT_PTR WINPROC_CallDlgProc16( DLGPROC16 func, HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
3123 if (!func) return 0;
3125 if (!(proc = handle16_to_proc( (WNDPROC16)func )))
3127 ret = call_dialog_proc16( hwnd, msg, wParam, lParam, &result, func );
3129 else if (proc->procA)
3131 ret = WINPROC_CallProc16To32A( call_dialog_proc, hwnd, msg, wParam, lParam,
3132 &result, proc->procA );
3133 SetWindowLongPtrW( WIN_Handle32(hwnd), DWLP_MSGRESULT, result );
3135 else if (proc->procW)
3137 ret = WINPROC_CallProc16To32W( call_dialog_proc, hwnd, msg, wParam, lParam,
3138 &result, proc->procW );
3139 SetWindowLongPtrW( WIN_Handle32(hwnd), DWLP_MSGRESULT, result );
3143 ret = call_dialog_proc16( hwnd, msg, wParam, lParam, &result, proc->proc16 );
3149 /**********************************************************************
3150 * WINPROC_CallDlgProcA
3152 INT_PTR WINPROC_CallDlgProcA( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
3158 if (!func) return 0;
3160 if (!(proc = handle_to_proc( (WNDPROC)func )))
3161 ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, func );
3162 else if (proc->procA)
3163 ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
3164 else if (proc->procW)
3166 ret = WINPROC_CallProcAtoW( call_dialog_proc, hwnd, msg, wParam, lParam, &result, proc->procW );
3167 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result );
3171 ret = WINPROC_CallProc32ATo16( call_dialog_proc16, hwnd, msg, wParam, lParam, &result, proc->proc16 );
3172 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result );
3178 /**********************************************************************
3179 * WINPROC_CallDlgProcW
3181 INT_PTR WINPROC_CallDlgProcW( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
3187 if (!func) return 0;
3189 if (!(proc = handle_to_proc( (WNDPROC)func )))
3190 ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, func );
3191 else if (proc->procW)
3192 ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procW );
3193 else if (proc->procA)
3195 ret = WINPROC_CallProcWtoA( call_dialog_proc, hwnd, msg, wParam, lParam, &result, proc->procA );
3196 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result );
3200 ret = WINPROC_CallProc32WTo16( call_dialog_proc16, hwnd, msg, wParam, lParam, &result, proc->proc16 );
3201 SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result );