2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
15 #include "wine/winbase16.h"
16 #include "wine/winuser16.h"
17 #include "stackframe.h"
18 #include "selectors.h"
24 #include "debugtools.h"
29 DECLARE_DEBUG_CHANNEL(msg);
30 DECLARE_DEBUG_CHANNEL(relay);
31 DECLARE_DEBUG_CHANNEL(win);
35 /* Window procedure 16-to-32-bit thunk */
38 BYTE popl_eax; /* popl %eax (return address) */
39 BYTE pushl_func; /* pushl $proc */
41 BYTE pushl_eax; /* pushl %eax */
42 BYTE ljmp; /* ljmp relay*/
43 DWORD relay_offset; /* __wine_call_wndproc_32A/W */
45 } WINPROC_THUNK_FROM16;
47 /* Window procedure 32-to-16-bit thunk */
50 BYTE popl_eax; /* popl %eax (return address) */
51 BYTE pushl_func; /* pushl $proc */
53 BYTE pushl_eax; /* pushl %eax */
54 BYTE jmp; /* jmp relay (relative jump)*/
55 void (*relay)(); /* WINPROC_CallProc32ATo16() */
56 } WINPROC_THUNK_FROM32;
58 /* Simple jmp to call 32-bit procedure directly */
61 BYTE jmp; /* jmp proc (relative jump) */
68 WINPROC_THUNK_FROM16 t_from16;
69 WINPROC_THUNK_FROM32 t_from32;
72 typedef struct tagWINDOWPROC
74 WINPROC_THUNK thunk; /* Thunk */
75 WINPROC_JUMP jmp; /* Jump */
76 struct tagWINDOWPROC *next; /* Next window proc */
77 UINT magic; /* Magic number */
78 WINDOWPROCTYPE type; /* Function type */
79 WINDOWPROCUSER user; /* Function user */
82 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
84 #define WINPROC_THUNKPROC(pproc) \
85 (((pproc)->type == WIN_PROC_16) ? \
86 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
87 (WNDPROC16)((pproc)->thunk.t_from16.proc))
89 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
90 UINT msg, WPARAM wParam,
92 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
93 UINT msg, WPARAM wParam,
96 static HANDLE WinProcHeap;
97 static WORD WinProcSel;
100 /**********************************************************************
103 BOOL WINPROC_Init(void)
105 WinProcHeap = HeapCreate( 0, 0x10000, 0x10000 );
106 WinProcSel = SELECTOR_AllocBlock( (void *)WinProcHeap, 0x10000,
107 WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT );
108 if (!WinProcHeap || !WinProcSel)
110 WARN_(relay)("Unable to create winproc heap\n" );
118 /* Some window procedures modify register they shouldn't, or are not
119 * properly declared stdcall; so we need a small assembly wrapper to
121 extern LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
122 WPARAM wParam, LPARAM lParam );
123 __ASM_GLOBAL_FUNC( WINPROC_wrapper,
133 "movl 8(%ebp),%eax\n\t"
135 "leal -12(%ebp),%esp\n\t"
142 static inline LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
143 WPARAM wParam, LPARAM lParam )
145 return proc( hwnd, msg, wParam, lParam );
147 #endif /* __i386__ */
149 /**********************************************************************
150 * WINPROC_CallWndProc32
152 * Call a 32-bit WndProc.
154 static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
155 WPARAM wParam, LPARAM lParam )
160 hwnd = WIN_GetFullHandle( hwnd );
162 DPRINTF( "%08lx:Call window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
163 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam );
164 /* To avoid any deadlocks, all the locks on the windows structures
165 must be suspended before the control is passed to the application */
166 iWndsLocks = WIN_SuspendWndsLock();
167 retvalue = WINPROC_wrapper( proc, hwnd, msg, wParam, lParam );
168 WIN_RestoreWndsLock(iWndsLocks);
171 DPRINTF( "%08lx:Ret window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
172 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam, retvalue );
176 /***********************************************************************
177 * WINPROC_CallWndProc16
179 * Call a 16-bit window procedure
181 static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
182 UINT16 msg, WPARAM16 wParam,
189 TEB *teb = NtCurrentTeb();
192 /* Window procedures want ax = hInstance, ds = es = ss */
194 memset(&context, '\0', sizeof(context));
195 context.SegDs = context.SegEs = SELECTOROF(teb->cur_stack);
196 if (!(context.Eax = GetWindowWord16( hwnd, GWL_HINSTANCE ))) context.Eax = context.SegDs;
197 context.SegCs = SELECTOROF(proc);
198 context.Eip = OFFSETOF(proc);
199 context.Ebp = OFFSETOF(teb->cur_stack)
200 + (WORD)&((STACK16FRAME*)0)->bp;
204 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
205 work if structures passed in lParam are placed in the stack/data
206 segment. Programmers easily make the mistake of converting lParam
207 to a near rather than a far pointer, since Windows apparently
208 allows this. We copy the structures to the 16 bit stack; this is
209 ugly but makes these programs work. */
214 offset = sizeof(CREATESTRUCT16); break;
216 offset = sizeof(DRAWITEMSTRUCT16); break;
218 offset = sizeof(COMPAREITEMSTRUCT16); break;
222 void *s = MapSL(lParam);
223 lParam = stack16_push( offset );
224 memcpy( MapSL(lParam), s, offset );
228 iWndsLocks = WIN_SuspendWndsLock();
230 args = (WORD *)THREAD_STACK16(teb) - 5;
231 args[0] = LOWORD(lParam);
232 args[1] = HIWORD(lParam);
237 wine_call_to_16_regs_short( &context, 5 * sizeof(WORD) );
238 ret = MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) );
239 if (offset) stack16_pop( offset );
241 WIN_RestoreWndsLock(iWndsLocks);
247 /**********************************************************************
250 * Return a pointer to the win proc.
252 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
257 /* ptr cannot be < 64K */
258 if (!HIWORD(handle)) return NULL;
260 /* Check for a linear pointer */
262 ptr = (BYTE *)handle;
263 /* First check if it is the jmp address */
264 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->jmp);
265 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
267 /* Now it must be the thunk address */
268 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->thunk);
269 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
272 /* Check for a segmented pointer */
274 if (!IsBadReadPtr16( (SEGPTR)handle, sizeof(proc->thunk) ))
276 ptr = MapSL( (SEGPTR)handle );
277 /* It must be the thunk address */
278 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->thunk);
279 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
287 /**********************************************************************
288 * WINPROC_AllocWinProc
290 * Allocate a new window procedure.
292 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
293 WINDOWPROCUSER user )
295 static FARPROC16 relay_32A, relay_32W;
297 WINDOWPROC *proc, *oldproc;
299 /* Allocate a window procedure */
301 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
303 /* Check if the function is already a win proc */
305 if ((oldproc = WINPROC_GetPtr( func )))
314 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
315 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
316 proc->thunk.t_from32.proc = func;
317 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
318 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
319 proc->thunk.t_from32.relay = /* relative jump */
320 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
321 (DWORD)(&proc->thunk.t_from32.relay + 1));
324 if (!relay_32A) relay_32A = GetProcAddress16( GetModuleHandle16("user"),
325 "__wine_call_wndproc_32A" );
326 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
327 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
328 proc->thunk.t_from16.proc = (WNDPROC)func;
329 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
330 proc->thunk.t_from16.ljmp = 0xea; /* ljmp relay*/
331 proc->thunk.t_from16.relay_offset = OFFSETOF(relay_32A);
332 proc->thunk.t_from16.relay_sel = SELECTOROF(relay_32A);
333 proc->jmp.jmp = 0xe9;
334 /* Fixup relative jump */
335 proc->jmp.proc = (WNDPROC)((DWORD)func - (DWORD)(&proc->jmp.proc + 1));
338 if (!relay_32W) relay_32W = GetProcAddress16( GetModuleHandle16("user"),
339 "__wine_call_wndproc_32W" );
340 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
341 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
342 proc->thunk.t_from16.proc = (WNDPROC)func;
343 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
344 proc->thunk.t_from16.ljmp = 0xea; /* ljmp relay*/
345 proc->thunk.t_from16.relay_offset = OFFSETOF(relay_32W);
346 proc->thunk.t_from16.relay_sel = SELECTOROF(relay_32W);
347 proc->jmp.jmp = 0xe9;
348 /* Fixup relative jump */
349 proc->jmp.proc = (WNDPROC)((DWORD)func - (DWORD)(&proc->jmp.proc + 1));
352 /* Should not happen */
355 proc->magic = WINPROC_MAGIC;
360 TRACE_(win)("(%08x,%d): returning %08x\n",
361 (UINT)func, type, (UINT)proc );
366 /**********************************************************************
369 * Get a window procedure pointer that can be passed to the Windows program.
371 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
373 WINDOWPROC *ptr = (WINDOWPROC *)proc;
375 if (!proc) return NULL;
376 if (type == WIN_PROC_16) /* We want a 16:16 address */
378 if (ptr->type == WIN_PROC_16)
379 return ptr->thunk.t_from32.proc;
381 return (WNDPROC16)MAKESEGPTR( WinProcSel, (char *)&ptr->thunk - (char *)WinProcHeap );
383 else /* We want a 32-bit address */
385 if (ptr->type == WIN_PROC_16)
386 return (WNDPROC16)&ptr->thunk;
387 else if (type != ptr->type)
388 /* Have to return the jmp address if types don't match */
389 return (WNDPROC16)&ptr->jmp;
391 /* Some Win16 programs want to get back the proc they set */
392 return (WNDPROC16)ptr->thunk.t_from16.proc;
397 /**********************************************************************
400 * Set the window procedure for a window or class. There are
401 * three tree classes of winproc callbacks:
403 * 1) class -> wp - not subclassed
404 * class -> wp -> wp -> wp -> wp - SetClassLong()
406 * 2) window -' / - not subclassed
407 * window -> wp -> wp ' - SetWindowLong()
409 * 3) timer -> wp - SetTimer()
411 * Initially, winproc of the window points to the current winproc
412 * thunk of its class. Subclassing prepends a new thunk to the
413 * window winproc chain at the head of the list. Thus, window thunk
414 * list includes class thunks and the latter are preserved when the
415 * window is destroyed.
418 BOOL WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
419 WINDOWPROCTYPE type, WINDOWPROCUSER user )
421 BOOL bRecycle = FALSE;
422 WINDOWPROC *proc, **ppPrev;
424 /* Check if function is already in the list */
426 ppPrev = (WINDOWPROC **)pFirst;
427 proc = WINPROC_GetPtr( func );
434 if ((*ppPrev)->user != user)
436 /* terminal thunk is being restored */
438 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
439 *(WINDOWPROC **)pFirst = *ppPrev;
448 if (((*ppPrev)->type == type) &&
449 (func == WINPROC_THUNKPROC(*ppPrev)))
456 /* WPF_CLASS thunk terminates window thunk list */
457 if ((*ppPrev)->user != user) break;
458 ppPrev = &(*ppPrev)->next;
463 /* Extract this thunk from the list */
465 *ppPrev = proc->next;
467 else /* Allocate a new one */
469 if (proc) /* Was already a win proc */
472 func = WINPROC_THUNKPROC(proc);
474 proc = WINPROC_AllocWinProc( func, type, user );
475 if (!proc) return FALSE;
478 /* Add the win proc at the head of the list */
480 TRACE_(win)("(%08x,%08x,%d): res=%08x\n",
481 (UINT)*pFirst, (UINT)func, type, (UINT)proc );
482 proc->next = *(WINDOWPROC **)pFirst;
483 *(WINDOWPROC **)pFirst = proc;
488 /**********************************************************************
491 * Free a list of win procs.
493 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
497 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
498 if (((WINDOWPROC *)proc)->user != user) break;
499 TRACE_(win)("freeing %08x\n", (UINT)proc);
500 HeapFree( WinProcHeap, 0, proc );
506 /**********************************************************************
507 * WINPROC_GetProcType
509 * Return the window procedure type.
511 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
514 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
515 return WIN_PROC_INVALID;
516 return ((WINDOWPROC *)proc)->type;
518 /**********************************************************************
519 * WINPROC_TestCBForStr
521 * Return TRUE if the lparam is a string
523 inline static BOOL WINPROC_TestCBForStr( HWND hwnd )
525 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
526 return (!(style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) || (style & CBS_HASSTRINGS));
528 /**********************************************************************
529 * WINPROC_TestLBForStr
531 * Return TRUE if the lparam is a string
533 inline static BOOL WINPROC_TestLBForStr( HWND hwnd )
535 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
536 return (!(style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) || (style & LBS_HASSTRINGS));
539 /**********************************************************************
540 * WINPROC_MapMsg32ATo32W
542 * Map a message from Ansi to Unicode.
543 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
546 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
547 * the first four bytes are the handle of the icon
548 * when the WM_SETTEXT message has been used to set the icon
550 INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
555 case WM_ASKCBFORMATNAME:
557 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
558 *pwparam * sizeof(WCHAR) + sizeof(LPARAM) );
560 *ptr++ = *plparam; /* Store previous lParam */
561 *plparam = (LPARAM)ptr;
564 /* lparam is string (0-terminated) */
566 case WM_WININICHANGE:
567 case WM_DEVMODECHANGE:
570 case CB_FINDSTRINGEXACT:
571 case CB_SELECTSTRING:
575 case LB_FINDSTRINGEXACT:
576 case LB_SELECTSTRING:
578 if(!*plparam) return 0;
579 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
580 return (*plparam ? 1 : -1);
581 case WM_GETTEXTLENGTH:
582 case CB_GETLBTEXTLEN:
584 return 1; /* need to map result */
589 { CREATESTRUCTW cs; /* new structure */
590 LPCWSTR lpszName; /* allocated Name */
591 LPCWSTR lpszClass; /* allocated Class */
594 struct s *xs = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct s));
596 xs->cs = *(CREATESTRUCTW *)*plparam;
597 if (HIWORD(xs->cs.lpszName))
598 xs->lpszName = xs->cs.lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
599 (LPCSTR)xs->cs.lpszName );
600 if (HIWORD(xs->cs.lpszClass))
601 xs->lpszClass = xs->cs.lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
602 (LPCSTR)xs->cs.lpszClass );
603 *plparam = (LPARAM)xs;
608 MDICREATESTRUCTW *cs =
609 (MDICREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
611 *cs = *(MDICREATESTRUCTW *)*plparam;
612 if (HIWORD(cs->szClass))
613 cs->szClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
614 (LPCSTR)cs->szClass );
615 if (HIWORD(cs->szTitle))
616 cs->szTitle = HEAP_strdupAtoW( GetProcessHeap(), 0,
617 (LPCSTR)cs->szTitle );
618 *plparam = (LPARAM)cs;
624 case LB_INSERTSTRING:
625 if(!*plparam) return 0;
626 if ( WINPROC_TestLBForStr( hwnd ))
627 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
628 return (*plparam ? 1 : -1);
630 case LB_GETTEXT: /* fixme: fixed sized buffer */
631 { if ( WINPROC_TestLBForStr( hwnd ))
632 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
634 *ptr++ = *plparam; /* Store previous lParam */
635 *plparam = (LPARAM)ptr;
642 case CB_INSERTSTRING:
643 if(!*plparam) return 0;
644 if ( WINPROC_TestCBForStr( hwnd ))
645 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
646 return (*plparam ? 1 : -1);
648 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
649 { if ( WINPROC_TestCBForStr( hwnd ))
650 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
652 *ptr++ = *plparam; /* Store previous lParam */
653 *plparam = (LPARAM)ptr;
660 { WORD len = (WORD)*plparam;
661 LPARAM *ptr = (LPARAM *) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
663 *ptr++ = *plparam; /* Store previous lParam */
664 *((WORD *) ptr) = len; /* Store the length */
665 *plparam = (LPARAM)ptr;
675 case EM_SETPASSWORDCHAR:
677 char ch = LOWORD(*pwparam);
679 MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1);
680 *pwparam = MAKEWPARAM( wch, HIWORD(*pwparam) );
684 case WM_PAINTCLIPBOARD:
685 case WM_SIZECLIPBOARD:
686 FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg, hwnd), msg );
688 default: /* No translation needed */
694 /**********************************************************************
695 * WINPROC_UnmapMsg32ATo32W
697 * Unmap a message that was mapped from Ansi to Unicode.
699 LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
705 case WM_ASKCBFORMATNAME:
707 LPARAM *ptr = (LPARAM *)lParam - 1;
708 if (wParam > 0 && !WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
709 (LPSTR)*ptr, wParam, NULL, NULL ))
710 ((LPSTR)*ptr)[wParam-1] = 0;
711 HeapFree( GetProcessHeap(), 0, ptr );
714 case WM_GETTEXTLENGTH:
715 case CB_GETLBTEXTLEN:
717 /* there may be one DBCS char for each Unicode char */
723 { CREATESTRUCTW cs; /* new structure */
724 LPWSTR lpszName; /* allocated Name */
725 LPWSTR lpszClass; /* allocated Class */
727 struct s *xs = (struct s *)lParam;
728 if (xs->lpszName) HeapFree( GetProcessHeap(), 0, xs->lpszName );
729 if (xs->lpszClass) HeapFree( GetProcessHeap(), 0, xs->lpszClass );
730 HeapFree( GetProcessHeap(), 0, xs );
736 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
737 if (HIWORD(cs->szTitle))
738 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
739 if (HIWORD(cs->szClass))
740 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
741 HeapFree( GetProcessHeap(), 0, cs );
746 case WM_WININICHANGE:
747 case WM_DEVMODECHANGE:
750 case CB_FINDSTRINGEXACT:
751 case CB_SELECTSTRING:
755 case LB_FINDSTRINGEXACT:
756 case LB_SELECTSTRING:
758 HeapFree( GetProcessHeap(), 0, (void *)lParam );
763 case LB_INSERTSTRING:
764 if ( WINPROC_TestLBForStr( hwnd ))
765 HeapFree( GetProcessHeap(), 0, (void *)lParam );
769 { if ( WINPROC_TestLBForStr( hwnd ))
770 { LPARAM *ptr = (LPARAM *)lParam - 1;
771 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, (LPSTR)*ptr, 0x7fffffff, NULL, NULL );
772 HeapFree( GetProcessHeap(), 0, ptr );
779 case CB_INSERTSTRING:
780 if ( WINPROC_TestCBForStr( hwnd ))
781 HeapFree( GetProcessHeap(), 0, (void *)lParam );
785 { if ( WINPROC_TestCBForStr( hwnd ))
786 { LPARAM *ptr = (LPARAM *)lParam - 1;
787 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, (LPSTR)*ptr, 0x7fffffff, NULL, NULL );
788 HeapFree( GetProcessHeap(), 0, ptr );
795 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
796 WORD len = *(WORD *) lParam;
797 if (len > 0 && !WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
798 (LPSTR)*ptr, len, NULL, NULL ))
799 ((LPSTR)*ptr)[len-1] = 0;
800 HeapFree( GetProcessHeap(), 0, ptr );
808 /**********************************************************************
809 * WINPROC_MapMsg32WTo32A
811 * Map a message from Unicode to Ansi.
812 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
814 INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
819 case WM_ASKCBFORMATNAME:
821 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
822 *pwparam + sizeof(LPARAM) );
824 *ptr++ = *plparam; /* Store previous lParam */
825 *plparam = (LPARAM)ptr;
830 case WM_WININICHANGE:
831 case WM_DEVMODECHANGE:
834 case CB_FINDSTRINGEXACT:
835 case CB_SELECTSTRING:
839 case LB_FINDSTRINGEXACT:
840 case LB_SELECTSTRING:
842 if(!*plparam) return 0;
843 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
844 return (*plparam ? 1 : -1);
849 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0,
852 *cs = *(CREATESTRUCTA *)*plparam;
853 if (HIWORD(cs->lpszName))
854 cs->lpszName = HEAP_strdupWtoA( GetProcessHeap(), 0,
855 (LPCWSTR)cs->lpszName );
856 if (HIWORD(cs->lpszClass))
857 cs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
858 (LPCWSTR)cs->lpszClass);
859 *plparam = (LPARAM)cs;
864 MDICREATESTRUCTA *cs =
865 (MDICREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
867 *cs = *(MDICREATESTRUCTA *)*plparam;
868 if (HIWORD(cs->szTitle))
869 cs->szTitle = HEAP_strdupWtoA( GetProcessHeap(), 0,
870 (LPCWSTR)cs->szTitle );
871 if (HIWORD(cs->szClass))
872 cs->szClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
873 (LPCWSTR)cs->szClass );
874 *plparam = (LPARAM)cs;
880 case LB_INSERTSTRING:
881 if(!*plparam) return 0;
882 if ( WINPROC_TestLBForStr( hwnd ))
883 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
884 return (*plparam ? 1 : -1);
886 case LB_GETTEXT: /* fixme: fixed sized buffer */
887 { if ( WINPROC_TestLBForStr( hwnd ))
888 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
890 *ptr++ = *plparam; /* Store previous lParam */
891 *plparam = (LPARAM)ptr;
898 case CB_INSERTSTRING:
899 if(!*plparam) return 0;
900 if ( WINPROC_TestCBForStr( hwnd ))
901 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
902 return (*plparam ? 1 : -1);
904 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
905 { if ( WINPROC_TestCBForStr( hwnd ))
906 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
908 *ptr++ = *plparam; /* Store previous lParam */
909 *plparam = (LPARAM)ptr;
916 { WORD len = (WORD)*plparam;
917 LPARAM *ptr = (LPARAM *) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
919 *ptr++ = *plparam; /* Store previous lParam */
920 *((WORD *) ptr) = len; /* Store the length */
921 *plparam = (LPARAM)ptr;
931 case EM_SETPASSWORDCHAR:
933 WCHAR wch = LOWORD(*pwparam);
935 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL );
936 *pwparam = MAKEWPARAM( ch, HIWORD(*pwparam) );
940 case WM_PAINTCLIPBOARD:
941 case WM_SIZECLIPBOARD:
942 FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg, hwnd),msg );
944 default: /* No translation needed */
950 /**********************************************************************
951 * WINPROC_UnmapMsg32WTo32A
953 * Unmap a message that was mapped from Unicode to Ansi.
955 void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
960 case WM_ASKCBFORMATNAME:
962 LPARAM *ptr = (LPARAM *)lParam - 1;
965 if (!MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, wParam ))
966 ((LPWSTR)*ptr)[wParam-1] = 0;
968 HeapFree( GetProcessHeap(), 0, ptr );
973 case WM_WININICHANGE:
974 case WM_DEVMODECHANGE:
977 case CB_FINDSTRINGEXACT:
978 case CB_SELECTSTRING:
982 case LB_FINDSTRINGEXACT:
983 case LB_SELECTSTRING:
985 HeapFree( GetProcessHeap(), 0, (void *)lParam );
991 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
992 if (HIWORD(cs->lpszName))
993 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
994 if (HIWORD(cs->lpszClass))
995 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
996 HeapFree( GetProcessHeap(), 0, cs );
1002 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1003 if (HIWORD(cs->szTitle))
1004 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
1005 if (HIWORD(cs->szClass))
1006 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
1007 HeapFree( GetProcessHeap(), 0, cs );
1013 case LB_INSERTSTRING:
1014 if ( WINPROC_TestLBForStr( hwnd ))
1015 HeapFree( GetProcessHeap(), 0, (void *)lParam );
1019 if ( WINPROC_TestLBForStr( hwnd ))
1021 LPARAM *ptr = (LPARAM *)lParam - 1;
1022 MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, 0x7fffffff );
1023 HeapFree( GetProcessHeap(), 0, ptr );
1029 case CB_INSERTSTRING:
1030 if ( WINPROC_TestCBForStr( hwnd ))
1031 HeapFree( GetProcessHeap(), 0, (void *)lParam );
1035 if ( WINPROC_TestCBForStr( hwnd ))
1037 LPARAM *ptr = (LPARAM *)lParam - 1;
1038 MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, 0x7fffffff );
1039 HeapFree( GetProcessHeap(), 0, ptr );
1043 /* Multiline edit */
1045 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lparam */
1046 WORD len = *(WORD *)ptr;
1049 if (!MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, len ))
1050 ((LPWSTR)*ptr)[len-1] = 0;
1052 HeapFree( GetProcessHeap(), 0, ptr );
1059 /**********************************************************************
1060 * WINPROC_MapMsg16To32A
1062 * Map a message from 16- to 32-bit Ansi.
1063 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1065 INT WINPROC_MapMsg16To32A( HWND hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1066 WPARAM *pwparam32, LPARAM *plparam )
1068 *pmsg32 = (UINT)msg16;
1069 *pwparam32 = (WPARAM)wParam16;
1076 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1077 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1081 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1082 *plparam = (LPARAM)WIN_Handle32( HIWORD(*plparam) );
1085 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
1086 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
1087 *pwparam32 = (WPARAM)(HDC)wParam16;
1088 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1090 case WM_COMPAREITEM:
1092 COMPAREITEMSTRUCT16* cis16 = MapSL(*plparam);
1093 COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)
1094 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis));
1095 if (!cis) return -1;
1096 cis->CtlType = cis16->CtlType;
1097 cis->CtlID = cis16->CtlID;
1098 cis->hwndItem = WIN_Handle32( cis16->hwndItem );
1099 cis->itemID1 = cis16->itemID1;
1100 cis->itemData1 = cis16->itemData1;
1101 cis->itemID2 = cis16->itemID2;
1102 cis->itemData2 = cis16->itemData2;
1103 cis->dwLocaleId = 0; /* FIXME */
1104 *plparam = (LPARAM)cis;
1109 DELETEITEMSTRUCT16* dis16 = MapSL(*plparam);
1110 DELETEITEMSTRUCT *dis = (DELETEITEMSTRUCT *)
1111 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis));
1112 if (!dis) return -1;
1113 dis->CtlType = dis16->CtlType;
1114 dis->CtlID = dis16->CtlID;
1115 dis->hwndItem = WIN_Handle32( dis16->hwndItem );
1116 dis->itemData = dis16->itemData;
1117 *plparam = (LPARAM)dis;
1120 case WM_MEASUREITEM:
1122 MEASUREITEMSTRUCT16* mis16 = MapSL(*plparam);
1123 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)
1124 HeapAlloc(GetProcessHeap(), 0,
1125 sizeof(*mis) + sizeof(LPARAM));
1126 if (!mis) return -1;
1127 mis->CtlType = mis16->CtlType;
1128 mis->CtlID = mis16->CtlID;
1129 mis->itemID = mis16->itemID;
1130 mis->itemWidth = mis16->itemWidth;
1131 mis->itemHeight = mis16->itemHeight;
1132 mis->itemData = mis16->itemData;
1133 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1134 *plparam = (LPARAM)mis;
1139 DRAWITEMSTRUCT16* dis16 = MapSL(*plparam);
1140 DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)HeapAlloc(GetProcessHeap(), 0,
1142 if (!dis) return -1;
1143 dis->CtlType = dis16->CtlType;
1144 dis->CtlID = dis16->CtlID;
1145 dis->itemID = dis16->itemID;
1146 dis->itemAction = dis16->itemAction;
1147 dis->itemState = dis16->itemState;
1148 dis->hwndItem = (dis->CtlType == ODT_MENU) ? (HWND)(HMENU)dis16->hwndItem
1149 : WIN_Handle32( dis16->hwndItem );
1150 dis->hDC = dis16->hDC;
1151 dis->itemData = dis16->itemData;
1152 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
1153 *plparam = (LPARAM)dis;
1156 case WM_GETMINMAXINFO:
1158 MINMAXINFO *mmi = (MINMAXINFO *)HeapAlloc( GetProcessHeap(), 0,
1159 sizeof(*mmi) + sizeof(LPARAM));
1160 if (!mmi) return -1;
1161 STRUCT32_MINMAXINFO16to32( MapSL(*plparam), mmi );
1162 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1163 *plparam = (LPARAM)mmi;
1168 case WM_WININICHANGE:
1169 case WM_DEVMODECHANGE:
1170 case WM_ASKCBFORMATNAME:
1171 *plparam = (LPARAM)MapSL(*plparam);
1175 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1176 MDICREATESTRUCTA *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1178 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
1179 cs->szTitle = MapSL(cs16->szTitle);
1180 cs->szClass = MapSL(cs16->szClass);
1181 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1182 *plparam = (LPARAM)cs;
1185 case WM_MDIGETACTIVE:
1186 *plparam = (LPARAM)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL) );
1187 *(BOOL*)(*plparam) = 0;
1191 *pmsg32=WM_MDIREFRESHMENU;
1192 *pwparam32 = (WPARAM)(HMENU)LOWORD(*plparam);
1193 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1196 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1197 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1200 if((LOWORD(*plparam) & MF_POPUP) && (LOWORD(*plparam) != 0xFFFF))
1202 HMENU hmenu=(HMENU)HIWORD(*plparam);
1203 UINT Pos=MENU_FindSubMenu( &hmenu, wParam16);
1204 if(Pos==0xFFFF) Pos=0; /* NO_SELECTED_ITEM */
1205 *pwparam32 = MAKEWPARAM( Pos, LOWORD(*plparam) );
1207 else *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1208 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1210 case WM_MDIACTIVATE:
1213 *pwparam32 = (WPARAM)WIN_Handle32( HIWORD(*plparam) );
1214 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1216 else /* message sent to MDI client */
1217 *pwparam32 = wParam16;
1221 NCCALCSIZE_PARAMS16 *nc16;
1222 NCCALCSIZE_PARAMS *nc;
1224 nc = (NCCALCSIZE_PARAMS *)HeapAlloc( GetProcessHeap(), 0,
1225 sizeof(*nc) + sizeof(LPARAM) );
1227 nc16 = MapSL(*plparam);
1228 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
1231 nc->lppos = (WINDOWPOS *)HeapAlloc( GetProcessHeap(), 0,
1232 sizeof(*nc->lppos) );
1233 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
1234 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
1235 if (nc->lppos) STRUCT32_WINDOWPOS16to32( MapSL(nc16->lppos), nc->lppos );
1237 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1238 *plparam = (LPARAM)nc;
1244 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1245 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0,
1246 sizeof(*cs) + sizeof(LPARAM) );
1248 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
1249 cs->lpszName = MapSL(cs16->lpszName);
1250 cs->lpszClass = MapSL(cs16->lpszClass);
1251 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1252 *plparam = (LPARAM)cs;
1255 case WM_PARENTNOTIFY:
1256 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1258 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1259 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1262 case WM_WINDOWPOSCHANGING:
1263 case WM_WINDOWPOSCHANGED:
1265 WINDOWPOS *wp = (WINDOWPOS *)HeapAlloc( GetProcessHeap(), 0,
1266 sizeof(*wp) + sizeof(LPARAM) );
1268 STRUCT32_WINDOWPOS16to32( MapSL(*plparam), wp );
1269 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1270 *plparam = (LPARAM)wp;
1276 LPMSG16 msg16 = MapSL(*plparam);
1277 LPMSG msg32 = (LPMSG)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1279 if (!msg32) return -1;
1280 msg32->hwnd = WIN_Handle32( msg16->hwnd );
1281 msg32->lParam = msg16->lParam;
1282 msg32->time = msg16->time;
1283 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1284 /* this is right, right? */
1285 if (WINPROC_MapMsg16To32A( msg32->hwnd, msg16->message,msg16->wParam,
1286 &msg32->message,&msg32->wParam,
1287 &msg32->lParam)<0) {
1288 HeapFree( GetProcessHeap(), 0, msg32 );
1291 *plparam = (LPARAM)msg32;
1296 *plparam = (LPARAM)MapSL(*plparam);
1298 case WM_ACTIVATEAPP:
1300 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1301 a 32bit window. Might be superflous with 32bit interprocess
1304 HTASK16 htask = (HTASK16) *plparam;
1305 DWORD idThread = (DWORD)TASK_GetPtr(htask)->teb->tid;
1306 *plparam = (LPARAM) idThread;
1311 MDINEXTMENU *next = HeapAlloc( GetProcessHeap(), 0, sizeof(*next) );
1312 if (!next) return -1;
1313 next->hmenuIn = *plparam;
1314 next->hmenuNext = 0;
1316 *plparam = (LPARAM)next;
1319 case WM_PAINTCLIPBOARD:
1320 case WM_SIZECLIPBOARD:
1321 FIXME_(msg)("message %04x needs translation\n",msg16 );
1324 default: /* No translation needed */
1330 /**********************************************************************
1331 * WINPROC_UnmapMsg16To32A
1333 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1335 LRESULT WINPROC_UnmapMsg16To32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1340 case WM_COMPAREITEM:
1343 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
1345 case WM_MEASUREITEM:
1347 MEASUREITEMSTRUCT16 *mis16;
1348 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1349 lParam = *(LPARAM *)(mis + 1);
1350 mis16 = MapSL(lParam);
1351 mis16->itemWidth = (UINT16)mis->itemWidth;
1352 mis16->itemHeight = (UINT16)mis->itemHeight;
1353 HeapFree( GetProcessHeap(), 0, mis );
1356 case WM_GETMINMAXINFO:
1358 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1359 lParam = *(LPARAM *)(mmi + 1);
1360 STRUCT32_MINMAXINFO32to16( mmi, MapSL(lParam));
1361 HeapFree( GetProcessHeap(), 0, mmi );
1366 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1367 lParam = *(LPARAM *)(cs + 1);
1368 STRUCT32_MDICREATESTRUCT32Ato16( cs, MapSL(lParam) );
1369 HeapFree( GetProcessHeap(), 0, cs );
1372 case WM_MDIGETACTIVE:
1373 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1374 HeapFree( GetProcessHeap(), 0, (BOOL *)lParam );
1378 NCCALCSIZE_PARAMS16 *nc16;
1379 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1380 lParam = *(LPARAM *)(nc + 1);
1381 nc16 = MapSL(lParam);
1382 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
1385 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
1386 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
1389 STRUCT32_WINDOWPOS32to16( nc->lppos, MapSL(nc16->lppos));
1390 HeapFree( GetProcessHeap(), 0, nc->lppos );
1393 HeapFree( GetProcessHeap(), 0, nc );
1399 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1400 lParam = *(LPARAM *)(cs + 1);
1401 STRUCT32_CREATESTRUCT32Ato16( cs, MapSL(lParam) );
1402 HeapFree( GetProcessHeap(), 0, cs );
1405 case WM_WINDOWPOSCHANGING:
1406 case WM_WINDOWPOSCHANGED:
1408 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1409 lParam = *(LPARAM *)(wp + 1);
1410 STRUCT32_WINDOWPOS32to16(wp, MapSL(lParam));
1411 HeapFree( GetProcessHeap(), 0, wp );
1417 LPMSG msg32 = (LPMSG)lParam;
1419 WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1421 HeapFree( GetProcessHeap(), 0, msg32 );
1426 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
1427 result = MAKELONG( next->hmenuNext, WIN_Handle16(next->hwndNext) );
1428 HeapFree( GetProcessHeap(), 0, next );
1436 /**********************************************************************
1437 * WINPROC_MapMsg16To32W
1439 * Map a message from 16- to 32-bit Unicode.
1440 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1442 INT WINPROC_MapMsg16To32W( HWND hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1443 WPARAM *pwparam32, LPARAM *plparam )
1448 *pmsg32=(UINT)msg16;
1449 *pwparam32 = (WPARAM)wParam16;
1454 case WM_WININICHANGE:
1455 case WM_DEVMODECHANGE:
1456 case WM_ASKCBFORMATNAME:
1457 *plparam = (LPARAM)MapSL(*plparam);
1458 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, pwparam32, plparam );
1459 case WM_GETTEXTLENGTH:
1460 case CB_GETLBTEXTLEN:
1462 return 1; /* need to map result */
1466 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1467 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
1468 sizeof(*cs) + sizeof(LPARAM) );
1470 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1471 cs->lpszName = map_str_16_to_32W(cs16->lpszName);
1472 cs->lpszClass = map_str_16_to_32W(cs16->lpszClass);
1473 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1474 *plparam = (LPARAM)cs;
1479 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1480 MDICREATESTRUCTW *cs =
1481 (MDICREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
1482 sizeof(*cs) + sizeof(LPARAM) );
1484 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1485 cs->szTitle = map_str_16_to_32W(cs16->szTitle);
1486 cs->szClass = map_str_16_to_32W(cs16->szClass);
1487 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1488 *plparam = (LPARAM)cs;
1494 LPMSG16 msg16 = MapSL(*plparam);
1495 LPMSG msg32 = (LPMSG)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1497 if (!msg32) return -1;
1498 msg32->hwnd = WIN_Handle32( msg16->hwnd );
1499 msg32->lParam = msg16->lParam;
1500 msg32->time = msg16->time;
1501 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1502 /* this is right, right? */
1503 if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
1504 &msg32->message,&msg32->wParam,
1505 &msg32->lParam)<0) {
1506 HeapFree( GetProcessHeap(), 0, msg32 );
1509 *plparam = (LPARAM)msg32;
1516 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1517 *pwparam32 = MAKEWPARAM( wch, HIWORD(*plparam) );
1518 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1522 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1523 *pwparam32 = MAKEWPARAM( wch, LOWORD(*plparam) );
1524 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1529 case WM_SYSDEADCHAR:
1531 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1535 default: /* No Unicode translation needed */
1536 return WINPROC_MapMsg16To32A( hwnd, msg16, wParam16, pmsg32,
1537 pwparam32, plparam );
1542 /**********************************************************************
1543 * WINPROC_UnmapMsg16To32W
1545 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1547 LRESULT WINPROC_UnmapMsg16To32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1554 case WM_GETTEXTLENGTH:
1555 case CB_GETLBTEXTLEN:
1557 case WM_ASKCBFORMATNAME:
1558 return WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
1562 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1563 lParam = *(LPARAM *)(cs + 1);
1564 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs, MapSL(lParam) );
1565 unmap_str_16_to_32W( cs->lpszName );
1566 unmap_str_16_to_32W( cs->lpszClass );
1567 HeapFree( GetProcessHeap(), 0, cs );
1572 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1573 lParam = *(LPARAM *)(cs + 1);
1574 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs, MapSL(lParam) );
1575 unmap_str_16_to_32W( cs->szTitle );
1576 unmap_str_16_to_32W( cs->szClass );
1577 HeapFree( GetProcessHeap(), 0, cs );
1583 LPMSG msg32 = (LPMSG)lParam;
1585 WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1587 HeapFree( GetProcessHeap(), 0, msg32 );
1591 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1597 /**********************************************************************
1598 * WINPROC_MapMsg32ATo16
1600 * Map a message from 32-bit Ansi to 16-bit.
1601 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1603 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1604 UINT16 *pmsg16, WPARAM16 *pwparam16,
1607 *pmsg16 = (UINT16)msg32;
1608 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1616 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1625 case EM_SCROLLCARET:
1628 case EM_GETLINECOUNT:
1640 case EM_LINEFROMCHAR:
1641 case EM_SETTABSTOPS:
1642 case EM_SETPASSWORDCHAR:
1643 case EM_EMPTYUNDOBUFFER:
1644 case EM_GETFIRSTVISIBLELINE:
1645 case EM_SETREADONLY:
1646 case EM_SETWORDBREAKPROC:
1647 case EM_GETWORDBREAKPROC:
1648 case EM_GETPASSWORDCHAR:
1649 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1654 case LB_DELETESTRING:
1655 case LB_GETANCHORINDEX:
1656 case LB_GETCARETINDEX:
1659 case LB_GETHORIZONTALEXTENT:
1660 case LB_GETITEMDATA:
1661 case LB_GETITEMHEIGHT:
1663 case LB_GETSELCOUNT:
1665 case LB_GETTOPINDEX:
1666 case LB_RESETCONTENT:
1667 case LB_SELITEMRANGE:
1668 case LB_SELITEMRANGEEX:
1669 case LB_SETANCHORINDEX:
1670 case LB_SETCARETINDEX:
1671 case LB_SETCOLUMNWIDTH:
1673 case LB_SETHORIZONTALEXTENT:
1674 case LB_SETITEMDATA:
1675 case LB_SETITEMHEIGHT:
1677 case LB_SETTOPINDEX:
1678 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1680 case CB_DELETESTRING:
1682 case CB_GETLBTEXTLEN:
1684 case CB_RESETCONTENT:
1688 case CB_SHOWDROPDOWN:
1689 case CB_SETITEMDATA:
1690 case CB_SETITEMHEIGHT:
1691 case CB_GETITEMHEIGHT:
1692 case CB_SETEXTENDEDUI:
1693 case CB_GETEXTENDEDUI:
1694 case CB_GETDROPPEDSTATE:
1695 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1698 *pmsg16 = CB_GETEDITSEL16;
1703 case LB_FINDSTRINGEXACT:
1704 case LB_INSERTSTRING:
1705 case LB_SELECTSTRING:
1708 *plparam = (LPARAM)MapLS( (LPSTR)*plparam );
1709 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1714 case CB_FINDSTRINGEXACT:
1715 case CB_INSERTSTRING:
1716 case CB_SELECTSTRING:
1718 *plparam = (LPARAM)MapLS( (LPSTR)*plparam );
1719 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1722 case LB_GETITEMRECT:
1724 RECT16 *rect = HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16) + sizeof(LPARAM) );
1725 if (!rect) return -1;
1726 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1727 *plparam = MapLS( rect );
1729 *pmsg16 = LB_GETITEMRECT16;
1731 case LB_GETSELITEMS:
1734 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1735 if (!(items = HeapAlloc( GetProcessHeap(), 0,
1736 *pwparam16 * sizeof(INT16) + sizeof(LPARAM)))) return -1;
1737 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1738 *plparam = MapLS( items );
1740 *pmsg16 = LB_GETSELITEMS16;
1742 case LB_SETTABSTOPS:
1747 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1748 if (!(stops = HeapAlloc( GetProcessHeap(), 0,
1749 *pwparam16 * sizeof(INT16) + sizeof(LPARAM)))) return -1;
1750 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1751 *plparam = MapLS( stops );
1754 *pmsg16 = LB_SETTABSTOPS16;
1757 case CB_GETDROPPEDCONTROLRECT:
1759 RECT16 *rect = HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16) + sizeof(LPARAM) );
1760 if (!rect) return -1;
1761 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1762 *plparam = (LPARAM)MapLS(rect);
1764 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1768 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1769 *pmsg16 = LB_GETTEXT16;
1773 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1774 *pmsg16 = CB_GETLBTEXT16;
1779 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
1780 *pmsg16 = EM_SETSEL16;
1787 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1791 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1793 case WM_CTLCOLORMSGBOX:
1794 case WM_CTLCOLOREDIT:
1795 case WM_CTLCOLORLISTBOX:
1796 case WM_CTLCOLORBTN:
1797 case WM_CTLCOLORDLG:
1798 case WM_CTLCOLORSCROLLBAR:
1799 case WM_CTLCOLORSTATIC:
1800 *pmsg16 = WM_CTLCOLOR;
1801 *plparam = MAKELPARAM( (HWND16)*plparam,
1802 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1804 case WM_COMPAREITEM:
1806 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
1807 COMPAREITEMSTRUCT16 *cis = HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16));
1808 if (!cis) return -1;
1809 cis->CtlType = (UINT16)cis32->CtlType;
1810 cis->CtlID = (UINT16)cis32->CtlID;
1811 cis->hwndItem = WIN_Handle16( cis32->hwndItem );
1812 cis->itemID1 = (UINT16)cis32->itemID1;
1813 cis->itemData1 = cis32->itemData1;
1814 cis->itemID2 = (UINT16)cis32->itemID2;
1815 cis->itemData2 = cis32->itemData2;
1816 *plparam = MapLS( cis );
1821 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
1822 DELETEITEMSTRUCT16 *dis = HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16) );
1823 if (!dis) return -1;
1824 dis->CtlType = (UINT16)dis32->CtlType;
1825 dis->CtlID = (UINT16)dis32->CtlID;
1826 dis->itemID = (UINT16)dis32->itemID;
1827 dis->hwndItem = (dis->CtlType == ODT_MENU) ? (HWND16)LOWORD(dis32->hwndItem)
1828 : WIN_Handle16( dis32->hwndItem );
1829 dis->itemData = dis32->itemData;
1830 *plparam = MapLS( dis );
1835 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
1836 DRAWITEMSTRUCT16 *dis = HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16) );
1837 if (!dis) return -1;
1838 dis->CtlType = (UINT16)dis32->CtlType;
1839 dis->CtlID = (UINT16)dis32->CtlID;
1840 dis->itemID = (UINT16)dis32->itemID;
1841 dis->itemAction = (UINT16)dis32->itemAction;
1842 dis->itemState = (UINT16)dis32->itemState;
1843 dis->hwndItem = WIN_Handle16( dis32->hwndItem );
1844 dis->hDC = (HDC16)dis32->hDC;
1845 dis->itemData = dis32->itemData;
1846 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1847 *plparam = MapLS( dis );
1850 case WM_MEASUREITEM:
1852 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
1853 MEASUREITEMSTRUCT16 *mis = HeapAlloc( GetProcessHeap(), 0, sizeof(*mis)+sizeof(LPARAM));
1854 if (!mis) return -1;
1855 mis->CtlType = (UINT16)mis32->CtlType;
1856 mis->CtlID = (UINT16)mis32->CtlID;
1857 mis->itemID = (UINT16)mis32->itemID;
1858 mis->itemWidth = (UINT16)mis32->itemWidth;
1859 mis->itemHeight = (UINT16)mis32->itemHeight;
1860 mis->itemData = mis32->itemData;
1861 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1862 *plparam = MapLS( mis );
1865 case WM_GETMINMAXINFO:
1867 MINMAXINFO16 *mmi = HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi) + sizeof(LPARAM) );
1868 if (!mmi) return -1;
1869 STRUCT32_MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
1870 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1871 *plparam = MapLS( mmi );
1875 case WM_ASKCBFORMATNAME:
1878 *pwparam16 = (WPARAM16)min( wParam32, 0xff80 ); /* Must be < 64K */
1879 if (!(str = HeapAlloc( GetProcessHeap(), 0, *pwparam16 + sizeof(LPARAM)))) return -1;
1880 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1881 *plparam = MapLS( str );
1886 MDICREATESTRUCT16 *cs;
1887 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
1889 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16) ))) return -1;
1890 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1891 cs->szTitle = MapLS( cs32->szTitle );
1892 cs->szClass = MapLS( cs32->szClass );
1893 *plparam = MapLS( cs );
1896 case WM_MDIGETACTIVE:
1899 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1900 (HMENU16)LOWORD(*plparam) );
1901 *pwparam16 = (*plparam == 0);
1904 if(HIWORD(wParam32) & MF_POPUP)
1907 if (((UINT)HIWORD(wParam32) != 0xFFFF) || (*plparam))
1909 if((hmenu = GetSubMenu((HMENU16)*plparam, *pwparam16)))
1915 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1917 case WM_MDIACTIVATE:
1918 if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_MDICHILD)
1920 *pwparam16 = ((HWND)*plparam == hwnd);
1921 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1922 (HWND16)LOWORD(wParam32) );
1926 *pwparam16 = WIN_Handle16( (HWND)wParam32 );
1932 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
1933 NCCALCSIZE_PARAMS16 *nc = HeapAlloc( GetProcessHeap(), 0, sizeof(*nc) + sizeof(LPARAM));
1936 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1940 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1941 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1942 if (!(wp = HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16) )))
1944 HeapFree( GetProcessHeap(), 0, nc );
1947 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1948 nc->lppos = MapLS( wp );
1950 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1951 *plparam = MapLS( nc );
1958 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
1960 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16) ))) return -1;
1961 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1962 cs->lpszName = MapLS( cs32->lpszName );
1963 cs->lpszClass = MapLS( cs32->lpszClass );
1964 *plparam = MapLS( cs );
1967 case WM_PARENTNOTIFY:
1968 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1969 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1970 /* else nothing to do */
1973 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
1976 case WM_WININICHANGE:
1977 case WM_DEVMODECHANGE:
1978 *plparam = MapLS( (LPSTR)*plparam );
1980 case WM_WINDOWPOSCHANGING:
1981 case WM_WINDOWPOSCHANGED:
1983 WINDOWPOS16 *wp = HeapAlloc( GetProcessHeap(), 0, sizeof(*wp) + sizeof(LPARAM) );
1985 STRUCT32_WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
1986 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1987 *plparam = MapLS( wp );
1992 LPMSG msg32 = (LPMSG) *plparam;
1993 LPMSG16 msg16 = HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16) );
1995 if (!msg16) return -1;
1996 msg16->hwnd = WIN_Handle16( msg32->hwnd );
1997 msg16->lParam = msg32->lParam;
1998 msg16->time = msg32->time;
1999 CONV_POINT32TO16(&msg32->pt,&msg16->pt);
2000 /* this is right, right? */
2001 if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
2002 &msg16->message,&msg16->wParam, &msg16->lParam)<0)
2004 HeapFree( GetProcessHeap(), 0, msg16 );
2007 *plparam = MapLS( msg16 );
2012 case WM_ACTIVATEAPP:
2013 if (*plparam) *plparam = (LPARAM)THREAD_IdToTEB((DWORD) *plparam)->htask16;
2017 MDINEXTMENU *next = (MDINEXTMENU *)*plparam;
2018 *plparam = next->hmenuIn;
2021 case WM_PAINTCLIPBOARD:
2022 case WM_SIZECLIPBOARD:
2023 FIXME_(msg)("message %04x needs translation\n", msg32 );
2025 /* following messages should not be sent to 16-bit apps */
2028 case WM_CAPTURECHANGED:
2029 case WM_STYLECHANGING:
2030 case WM_STYLECHANGED:
2032 default: /* No translation needed */
2038 /**********************************************************************
2039 * WINPROC_UnmapMsg32ATo16
2041 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2043 void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2052 case LB_FINDSTRINGEXACT:
2053 case LB_INSERTSTRING:
2054 case LB_SELECTSTRING:
2058 case CB_FINDSTRINGEXACT:
2059 case CB_INSERTSTRING:
2060 case CB_SELECTSTRING:
2064 case WM_WININICHANGE:
2065 case WM_DEVMODECHANGE:
2066 UnMapLS( (SEGPTR)p16->lParam );
2068 case LB_SETTABSTOPS:
2069 case WM_COMPAREITEM:
2073 void *ptr = MapSL( p16->lParam );
2074 UnMapLS( p16->lParam );
2075 HeapFree( GetProcessHeap(), 0, ptr );
2078 case CB_GETDROPPEDCONTROLRECT:
2079 case LB_GETITEMRECT:
2081 RECT16 *rect = MapSL(p16->lParam);
2082 UnMapLS( p16->lParam );
2083 p16->lParam = *(LPARAM *)(rect + 1);
2084 CONV_RECT16TO32( rect, (RECT *)(p16->lParam));
2085 HeapFree( GetProcessHeap(), 0, rect );
2088 case LB_GETSELITEMS:
2091 LPINT16 items = MapSL(p16->lParam);
2092 UnMapLS( p16->lParam );
2093 p16->lParam = *((LPARAM *)items - 1);
2094 for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
2095 HeapFree( GetProcessHeap(), 0, (LPARAM *)items - 1 );
2101 *((LPUINT)(wParam)) = LOWORD(p16->lResult);
2103 *((LPUINT)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
2106 case WM_MEASUREITEM:
2108 MEASUREITEMSTRUCT16 *mis = MapSL(p16->lParam);
2109 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
2110 mis32->itemWidth = mis->itemWidth;
2111 mis32->itemHeight = mis->itemHeight;
2112 UnMapLS( p16->lParam );
2113 HeapFree( GetProcessHeap(), 0, mis );
2116 case WM_GETMINMAXINFO:
2118 MINMAXINFO16 *mmi = MapSL(p16->lParam);
2119 UnMapLS( p16->lParam );
2120 p16->lParam = *(LPARAM *)(mmi + 1);
2121 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
2122 HeapFree( GetProcessHeap(), 0, mmi );
2126 case WM_ASKCBFORMATNAME:
2128 LPSTR str = MapSL(p16->lParam);
2129 UnMapLS( p16->lParam );
2130 p16->lParam = *((LPARAM *)str - 1);
2131 lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
2132 HeapFree( GetProcessHeap(), 0, (LPARAM *)str - 1 );
2137 MDICREATESTRUCT16 *cs = MapSL(p16->lParam);
2138 UnMapLS( cs->szTitle );
2139 UnMapLS( cs->szClass );
2140 UnMapLS( p16->lParam );
2141 HeapFree( GetProcessHeap(), 0, cs );
2144 case WM_MDIGETACTIVE:
2145 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
2146 p16->lResult = (LRESULT)WIN_Handle32( LOWORD(p16->lResult) );
2150 NCCALCSIZE_PARAMS *nc32;
2151 NCCALCSIZE_PARAMS16 *nc = MapSL(p16->lParam);
2152 UnMapLS( p16->lParam );
2153 p16->lParam = *(LPARAM *)(nc + 1);
2154 nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
2155 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
2158 WINDOWPOS16 *pos = MapSL(nc->lppos);
2159 UnMapLS( nc->lppos );
2160 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
2161 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
2162 STRUCT32_WINDOWPOS16to32( pos, nc32->lppos );
2163 HeapFree( GetProcessHeap(), 0, pos );
2165 HeapFree( GetProcessHeap(), 0, nc );
2171 CREATESTRUCT16 *cs = MapSL(p16->lParam);
2172 UnMapLS( p16->lParam );
2173 UnMapLS( cs->lpszName );
2174 UnMapLS( cs->lpszClass );
2175 HeapFree( GetProcessHeap(), 0, cs );
2178 case WM_WINDOWPOSCHANGING:
2179 case WM_WINDOWPOSCHANGED:
2181 WINDOWPOS16 *wp = MapSL(p16->lParam);
2182 UnMapLS( p16->lParam );
2183 p16->lParam = *(LPARAM *)(wp + 1);
2184 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
2185 HeapFree( GetProcessHeap(), 0, wp );
2189 UnMapLS(p16->lParam);
2194 LPMSG16 msg16 = MapSL(p16->lParam);
2196 UnMapLS( p16->lParam );
2197 msgp16.wParam=msg16->wParam;
2198 msgp16.lParam=msg16->lParam;
2199 WINPROC_UnmapMsg32ATo16(((LPMSG)lParam)->hwnd, ((LPMSG)lParam)->message,
2200 ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam,
2202 HeapFree( GetProcessHeap(), 0, msg16 );
2207 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
2208 next->hmenuNext = LOWORD(p16->lResult);
2209 next->hwndNext = WIN_Handle32( HIWORD(p16->lResult) );
2217 /**********************************************************************
2218 * WINPROC_MapMsg32WTo16
2220 * Map a message from 32-bit Unicode to 16-bit.
2221 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2223 INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
2224 UINT16 *pmsg16, WPARAM16 *pwparam16,
2230 *pmsg16 = LOWORD(msg32);
2231 *pwparam16 = LOWORD(wParam32);
2236 case LB_FINDSTRINGEXACT:
2237 case LB_INSERTSTRING:
2238 case LB_SELECTSTRING:
2241 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2242 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2247 case CB_FINDSTRINGEXACT:
2248 case CB_INSERTSTRING:
2249 case CB_SELECTSTRING:
2251 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2252 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2259 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2261 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16) ))) return -1;
2262 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2263 cs->lpszName = map_str_32W_to_16( cs32->lpszName );
2264 cs->lpszClass = map_str_32W_to_16( cs32->lpszClass );
2265 *plparam = MapLS(cs);
2270 MDICREATESTRUCT16 *cs;
2271 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2273 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16) ))) return -1;
2274 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2275 cs->szTitle = map_str_32W_to_16( cs32->szTitle );
2276 cs->szClass = map_str_32W_to_16( cs32->szClass );
2277 *plparam = MapLS(cs);
2281 case WM_WININICHANGE:
2282 case WM_DEVMODECHANGE:
2283 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2287 if ( WINPROC_TestLBForStr( hwnd ))
2289 LPSTR str = HeapAlloc( GetProcessHeap(), 0, 256 ); /* fixme: fixed sized buffer */
2290 if (!str) return -1;
2291 *pmsg16 = (msg32 == LB_GETTEXT)? LB_GETTEXT16 : CB_GETLBTEXT16;
2292 *plparam = (LPARAM)MapLS(str);
2297 wch = LOWORD(wParam32);
2298 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2300 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
2303 wch = LOWORD(wParam32);
2304 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2306 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
2311 case WM_SYSDEADCHAR:
2313 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2317 default: /* No Unicode translation needed (?) */
2318 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2319 pwparam16, plparam );
2324 /**********************************************************************
2325 * WINPROC_UnmapMsg32WTo16
2327 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2329 void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2336 case LB_FINDSTRINGEXACT:
2337 case LB_INSERTSTRING:
2338 case LB_SELECTSTRING:
2343 case CB_FINDSTRINGEXACT:
2344 case CB_INSERTSTRING:
2345 case CB_SELECTSTRING:
2348 case WM_WININICHANGE:
2349 case WM_DEVMODECHANGE:
2350 unmap_str_32W_to_16( p16->lParam );
2355 CREATESTRUCT16 *cs = MapSL(p16->lParam);
2356 UnMapLS( p16->lParam );
2357 unmap_str_32W_to_16( cs->lpszName );
2358 unmap_str_32W_to_16( cs->lpszClass );
2359 HeapFree( GetProcessHeap(), 0, cs );
2364 MDICREATESTRUCT16 *cs = MapSL(p16->lParam);
2365 UnMapLS( p16->lParam );
2366 unmap_str_32W_to_16( cs->szTitle );
2367 unmap_str_32W_to_16( cs->szClass );
2368 HeapFree( GetProcessHeap(), 0, cs );
2372 case WM_ASKCBFORMATNAME:
2374 LPSTR str = MapSL(p16->lParam);
2375 UnMapLS( p16->lParam );
2376 p16->lParam = *((LPARAM *)str - 1);
2377 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)p16->lParam, 0x7fffffff );
2378 HeapFree( GetProcessHeap(), 0, (LPARAM *)str - 1 );
2383 if ( WINPROC_TestLBForStr( hwnd ))
2385 LPSTR str = MapSL(p16->lParam);
2386 UnMapLS( p16->lParam );
2387 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)lParam, 0x7fffffff );
2388 HeapFree( GetProcessHeap(), 0, (LPARAM *)str );
2392 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2398 /**********************************************************************
2399 * WINPROC_CallProc32ATo32W
2401 * Call a window procedure, translating args from Ansi to Unicode.
2403 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
2404 UINT msg, WPARAM wParam,
2410 if( (unmap = WINPROC_MapMsg32ATo32W( hwnd, msg, &wParam, &lParam )) == -1) {
2411 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2412 SPY_GetMsgName(msg, hwnd), wParam, lParam );
2415 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2416 if (unmap) result = WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
2421 /**********************************************************************
2422 * WINPROC_CallProc32WTo32A
2424 * Call a window procedure, translating args from Unicode to Ansi.
2426 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
2427 UINT msg, WPARAM wParam,
2433 if ((unmap = WINPROC_MapMsg32WTo32A( hwnd, msg, &wParam, &lParam )) == -1) {
2434 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2435 SPY_GetMsgName(msg, hwnd), wParam, lParam );
2438 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2439 if( unmap ) WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
2444 /**********************************************************************
2445 * __wine_call_wndproc_32A (USER.1010)
2447 LRESULT WINAPI __wine_call_wndproc_32A( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam,
2453 HWND hwnd32 = WIN_Handle32( hwnd );
2455 if (WINPROC_MapMsg16To32A( hwnd32, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2457 result = WINPROC_CallWndProc( func, hwnd32, msg32, wParam32, lParam );
2458 return WINPROC_UnmapMsg16To32A( hwnd32, msg32, wParam32, lParam, result );
2462 /**********************************************************************
2463 * __wine_call_wndproc_32W (USER.1011)
2465 LRESULT WINAPI __wine_call_wndproc_32W( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam,
2471 HWND hwnd32 = WIN_Handle32( hwnd );
2473 if (WINPROC_MapMsg16To32W( hwnd32, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2475 result = WINPROC_CallWndProc( func, hwnd32, msg32, wParam32, lParam );
2476 return WINPROC_UnmapMsg16To32W( hwnd32, msg32, wParam32, lParam, result );
2480 /**********************************************************************
2481 * WINPROC_CallProc32ATo16
2483 * Call a 16-bit window procedure, translating the 32-bit args.
2485 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
2486 UINT msg, WPARAM wParam,
2492 mp16.lParam = lParam;
2493 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1)
2495 mp16.lResult = WINPROC_CallWndProc16( func, WIN_Handle16(hwnd), msg16,
2496 mp16.wParam, mp16.lParam );
2497 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
2498 return mp16.lResult;
2502 /**********************************************************************
2503 * WINPROC_CallProc32WTo16
2505 * Call a 16-bit window procedure, translating the 32-bit args.
2507 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
2508 UINT msg, WPARAM wParam,
2514 mp16.lParam = lParam;
2515 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
2516 &mp16.lParam ) == -1)
2518 mp16.lResult = WINPROC_CallWndProc16( func, WIN_Handle16(hwnd), msg16,
2519 mp16.wParam, mp16.lParam );
2520 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
2521 return mp16.lResult;
2525 /**********************************************************************
2526 * CallWindowProc (USER.122)
2527 * CallWindowProc16 (USER32.@)
2529 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
2530 WPARAM16 wParam, LPARAM lParam )
2532 WINDOWPROC *proc = WINPROC_GetPtr( func );
2535 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2538 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
2539 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2545 if (!proc->thunk.t_from32.proc) return 0;
2546 return WINPROC_CallWndProc16( proc->thunk.t_from32.proc,
2547 hwnd, msg, wParam, lParam );
2549 if (!proc->thunk.t_from16.proc) return 0;
2550 return __wine_call_wndproc_32A( hwnd, msg, wParam, lParam, proc->thunk.t_from16.proc );
2552 if (!proc->thunk.t_from16.proc) return 0;
2553 return __wine_call_wndproc_32W( hwnd, msg, wParam, lParam, proc->thunk.t_from16.proc );
2555 WARN_(relay)("Invalid proc %p\n", proc );
2561 /**********************************************************************
2562 * CallWindowProcA (USER32.@)
2564 * The CallWindowProc() function invokes the windows procedure _func_,
2565 * with _hwnd_ as the target window, the message specified by _msg_, and
2566 * the message parameters _wParam_ and _lParam_.
2568 * Some kinds of argument conversion may be done, I'm not sure what.
2570 * CallWindowProc() may be used for windows subclassing. Use
2571 * SetWindowLong() to set a new windows procedure for windows of the
2572 * subclass, and handle subclassed messages in the new windows
2573 * procedure. The new windows procedure may then use CallWindowProc()
2574 * with _func_ set to the parent class's windows procedure to dispatch
2575 * the message to the superclass.
2579 * The return value is message dependent.
2585 LRESULT WINAPI CallWindowProcA(
2586 WNDPROC func, /* [in] window procedure */
2587 HWND hwnd, /* [in] target window */
2588 UINT msg, /* [in] message */
2589 WPARAM wParam, /* [in] message dependent parameter */
2590 LPARAM lParam /* [in] message dependent parameter */
2592 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2594 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2597 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2598 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2604 if (!proc->thunk.t_from32.proc) return 0;
2605 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2606 hwnd, msg, wParam, lParam );
2608 if (!proc->thunk.t_from16.proc) return 0;
2609 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2610 hwnd, msg, wParam, lParam );
2612 if (!proc->thunk.t_from16.proc) return 0;
2613 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2614 hwnd, msg, wParam, lParam );
2616 WARN_(relay)("Invalid proc %p\n", proc );
2622 /**********************************************************************
2623 * CallWindowProcW (USER32.@)
2625 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
2626 WPARAM wParam, LPARAM lParam )
2628 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2630 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2633 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2634 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2640 if (!proc->thunk.t_from32.proc) return 0;
2641 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2642 hwnd, msg, wParam, lParam );
2644 if (!proc->thunk.t_from16.proc) return 0;
2645 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2646 hwnd, msg, wParam, lParam );
2648 if (!proc->thunk.t_from16.proc) return 0;
2649 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2650 hwnd, msg, wParam, lParam );
2652 WARN_(relay)("Invalid proc %p\n", proc );