2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
14 #include "wine/winbase16.h"
15 #include "wine/winuser16.h"
16 #include "stackframe.h"
17 #include "builtin16.h"
23 #include "debugtools.h"
28 DECLARE_DEBUG_CHANNEL(msg);
29 DECLARE_DEBUG_CHANNEL(relay);
30 DECLARE_DEBUG_CHANNEL(win);
32 /* Window procedure 16-to-32-bit thunk,
33 * see BuildSpec16File() in tools/build.c */
38 WORD pushw_bp; /* pushw %bp */
39 BYTE pushl_func; /* pushl $proc */
41 WORD pushw_ax; /* pushw %ax */
42 BYTE pushl_relay; /* pushl $relay */
43 void (*relay)(); /* WINPROC_Thunk16To32A/W() */
44 BYTE lcall; /* lcall cs:glue */
45 void (*glue)(); /* __wine_call_from_16_long */
46 WORD cs; /* __FLATCS */
47 WORD lret; /* lret $10 */
49 } WINPROC_THUNK_FROM16;
52 /* Window procedure 32-to-16-bit thunk,
53 * see BuildSpec32File() in tools/build.c */
57 BYTE popl_eax; /* popl %eax (return address) */
58 BYTE pushl_func; /* pushl $proc */
59 WNDPROC16 proc WINE_PACKED;
60 BYTE pushl_eax; /* pushl %eax */
61 BYTE jmp; /* jmp relay (relative jump)*/
62 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
63 } WINPROC_THUNK_FROM32;
65 /* Simple jmp to call 32-bit procedure directly */
68 BYTE jmp; /* jmp proc (relative jump) */
69 WNDPROC proc WINE_PACKED;
74 WINPROC_THUNK_FROM16 t_from16;
75 WINPROC_THUNK_FROM32 t_from32;
78 typedef struct tagWINDOWPROC
80 WINPROC_THUNK thunk; /* Thunk */
81 WINPROC_JUMP jmp; /* Jump */
82 struct tagWINDOWPROC *next; /* Next window proc */
83 UINT magic; /* Magic number */
84 WINDOWPROCTYPE type; /* Function type */
85 WINDOWPROCUSER user; /* Function user */
88 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
90 #define WINPROC_THUNKPROC(pproc) \
91 (((pproc)->type == WIN_PROC_16) ? \
92 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
93 (WNDPROC16)((pproc)->thunk.t_from16.proc))
95 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
96 UINT msg, WPARAM wParam,
98 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
99 UINT msg, WPARAM wParam,
101 static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args );
102 static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args );
104 static HANDLE WinProcHeap;
107 /**********************************************************************
110 BOOL WINPROC_Init(void)
112 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
115 WARN_(relay)("Unable to create winproc heap\n" );
123 /* Some window procedures modify register they shouldn't, or are not
124 * properly declared stdcall; so we need a small assembly wrapper to
126 extern LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
127 WPARAM wParam, LPARAM lParam );
128 __ASM_GLOBAL_FUNC( WINPROC_wrapper,
138 "movl 8(%ebp),%eax\n\t"
140 "leal -12(%ebp),%esp\n\t"
147 static inline LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
148 WPARAM wParam, LPARAM lParam )
150 return proc( hwnd, msg, wParam, lParam );
152 #endif /* __i386__ */
154 /**********************************************************************
155 * WINPROC_CallWndProc32
157 * Call a 32-bit WndProc.
159 static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
160 WPARAM wParam, LPARAM lParam )
166 DPRINTF( "%08lx:Call window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
167 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
168 /* To avoid any deadlocks, all the locks on the windows structures
169 must be suspended before the control is passed to the application */
170 iWndsLocks = WIN_SuspendWndsLock();
171 retvalue = WINPROC_wrapper( proc, hwnd, msg, wParam, lParam );
172 WIN_RestoreWndsLock(iWndsLocks);
175 DPRINTF( "%08lx:Ret window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
176 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg), wParam, lParam, retvalue );
180 /***********************************************************************
181 * WINPROC_CallWndProc16
183 * Call a 16-bit window procedure
185 static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
186 UINT16 msg, WPARAM16 wParam,
192 WND *wndPtr = WIN_FindWndPtr( hwnd );
194 TEB *teb = NtCurrentTeb();
197 /* Window procedures want ax = hInstance, ds = es = ss */
199 memset(&context, '\0', sizeof(context));
200 context.SegDs = context.SegEs = SELECTOROF(teb->cur_stack);
201 context.Eax = wndPtr ? wndPtr->hInstance : context.SegDs;
202 context.SegCs = SELECTOROF(proc);
203 context.Eip = OFFSETOF(proc);
204 context.Ebp = OFFSETOF(teb->cur_stack)
205 + (WORD)&((STACK16FRAME*)0)->bp;
207 WIN_ReleaseWndPtr(wndPtr);
211 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
212 work if structures passed in lParam are placed in the stack/data
213 segment. Programmers easily make the mistake of converting lParam
214 to a near rather than a far pointer, since Windows apparently
215 allows this. We copy the structures to the 16 bit stack; this is
216 ugly but makes these programs work. */
221 offset = sizeof(CREATESTRUCT16); break;
223 offset = sizeof(DRAWITEMSTRUCT16); break;
225 offset = sizeof(COMPAREITEMSTRUCT16); break;
229 void *s = MapSL(lParam);
230 lParam = stack16_push( offset );
231 memcpy( MapSL(lParam), s, offset );
235 iWndsLocks = WIN_SuspendWndsLock();
237 args = (WORD *)THREAD_STACK16(teb) - 5;
238 args[0] = LOWORD(lParam);
239 args[1] = HIWORD(lParam);
244 wine_call_to_16_regs_short( &context, 5 * sizeof(WORD) );
245 ret = MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) );
246 if (offset) stack16_pop( offset );
248 WIN_RestoreWndsLock(iWndsLocks);
254 /**********************************************************************
257 * Return a pointer to the win proc.
259 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
264 /* ptr cannot be < 64K */
265 if (!HIWORD(handle)) return NULL;
267 /* Check for a linear pointer */
269 ptr = (BYTE *)handle;
270 /* First check if it is the jmp address */
271 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->jmp);
272 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
274 /* Now it must be the thunk address */
275 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->thunk);
276 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
279 /* Check for a segmented pointer */
281 if (!IsBadReadPtr16( (SEGPTR)handle, sizeof(proc->thunk) ))
283 ptr = MapSL( (SEGPTR)handle );
284 /* It must be the thunk address */
285 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->thunk);
286 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
294 /**********************************************************************
295 * WINPROC_AllocWinProc
297 * Allocate a new window procedure.
299 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
300 WINDOWPROCUSER user )
302 WINDOWPROC *proc, *oldproc;
304 /* Allocate a window procedure */
306 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
308 /* Check if the function is already a win proc */
310 if ((oldproc = WINPROC_GetPtr( func )))
319 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
320 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
321 proc->thunk.t_from32.proc = func;
322 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
323 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
324 proc->thunk.t_from32.relay = /* relative jump */
325 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
326 (DWORD)(&proc->thunk.t_from32.relay + 1));
330 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
331 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
332 proc->thunk.t_from16.proc = (WNDPROC)func;
333 proc->thunk.t_from16.pushw_ax = 0x5066; /* pushw %ax */
334 proc->thunk.t_from16.pushl_relay = 0x68; /* pushl $relay */
335 proc->thunk.t_from16.relay = (type == WIN_PROC_32A) ?
336 (void(*)())WINPROC_Thunk16To32A :
337 (void(*)())WINPROC_Thunk16To32W;
338 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:glue */
339 proc->thunk.t_from16.glue = (void*)__wine_call_from_16_long;
340 proc->thunk.t_from16.cs = __get_cs();
341 proc->thunk.t_from16.lret = 0xca66;
342 proc->thunk.t_from16.nArgs = 10;
343 proc->jmp.jmp = 0xe9;
344 /* Fixup relative jump */
345 proc->jmp.proc = (WNDPROC)((DWORD)func -
346 (DWORD)(&proc->jmp.proc + 1));
349 /* Should not happen */
352 proc->magic = WINPROC_MAGIC;
357 TRACE_(win)("(%08x,%d): returning %08x\n",
358 (UINT)func, type, (UINT)proc );
363 /**********************************************************************
366 * Get a window procedure pointer that can be passed to the Windows program.
368 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
370 if (!proc) return NULL;
371 if (type == WIN_PROC_16) /* We want a 16:16 address */
373 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
374 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
376 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
377 &((WINDOWPROC *)proc)->thunk );
379 else /* We want a 32-bit address */
381 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
382 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
383 else if (type != ((WINDOWPROC *)proc)->type)
384 /* Have to return the jmp address if types don't match */
385 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
387 /* Some Win16 programs want to get back the proc they set */
388 return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc;
393 /**********************************************************************
396 * Set the window procedure for a window or class. There are
397 * three tree classes of winproc callbacks:
399 * 1) class -> wp - not subclassed
400 * class -> wp -> wp -> wp -> wp - SetClassLong()
402 * 2) window -' / - not subclassed
403 * window -> wp -> wp ' - SetWindowLong()
405 * 3) timer -> wp - SetTimer()
407 * Initially, winproc of the window points to the current winproc
408 * thunk of its class. Subclassing prepends a new thunk to the
409 * window winproc chain at the head of the list. Thus, window thunk
410 * list includes class thunks and the latter are preserved when the
411 * window is destroyed.
414 BOOL WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
415 WINDOWPROCTYPE type, WINDOWPROCUSER user )
417 BOOL bRecycle = FALSE;
418 WINDOWPROC *proc, **ppPrev;
420 /* Check if function is already in the list */
422 ppPrev = (WINDOWPROC **)pFirst;
423 proc = WINPROC_GetPtr( func );
430 if ((*ppPrev)->user != user)
432 /* terminal thunk is being restored */
434 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
435 *(WINDOWPROC **)pFirst = *ppPrev;
444 if (((*ppPrev)->type == type) &&
445 (func == WINPROC_THUNKPROC(*ppPrev)))
452 /* WPF_CLASS thunk terminates window thunk list */
453 if ((*ppPrev)->user != user) break;
454 ppPrev = &(*ppPrev)->next;
459 /* Extract this thunk from the list */
461 *ppPrev = proc->next;
463 else /* Allocate a new one */
465 if (proc) /* Was already a win proc */
468 func = WINPROC_THUNKPROC(proc);
470 proc = WINPROC_AllocWinProc( func, type, user );
471 if (!proc) return FALSE;
474 /* Add the win proc at the head of the list */
476 TRACE_(win)("(%08x,%08x,%d): res=%08x\n",
477 (UINT)*pFirst, (UINT)func, type, (UINT)proc );
478 proc->next = *(WINDOWPROC **)pFirst;
479 *(WINDOWPROC **)pFirst = proc;
484 /**********************************************************************
487 * Free a list of win procs.
489 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
493 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
494 if (((WINDOWPROC *)proc)->user != user) break;
495 TRACE_(win)("freeing %08x\n", (UINT)proc);
496 HeapFree( WinProcHeap, 0, proc );
502 /**********************************************************************
503 * WINPROC_GetProcType
505 * Return the window procedure type.
507 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
510 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
511 return WIN_PROC_INVALID;
512 return ((WINDOWPROC *)proc)->type;
514 /**********************************************************************
515 * WINPROC_TestCBForStr
517 * Return TRUE if the lparam is a string
519 static BOOL WINPROC_TestCBForStr ( HWND hwnd )
522 WND * wnd = WIN_FindWndPtr(hwnd);
523 retvalue = ( !(LOWORD(wnd->dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
524 (LOWORD(wnd->dwStyle) & CBS_HASSTRINGS) );
525 WIN_ReleaseWndPtr(wnd);
528 /**********************************************************************
529 * WINPROC_TestLBForStr
531 * Return TRUE if the lparam is a string
533 static BOOL WINPROC_TestLBForStr ( HWND hwnd )
536 WND * wnd = WIN_FindWndPtr(hwnd);
537 retvalue = ( !(LOWORD(wnd->dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) ||
538 (LOWORD(wnd->dwStyle) & LBS_HASSTRINGS) );
539 WIN_ReleaseWndPtr(wnd);
543 /**********************************************************************
544 * WINPROC_MapMsg32ATo32W
546 * Map a message from Ansi to Unicode.
547 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
550 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
551 * the first four bytes are the handle of the icon
552 * when the WM_SETTEXT message has been used to set the icon
554 INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
559 case WM_ASKCBFORMATNAME:
561 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
562 *pwparam * sizeof(WCHAR) + sizeof(LPARAM) );
564 *ptr++ = *plparam; /* Store previous lParam */
565 *plparam = (LPARAM)ptr;
568 /* lparam is string (0-terminated) */
570 case WM_WININICHANGE:
571 case WM_DEVMODECHANGE:
574 case CB_FINDSTRINGEXACT:
575 case CB_SELECTSTRING:
579 case LB_FINDSTRINGEXACT:
580 case LB_SELECTSTRING:
582 if(!*plparam) return 0;
583 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
584 return (*plparam ? 1 : -1);
585 case WM_GETTEXTLENGTH:
586 case CB_GETLBTEXTLEN:
588 return 1; /* need to map result */
593 { CREATESTRUCTW cs; /* new structure */
594 LPCWSTR lpszName; /* allocated Name */
595 LPCWSTR lpszClass; /* allocated Class */
598 struct s *xs = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct s));
600 xs->cs = *(CREATESTRUCTW *)*plparam;
601 if (HIWORD(xs->cs.lpszName))
602 xs->lpszName = xs->cs.lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
603 (LPCSTR)xs->cs.lpszName );
604 if (HIWORD(xs->cs.lpszClass))
605 xs->lpszClass = xs->cs.lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
606 (LPCSTR)xs->cs.lpszClass );
607 *plparam = (LPARAM)xs;
612 MDICREATESTRUCTW *cs =
613 (MDICREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
615 *cs = *(MDICREATESTRUCTW *)*plparam;
616 if (HIWORD(cs->szClass))
617 cs->szClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
618 (LPCSTR)cs->szClass );
619 if (HIWORD(cs->szTitle))
620 cs->szTitle = HEAP_strdupAtoW( GetProcessHeap(), 0,
621 (LPCSTR)cs->szTitle );
622 *plparam = (LPARAM)cs;
628 case LB_INSERTSTRING:
629 if(!*plparam) return 0;
630 if ( WINPROC_TestLBForStr( hwnd ))
631 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
632 return (*plparam ? 1 : -1);
634 case LB_GETTEXT: /* fixme: fixed sized buffer */
635 { if ( WINPROC_TestLBForStr( hwnd ))
636 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
638 *ptr++ = *plparam; /* Store previous lParam */
639 *plparam = (LPARAM)ptr;
646 case CB_INSERTSTRING:
647 if(!*plparam) return 0;
648 if ( WINPROC_TestCBForStr( hwnd ))
649 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
650 return (*plparam ? 1 : -1);
652 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
653 { if ( WINPROC_TestCBForStr( hwnd ))
654 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
656 *ptr++ = *plparam; /* Store previous lParam */
657 *plparam = (LPARAM)ptr;
664 { WORD len = (WORD)*plparam;
665 LPARAM *ptr = (LPARAM *) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
667 *ptr++ = *plparam; /* Store previous lParam */
668 *((WORD *) ptr) = len; /* Store the length */
669 *plparam = (LPARAM)ptr;
679 case EM_SETPASSWORDCHAR:
681 char ch = LOWORD(*pwparam);
683 MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1);
684 *pwparam = MAKEWPARAM( wch, HIWORD(*pwparam) );
688 case WM_PAINTCLIPBOARD:
689 case WM_SIZECLIPBOARD:
690 FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg), msg );
692 default: /* No translation needed */
698 /**********************************************************************
699 * WINPROC_UnmapMsg32ATo32W
701 * Unmap a message that was mapped from Ansi to Unicode.
703 LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
709 case WM_ASKCBFORMATNAME:
711 LPARAM *ptr = (LPARAM *)lParam - 1;
712 if (wParam > 0 && !WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
713 (LPSTR)*ptr, wParam, NULL, NULL ))
714 ((LPSTR)*ptr)[wParam-1] = 0;
715 HeapFree( GetProcessHeap(), 0, ptr );
718 case WM_GETTEXTLENGTH:
719 case CB_GETLBTEXTLEN:
721 /* there may be one DBCS char for each Unicode char */
727 { CREATESTRUCTW cs; /* new structure */
728 LPWSTR lpszName; /* allocated Name */
729 LPWSTR lpszClass; /* allocated Class */
731 struct s *xs = (struct s *)lParam;
732 if (xs->lpszName) HeapFree( GetProcessHeap(), 0, xs->lpszName );
733 if (xs->lpszClass) HeapFree( GetProcessHeap(), 0, xs->lpszClass );
734 HeapFree( GetProcessHeap(), 0, xs );
740 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
741 if (HIWORD(cs->szTitle))
742 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
743 if (HIWORD(cs->szClass))
744 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
745 HeapFree( GetProcessHeap(), 0, cs );
750 case WM_WININICHANGE:
751 case WM_DEVMODECHANGE:
754 case CB_FINDSTRINGEXACT:
755 case CB_SELECTSTRING:
759 case LB_FINDSTRINGEXACT:
760 case LB_SELECTSTRING:
762 HeapFree( GetProcessHeap(), 0, (void *)lParam );
767 case LB_INSERTSTRING:
768 if ( WINPROC_TestLBForStr( hwnd ))
769 HeapFree( GetProcessHeap(), 0, (void *)lParam );
773 { if ( WINPROC_TestLBForStr( hwnd ))
774 { LPARAM *ptr = (LPARAM *)lParam - 1;
775 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, (LPSTR)*ptr, 0x7fffffff, NULL, NULL );
776 HeapFree( GetProcessHeap(), 0, ptr );
783 case CB_INSERTSTRING:
784 if ( WINPROC_TestCBForStr( hwnd ))
785 HeapFree( GetProcessHeap(), 0, (void *)lParam );
789 { if ( WINPROC_TestCBForStr( hwnd ))
790 { LPARAM *ptr = (LPARAM *)lParam - 1;
791 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, (LPSTR)*ptr, 0x7fffffff, NULL, NULL );
792 HeapFree( GetProcessHeap(), 0, ptr );
799 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
800 WORD len = *(WORD *) lParam;
801 if (len > 0 && !WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
802 (LPSTR)*ptr, len, NULL, NULL ))
803 ((LPSTR)*ptr)[len-1] = 0;
804 HeapFree( GetProcessHeap(), 0, ptr );
812 /**********************************************************************
813 * WINPROC_MapMsg32WTo32A
815 * Map a message from Unicode to Ansi.
816 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
818 INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
823 case WM_ASKCBFORMATNAME:
825 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
826 *pwparam + sizeof(LPARAM) );
828 *ptr++ = *plparam; /* Store previous lParam */
829 *plparam = (LPARAM)ptr;
834 case WM_WININICHANGE:
835 case WM_DEVMODECHANGE:
838 case CB_FINDSTRINGEXACT:
839 case CB_SELECTSTRING:
843 case LB_FINDSTRINGEXACT:
844 case LB_SELECTSTRING:
846 if(!*plparam) return 0;
847 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
848 return (*plparam ? 1 : -1);
853 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0,
856 *cs = *(CREATESTRUCTA *)*plparam;
857 if (HIWORD(cs->lpszName))
858 cs->lpszName = HEAP_strdupWtoA( GetProcessHeap(), 0,
859 (LPCWSTR)cs->lpszName );
860 if (HIWORD(cs->lpszClass))
861 cs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
862 (LPCWSTR)cs->lpszClass);
863 *plparam = (LPARAM)cs;
868 MDICREATESTRUCTA *cs =
869 (MDICREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
871 *cs = *(MDICREATESTRUCTA *)*plparam;
872 if (HIWORD(cs->szTitle))
873 cs->szTitle = HEAP_strdupWtoA( GetProcessHeap(), 0,
874 (LPCWSTR)cs->szTitle );
875 if (HIWORD(cs->szClass))
876 cs->szClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
877 (LPCWSTR)cs->szClass );
878 *plparam = (LPARAM)cs;
884 case LB_INSERTSTRING:
885 if(!*plparam) return 0;
886 if ( WINPROC_TestLBForStr( hwnd ))
887 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
888 return (*plparam ? 1 : -1);
890 case LB_GETTEXT: /* fixme: fixed sized buffer */
891 { if ( WINPROC_TestLBForStr( hwnd ))
892 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
894 *ptr++ = *plparam; /* Store previous lParam */
895 *plparam = (LPARAM)ptr;
902 case CB_INSERTSTRING:
903 if(!*plparam) return 0;
904 if ( WINPROC_TestCBForStr( hwnd ))
905 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
906 return (*plparam ? 1 : -1);
908 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
909 { if ( WINPROC_TestCBForStr( hwnd ))
910 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
912 *ptr++ = *plparam; /* Store previous lParam */
913 *plparam = (LPARAM)ptr;
920 { WORD len = (WORD)*plparam;
921 LPARAM *ptr = (LPARAM *) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
923 *ptr++ = *plparam; /* Store previous lParam */
924 *((WORD *) ptr) = len; /* Store the length */
925 *plparam = (LPARAM)ptr;
935 case EM_SETPASSWORDCHAR:
937 WCHAR wch = LOWORD(*pwparam);
939 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL );
940 *pwparam = MAKEWPARAM( ch, HIWORD(*pwparam) );
944 case WM_PAINTCLIPBOARD:
945 case WM_SIZECLIPBOARD:
946 FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg),msg );
948 default: /* No translation needed */
954 /**********************************************************************
955 * WINPROC_UnmapMsg32WTo32A
957 * Unmap a message that was mapped from Unicode to Ansi.
959 void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
964 case WM_ASKCBFORMATNAME:
966 LPARAM *ptr = (LPARAM *)lParam - 1;
969 if (!MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, wParam ))
970 ((LPWSTR)*ptr)[wParam-1] = 0;
972 HeapFree( GetProcessHeap(), 0, ptr );
977 case WM_WININICHANGE:
978 case WM_DEVMODECHANGE:
981 case CB_FINDSTRINGEXACT:
982 case CB_SELECTSTRING:
986 case LB_FINDSTRINGEXACT:
987 case LB_SELECTSTRING:
989 HeapFree( GetProcessHeap(), 0, (void *)lParam );
995 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
996 if (HIWORD(cs->lpszName))
997 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
998 if (HIWORD(cs->lpszClass))
999 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
1000 HeapFree( GetProcessHeap(), 0, cs );
1006 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1007 if (HIWORD(cs->szTitle))
1008 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
1009 if (HIWORD(cs->szClass))
1010 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
1011 HeapFree( GetProcessHeap(), 0, cs );
1017 case LB_INSERTSTRING:
1018 if ( WINPROC_TestLBForStr( hwnd ))
1019 HeapFree( GetProcessHeap(), 0, (void *)lParam );
1023 if ( WINPROC_TestLBForStr( hwnd ))
1025 LPARAM *ptr = (LPARAM *)lParam - 1;
1026 MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, 0x7fffffff );
1027 HeapFree( GetProcessHeap(), 0, ptr );
1033 case CB_INSERTSTRING:
1034 if ( WINPROC_TestCBForStr( hwnd ))
1035 HeapFree( GetProcessHeap(), 0, (void *)lParam );
1039 if ( WINPROC_TestCBForStr( hwnd ))
1041 LPARAM *ptr = (LPARAM *)lParam - 1;
1042 MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, 0x7fffffff );
1043 HeapFree( GetProcessHeap(), 0, ptr );
1047 /* Multiline edit */
1049 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lparam */
1050 WORD len = *(WORD *)ptr;
1053 if (!MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, len ))
1054 ((LPWSTR)*ptr)[len-1] = 0;
1056 HeapFree( GetProcessHeap(), 0, ptr );
1063 /**********************************************************************
1064 * WINPROC_MapMsg16To32A
1066 * Map a message from 16- to 32-bit Ansi.
1067 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1069 INT WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1070 WPARAM *pwparam32, LPARAM *plparam )
1072 *pmsg32 = (UINT)msg16;
1073 *pwparam32 = (WPARAM)wParam16;
1080 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1081 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1085 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1086 *plparam = (LPARAM)(HWND)HIWORD(*plparam);
1089 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
1090 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
1091 *pwparam32 = (WPARAM)(HDC)wParam16;
1092 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1094 case WM_COMPAREITEM:
1096 COMPAREITEMSTRUCT16* cis16 = MapSL(*plparam);
1097 COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)
1098 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis));
1099 if (!cis) return -1;
1100 cis->CtlType = cis16->CtlType;
1101 cis->CtlID = cis16->CtlID;
1102 cis->hwndItem = cis16->hwndItem;
1103 cis->itemID1 = cis16->itemID1;
1104 cis->itemData1 = cis16->itemData1;
1105 cis->itemID2 = cis16->itemID2;
1106 cis->itemData2 = cis16->itemData2;
1107 cis->dwLocaleId = 0; /* FIXME */
1108 *plparam = (LPARAM)cis;
1113 DELETEITEMSTRUCT16* dis16 = MapSL(*plparam);
1114 DELETEITEMSTRUCT *dis = (DELETEITEMSTRUCT *)
1115 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis));
1116 if (!dis) return -1;
1117 dis->CtlType = dis16->CtlType;
1118 dis->CtlID = dis16->CtlID;
1119 dis->hwndItem = dis16->hwndItem;
1120 dis->itemData = dis16->itemData;
1121 *plparam = (LPARAM)dis;
1124 case WM_MEASUREITEM:
1126 MEASUREITEMSTRUCT16* mis16 = MapSL(*plparam);
1127 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)
1128 HeapAlloc(GetProcessHeap(), 0,
1129 sizeof(*mis) + sizeof(LPARAM));
1130 if (!mis) return -1;
1131 mis->CtlType = mis16->CtlType;
1132 mis->CtlID = mis16->CtlID;
1133 mis->itemID = mis16->itemID;
1134 mis->itemWidth = mis16->itemWidth;
1135 mis->itemHeight = mis16->itemHeight;
1136 mis->itemData = mis16->itemData;
1137 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1138 *plparam = (LPARAM)mis;
1143 DRAWITEMSTRUCT16* dis16 = MapSL(*plparam);
1144 DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)HeapAlloc(GetProcessHeap(), 0,
1146 if (!dis) return -1;
1147 dis->CtlType = dis16->CtlType;
1148 dis->CtlID = dis16->CtlID;
1149 dis->itemID = dis16->itemID;
1150 dis->itemAction = dis16->itemAction;
1151 dis->itemState = dis16->itemState;
1152 dis->hwndItem = dis16->hwndItem;
1153 dis->hDC = dis16->hDC;
1154 dis->itemData = dis16->itemData;
1155 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
1156 *plparam = (LPARAM)dis;
1159 case WM_GETMINMAXINFO:
1161 MINMAXINFO *mmi = (MINMAXINFO *)HeapAlloc( GetProcessHeap(), 0,
1162 sizeof(*mmi) + sizeof(LPARAM));
1163 if (!mmi) return -1;
1164 STRUCT32_MINMAXINFO16to32( MapSL(*plparam), mmi );
1165 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1166 *plparam = (LPARAM)mmi;
1171 case WM_WININICHANGE:
1172 case WM_DEVMODECHANGE:
1173 case WM_ASKCBFORMATNAME:
1174 *plparam = (LPARAM)MapSL(*plparam);
1178 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1179 MDICREATESTRUCTA *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1181 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
1182 cs->szTitle = MapSL(cs16->szTitle);
1183 cs->szClass = MapSL(cs16->szClass);
1184 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1185 *plparam = (LPARAM)cs;
1188 case WM_MDIGETACTIVE:
1189 *plparam = (LPARAM)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL) );
1190 *(BOOL*)(*plparam) = 0;
1194 *pmsg32=WM_MDIREFRESHMENU;
1195 *pwparam32 = (WPARAM)(HMENU)LOWORD(*plparam);
1196 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1199 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1200 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1203 if((LOWORD(*plparam) & MF_POPUP) && (LOWORD(*plparam) != 0xFFFF))
1205 HMENU hmenu=(HMENU)HIWORD(*plparam);
1206 UINT Pos=MENU_FindSubMenu( &hmenu, wParam16);
1207 if(Pos==0xFFFF) Pos=0; /* NO_SELECTED_ITEM */
1208 *pwparam32 = MAKEWPARAM( Pos, LOWORD(*plparam) );
1210 else *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1211 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1213 case WM_MDIACTIVATE:
1216 *pwparam32 = (WPARAM)(HWND)HIWORD(*plparam);
1217 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1219 else /* message sent to MDI client */
1220 *pwparam32 = wParam16;
1224 NCCALCSIZE_PARAMS16 *nc16;
1225 NCCALCSIZE_PARAMS *nc;
1227 nc = (NCCALCSIZE_PARAMS *)HeapAlloc( GetProcessHeap(), 0,
1228 sizeof(*nc) + sizeof(LPARAM) );
1230 nc16 = MapSL(*plparam);
1231 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
1234 nc->lppos = (WINDOWPOS *)HeapAlloc( GetProcessHeap(), 0,
1235 sizeof(*nc->lppos) );
1236 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
1237 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
1238 if (nc->lppos) STRUCT32_WINDOWPOS16to32( MapSL(nc16->lppos), nc->lppos );
1240 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1241 *plparam = (LPARAM)nc;
1247 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1248 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0,
1249 sizeof(*cs) + sizeof(LPARAM) );
1251 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
1252 cs->lpszName = MapSL(cs16->lpszName);
1253 cs->lpszClass = MapSL(cs16->lpszClass);
1254 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1255 *plparam = (LPARAM)cs;
1258 case WM_PARENTNOTIFY:
1259 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1261 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1262 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1265 case WM_WINDOWPOSCHANGING:
1266 case WM_WINDOWPOSCHANGED:
1268 WINDOWPOS *wp = (WINDOWPOS *)HeapAlloc( GetProcessHeap(), 0,
1269 sizeof(*wp) + sizeof(LPARAM) );
1271 STRUCT32_WINDOWPOS16to32( MapSL(*plparam), wp );
1272 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1273 *plparam = (LPARAM)wp;
1279 LPMSG16 msg16 = MapSL(*plparam);
1280 LPMSG msg32 = (LPMSG)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1282 if (!msg32) return -1;
1283 msg32->hwnd = msg16->hwnd;
1284 msg32->lParam = msg16->lParam;
1285 msg32->time = msg16->time;
1286 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1287 /* this is right, right? */
1288 if (WINPROC_MapMsg16To32A(msg16->message,msg16->wParam,
1289 &msg32->message,&msg32->wParam,
1290 &msg32->lParam)<0) {
1291 HeapFree( GetProcessHeap(), 0, msg32 );
1294 *plparam = (LPARAM)msg32;
1299 *plparam = (LPARAM)MapSL(*plparam);
1301 case WM_ACTIVATEAPP:
1303 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1304 a 32bit window. Might be superflous with 32bit interprocess
1307 HTASK16 htask = (HTASK16) *plparam;
1308 DWORD idThread = (DWORD)TASK_GetPtr(htask)->teb->tid;
1309 *plparam = (LPARAM) idThread;
1314 MDINEXTMENU *next = HeapAlloc( GetProcessHeap(), 0, sizeof(*next) );
1315 if (!next) return -1;
1316 next->hmenuIn = *plparam;
1317 next->hmenuNext = 0;
1319 *plparam = (LPARAM)next;
1322 case WM_PAINTCLIPBOARD:
1323 case WM_SIZECLIPBOARD:
1324 FIXME_(msg)("message %04x needs translation\n",msg16 );
1327 default: /* No translation needed */
1333 /**********************************************************************
1334 * WINPROC_UnmapMsg16To32A
1336 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1338 LRESULT WINPROC_UnmapMsg16To32A( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1343 case WM_COMPAREITEM:
1346 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
1348 case WM_MEASUREITEM:
1350 MEASUREITEMSTRUCT16 *mis16;
1351 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1352 lParam = *(LPARAM *)(mis + 1);
1353 mis16 = MapSL(lParam);
1354 mis16->itemWidth = (UINT16)mis->itemWidth;
1355 mis16->itemHeight = (UINT16)mis->itemHeight;
1356 HeapFree( GetProcessHeap(), 0, mis );
1359 case WM_GETMINMAXINFO:
1361 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1362 lParam = *(LPARAM *)(mmi + 1);
1363 STRUCT32_MINMAXINFO32to16( mmi, MapSL(lParam));
1364 HeapFree( GetProcessHeap(), 0, mmi );
1369 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1370 lParam = *(LPARAM *)(cs + 1);
1371 STRUCT32_MDICREATESTRUCT32Ato16( cs, MapSL(lParam) );
1372 HeapFree( GetProcessHeap(), 0, cs );
1375 case WM_MDIGETACTIVE:
1376 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1377 HeapFree( GetProcessHeap(), 0, (BOOL *)lParam );
1381 NCCALCSIZE_PARAMS16 *nc16;
1382 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1383 lParam = *(LPARAM *)(nc + 1);
1384 nc16 = MapSL(lParam);
1385 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
1388 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
1389 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
1392 STRUCT32_WINDOWPOS32to16( nc->lppos, MapSL(nc16->lppos));
1393 HeapFree( GetProcessHeap(), 0, nc->lppos );
1396 HeapFree( GetProcessHeap(), 0, nc );
1402 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1403 lParam = *(LPARAM *)(cs + 1);
1404 STRUCT32_CREATESTRUCT32Ato16( cs, MapSL(lParam) );
1405 HeapFree( GetProcessHeap(), 0, cs );
1408 case WM_WINDOWPOSCHANGING:
1409 case WM_WINDOWPOSCHANGED:
1411 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1412 lParam = *(LPARAM *)(wp + 1);
1413 STRUCT32_WINDOWPOS32to16(wp, MapSL(lParam));
1414 HeapFree( GetProcessHeap(), 0, wp );
1420 LPMSG msg32 = (LPMSG)lParam;
1422 WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1424 HeapFree( GetProcessHeap(), 0, msg32 );
1429 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
1430 result = MAKELONG( next->hmenuNext, next->hwndNext );
1431 HeapFree( GetProcessHeap(), 0, next );
1439 /**********************************************************************
1440 * WINPROC_MapMsg16To32W
1442 * Map a message from 16- to 32-bit Unicode.
1443 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1445 INT WINPROC_MapMsg16To32W( HWND16 hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1446 WPARAM *pwparam32, LPARAM *plparam )
1451 *pmsg32=(UINT)msg16;
1452 *pwparam32 = (WPARAM)wParam16;
1457 case WM_WININICHANGE:
1458 case WM_DEVMODECHANGE:
1459 case WM_ASKCBFORMATNAME:
1460 *plparam = (LPARAM)MapSL(*plparam);
1461 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, pwparam32, plparam );
1462 case WM_GETTEXTLENGTH:
1463 case CB_GETLBTEXTLEN:
1465 return 1; /* need to map result */
1469 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1470 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
1471 sizeof(*cs) + sizeof(LPARAM) );
1473 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1474 cs->lpszName = MapSL(cs16->lpszName);
1475 cs->lpszClass = MapSL(cs16->lpszClass);
1476 if (HIWORD(cs->lpszName))
1477 cs->lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
1478 (LPCSTR)cs->lpszName );
1479 if (HIWORD(cs->lpszClass))
1480 cs->lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
1481 (LPCSTR)cs->lpszClass );
1482 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1483 *plparam = (LPARAM)cs;
1488 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1489 MDICREATESTRUCTW *cs =
1490 (MDICREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
1491 sizeof(*cs) + sizeof(LPARAM) );
1493 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1494 cs->szTitle = MapSL(cs16->szTitle);
1495 cs->szClass = MapSL(cs16->szClass);
1496 if (HIWORD(cs->szTitle))
1497 cs->szTitle = HEAP_strdupAtoW( GetProcessHeap(), 0,
1498 (LPCSTR)cs->szTitle );
1499 if (HIWORD(cs->szClass))
1500 cs->szClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
1501 (LPCSTR)cs->szClass );
1502 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1503 *plparam = (LPARAM)cs;
1509 LPMSG16 msg16 = MapSL(*plparam);
1510 LPMSG msg32 = (LPMSG)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1512 if (!msg32) return -1;
1513 msg32->hwnd = msg16->hwnd;
1514 msg32->lParam = msg16->lParam;
1515 msg32->time = msg16->time;
1516 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1517 /* this is right, right? */
1518 if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
1519 &msg32->message,&msg32->wParam,
1520 &msg32->lParam)<0) {
1521 HeapFree( GetProcessHeap(), 0, msg32 );
1524 *plparam = (LPARAM)msg32;
1531 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1532 *pwparam32 = MAKEWPARAM( wch, HIWORD(*plparam) );
1533 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1537 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1538 *pwparam32 = MAKEWPARAM( wch, LOWORD(*plparam) );
1539 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1544 case WM_SYSDEADCHAR:
1546 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1550 default: /* No Unicode translation needed */
1551 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1552 pwparam32, plparam );
1557 /**********************************************************************
1558 * WINPROC_UnmapMsg16To32W
1560 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1562 LRESULT WINPROC_UnmapMsg16To32W( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1569 case WM_GETTEXTLENGTH:
1570 case CB_GETLBTEXTLEN:
1572 case WM_ASKCBFORMATNAME:
1573 return WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
1577 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1578 lParam = *(LPARAM *)(cs + 1);
1579 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs, MapSL(lParam) );
1580 if (HIWORD(cs->lpszName))
1581 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
1582 if (HIWORD(cs->lpszClass))
1583 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
1584 HeapFree( GetProcessHeap(), 0, cs );
1589 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1590 lParam = *(LPARAM *)(cs + 1);
1591 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs, MapSL(lParam) );
1592 if (HIWORD(cs->szTitle))
1593 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
1594 if (HIWORD(cs->szClass))
1595 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
1596 HeapFree( GetProcessHeap(), 0, cs );
1602 LPMSG msg32 = (LPMSG)lParam;
1604 WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1606 HeapFree( GetProcessHeap(), 0, msg32 );
1610 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1616 /**********************************************************************
1617 * WINPROC_MapMsg32ATo16
1619 * Map a message from 32-bit Ansi to 16-bit.
1620 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1622 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1623 UINT16 *pmsg16, WPARAM16 *pwparam16,
1626 *pmsg16 = (UINT16)msg32;
1627 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1635 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1644 case EM_SCROLLCARET:
1647 case EM_GETLINECOUNT:
1659 case EM_LINEFROMCHAR:
1660 case EM_SETTABSTOPS:
1661 case EM_SETPASSWORDCHAR:
1662 case EM_EMPTYUNDOBUFFER:
1663 case EM_GETFIRSTVISIBLELINE:
1664 case EM_SETREADONLY:
1665 case EM_SETWORDBREAKPROC:
1666 case EM_GETWORDBREAKPROC:
1667 case EM_GETPASSWORDCHAR:
1668 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1673 case LB_DELETESTRING:
1674 case LB_GETANCHORINDEX:
1675 case LB_GETCARETINDEX:
1678 case LB_GETHORIZONTALEXTENT:
1679 case LB_GETITEMDATA:
1680 case LB_GETITEMHEIGHT:
1682 case LB_GETSELCOUNT:
1684 case LB_GETTOPINDEX:
1685 case LB_RESETCONTENT:
1686 case LB_SELITEMRANGE:
1687 case LB_SELITEMRANGEEX:
1688 case LB_SETANCHORINDEX:
1689 case LB_SETCARETINDEX:
1690 case LB_SETCOLUMNWIDTH:
1692 case LB_SETHORIZONTALEXTENT:
1693 case LB_SETITEMDATA:
1694 case LB_SETITEMHEIGHT:
1696 case LB_SETTOPINDEX:
1697 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1699 case CB_DELETESTRING:
1701 case CB_GETLBTEXTLEN:
1703 case CB_RESETCONTENT:
1707 case CB_SHOWDROPDOWN:
1708 case CB_SETITEMDATA:
1709 case CB_SETITEMHEIGHT:
1710 case CB_GETITEMHEIGHT:
1711 case CB_SETEXTENDEDUI:
1712 case CB_GETEXTENDEDUI:
1713 case CB_GETDROPPEDSTATE:
1714 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1717 *pmsg16 = CB_GETEDITSEL16;
1722 case LB_FINDSTRINGEXACT:
1723 case LB_INSERTSTRING:
1724 case LB_SELECTSTRING:
1728 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1729 if (!str) return -1;
1730 *plparam = (LPARAM)SEGPTR_GET(str);
1732 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1737 case CB_FINDSTRINGEXACT:
1738 case CB_INSERTSTRING:
1739 case CB_SELECTSTRING:
1742 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1743 if (!str) return -1;
1744 *plparam = (LPARAM)SEGPTR_GET(str);
1746 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1749 case LB_GETITEMRECT:
1752 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1753 if (!rect) return -1;
1754 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1755 *plparam = (LPARAM)SEGPTR_GET(rect);
1757 *pmsg16 = LB_GETITEMRECT16;
1759 case LB_GETSELITEMS:
1762 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1763 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1764 + sizeof(LPARAM)))) return -1;
1765 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1766 *plparam = (LPARAM)SEGPTR_GET(items);
1768 *pmsg16 = LB_GETSELITEMS16;
1770 case LB_SETTABSTOPS:
1775 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1776 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1777 + sizeof(LPARAM)))) return -1;
1778 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1779 *plparam = (LPARAM)SEGPTR_GET(stops);
1782 *pmsg16 = LB_SETTABSTOPS16;
1785 case CB_GETDROPPEDCONTROLRECT:
1788 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1789 if (!rect) return -1;
1790 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1791 *plparam = (LPARAM)SEGPTR_GET(rect);
1793 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1797 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1798 *pmsg16 = LB_GETTEXT16;
1802 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1803 *pmsg16 = CB_GETLBTEXT16;
1808 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
1809 *pmsg16 = EM_SETSEL16;
1816 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1820 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1822 case WM_CTLCOLORMSGBOX:
1823 case WM_CTLCOLOREDIT:
1824 case WM_CTLCOLORLISTBOX:
1825 case WM_CTLCOLORBTN:
1826 case WM_CTLCOLORDLG:
1827 case WM_CTLCOLORSCROLLBAR:
1828 case WM_CTLCOLORSTATIC:
1829 *pmsg16 = WM_CTLCOLOR;
1830 *plparam = MAKELPARAM( (HWND16)*plparam,
1831 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1833 case WM_COMPAREITEM:
1835 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
1836 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1837 if (!cis) return -1;
1838 cis->CtlType = (UINT16)cis32->CtlType;
1839 cis->CtlID = (UINT16)cis32->CtlID;
1840 cis->hwndItem = (HWND16)cis32->hwndItem;
1841 cis->itemID1 = (UINT16)cis32->itemID1;
1842 cis->itemData1 = cis32->itemData1;
1843 cis->itemID2 = (UINT16)cis32->itemID2;
1844 cis->itemData2 = cis32->itemData2;
1845 *plparam = (LPARAM)SEGPTR_GET(cis);
1850 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
1851 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1852 if (!dis) return -1;
1853 dis->CtlType = (UINT16)dis32->CtlType;
1854 dis->CtlID = (UINT16)dis32->CtlID;
1855 dis->itemID = (UINT16)dis32->itemID;
1856 dis->hwndItem = (HWND16)dis32->hwndItem;
1857 dis->itemData = dis32->itemData;
1858 *plparam = (LPARAM)SEGPTR_GET(dis);
1863 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
1864 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1865 if (!dis) return -1;
1866 dis->CtlType = (UINT16)dis32->CtlType;
1867 dis->CtlID = (UINT16)dis32->CtlID;
1868 dis->itemID = (UINT16)dis32->itemID;
1869 dis->itemAction = (UINT16)dis32->itemAction;
1870 dis->itemState = (UINT16)dis32->itemState;
1871 dis->hwndItem = (HWND16)dis32->hwndItem;
1872 dis->hDC = (HDC16)dis32->hDC;
1873 dis->itemData = dis32->itemData;
1874 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1875 *plparam = (LPARAM)SEGPTR_GET(dis);
1878 case WM_MEASUREITEM:
1880 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
1881 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1882 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1883 if (!mis) return -1;
1884 mis->CtlType = (UINT16)mis32->CtlType;
1885 mis->CtlID = (UINT16)mis32->CtlID;
1886 mis->itemID = (UINT16)mis32->itemID;
1887 mis->itemWidth = (UINT16)mis32->itemWidth;
1888 mis->itemHeight = (UINT16)mis32->itemHeight;
1889 mis->itemData = mis32->itemData;
1890 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1891 *plparam = (LPARAM)SEGPTR_GET(mis);
1894 case WM_GETMINMAXINFO:
1896 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1898 if (!mmi) return -1;
1899 STRUCT32_MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
1900 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1901 *plparam = (LPARAM)SEGPTR_GET(mmi);
1905 case WM_ASKCBFORMATNAME:
1908 *pwparam16 = (WPARAM16)min( wParam32, 0xff80 ); /* Must be < 64K */
1909 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1910 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1911 *plparam = (LPARAM)SEGPTR_GET(str);
1916 MDICREATESTRUCT16 *cs;
1917 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
1920 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1921 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1922 name = SEGPTR_STRDUP( cs32->szTitle );
1923 cls = SEGPTR_STRDUP( cs32->szClass );
1924 cs->szTitle = SEGPTR_GET(name);
1925 cs->szClass = SEGPTR_GET(cls);
1926 *plparam = (LPARAM)SEGPTR_GET(cs);
1929 case WM_MDIGETACTIVE:
1932 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1933 (HMENU16)LOWORD(*plparam) );
1934 *pwparam16 = (*plparam == 0);
1937 if(HIWORD(wParam32) & MF_POPUP)
1940 if (((UINT)HIWORD(wParam32) != 0xFFFF) || (*plparam))
1942 if((hmenu = GetSubMenu((HMENU16)*plparam, *pwparam16)))
1948 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1950 case WM_MDIACTIVATE:
1951 if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_MDICHILD)
1953 *pwparam16 = ((HWND)*plparam == hwnd);
1954 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1955 (HWND16)LOWORD(wParam32) );
1959 *pwparam16 = (HWND)wParam32;
1965 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
1966 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1969 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1973 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1974 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1975 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1980 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1981 nc->lppos = SEGPTR_GET(wp);
1983 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1984 *plparam = (LPARAM)SEGPTR_GET(nc);
1991 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
1994 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1995 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1996 name = SEGPTR_STRDUP( cs32->lpszName );
1997 cls = SEGPTR_STRDUP( cs32->lpszClass );
1998 cs->lpszName = SEGPTR_GET(name);
1999 cs->lpszClass = SEGPTR_GET(cls);
2000 *plparam = (LPARAM)SEGPTR_GET(cs);
2003 case WM_PARENTNOTIFY:
2004 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
2005 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
2006 /* else nothing to do */
2009 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
2012 case WM_WININICHANGE:
2013 case WM_DEVMODECHANGE:
2015 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
2016 if (!str) return -1;
2017 *plparam = (LPARAM)SEGPTR_GET(str);
2020 case WM_WINDOWPOSCHANGING:
2021 case WM_WINDOWPOSCHANGED:
2023 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
2026 STRUCT32_WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
2027 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
2028 *plparam = (LPARAM)SEGPTR_GET(wp);
2033 LPMSG msg32 = (LPMSG) *plparam;
2034 LPMSG16 msg16 = (LPMSG16) SEGPTR_NEW( MSG16 );
2036 if (!msg16) return -1;
2037 msg16->hwnd = msg32->hwnd;
2038 msg16->lParam = msg32->lParam;
2039 msg16->time = msg32->time;
2040 CONV_POINT32TO16(&msg32->pt,&msg16->pt);
2041 /* this is right, right? */
2042 if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
2043 &msg16->message,&msg16->wParam, &msg16->lParam)<0) {
2044 SEGPTR_FREE( msg16 );
2047 *plparam = (LPARAM)SEGPTR_GET(msg16);
2052 case WM_ACTIVATEAPP:
2053 if (*plparam) *plparam = (LPARAM)THREAD_IdToTEB((DWORD) *plparam)->htask16;
2057 MDINEXTMENU *next = (MDINEXTMENU *)*plparam;
2058 *plparam = next->hmenuIn;
2061 case WM_PAINTCLIPBOARD:
2062 case WM_SIZECLIPBOARD:
2063 FIXME_(msg)("message %04x needs translation\n", msg32 );
2065 /* following messages should not be sent to 16-bit apps */
2068 case WM_CAPTURECHANGED:
2069 case WM_STYLECHANGING:
2070 case WM_STYLECHANGED:
2072 default: /* No translation needed */
2078 /**********************************************************************
2079 * WINPROC_UnmapMsg32ATo16
2081 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2083 void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2092 case LB_FINDSTRINGEXACT:
2093 case LB_INSERTSTRING:
2094 case LB_SELECTSTRING:
2095 case LB_SETTABSTOPS:
2098 case CB_FINDSTRINGEXACT:
2099 case CB_INSERTSTRING:
2100 case CB_SELECTSTRING:
2102 case WM_COMPAREITEM:
2106 case WM_WININICHANGE:
2107 case WM_DEVMODECHANGE:
2108 SEGPTR_FREE( MapSL(p16->lParam) );
2111 case CB_GETDROPPEDCONTROLRECT:
2112 case LB_GETITEMRECT:
2114 RECT16 *rect = MapSL(p16->lParam);
2115 p16->lParam = *(LPARAM *)(rect + 1);
2116 CONV_RECT16TO32( rect, (RECT *)(p16->lParam));
2117 SEGPTR_FREE( rect );
2120 case LB_GETSELITEMS:
2123 LPINT16 items = MapSL(lParam);
2124 p16->lParam = *((LPARAM *)items - 1);
2125 for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
2126 SEGPTR_FREE( (LPARAM *)items - 1 );
2132 *((LPUINT)(wParam)) = LOWORD(p16->lResult);
2134 *((LPUINT)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
2139 UnMapLS( (SEGPTR)(p16->lParam) );
2142 case WM_MEASUREITEM:
2144 MEASUREITEMSTRUCT16 *mis = MapSL(p16->lParam);
2145 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
2146 mis32->itemWidth = mis->itemWidth;
2147 mis32->itemHeight = mis->itemHeight;
2151 case WM_GETMINMAXINFO:
2153 MINMAXINFO16 *mmi = MapSL(p16->lParam);
2154 p16->lParam = *(LPARAM *)(mmi + 1);
2155 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
2160 case WM_ASKCBFORMATNAME:
2162 LPSTR str = MapSL(p16->lParam);
2163 p16->lParam = *((LPARAM *)str - 1);
2164 lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
2165 SEGPTR_FREE( (LPARAM *)str - 1 );
2170 MDICREATESTRUCT16 *cs = MapSL(p16->lParam);
2171 SEGPTR_FREE( MapSL(cs->szTitle) );
2172 SEGPTR_FREE( MapSL(cs->szClass) );
2176 case WM_MDIGETACTIVE:
2177 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
2178 p16->lResult = (HWND)LOWORD(p16->lResult);
2182 NCCALCSIZE_PARAMS *nc32;
2183 NCCALCSIZE_PARAMS16 *nc = MapSL(p16->lParam);
2184 p16->lParam = *(LPARAM *)(nc + 1);
2185 nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
2186 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
2189 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
2190 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
2191 STRUCT32_WINDOWPOS16to32( MapSL(nc->lppos), nc32->lppos );
2192 SEGPTR_FREE( MapSL(nc->lppos) );
2200 CREATESTRUCT16 *cs = MapSL(p16->lParam);
2201 SEGPTR_FREE( MapSL(cs->lpszName) );
2202 SEGPTR_FREE( MapSL(cs->lpszClass) );
2206 case WM_WINDOWPOSCHANGING:
2207 case WM_WINDOWPOSCHANGED:
2209 WINDOWPOS16 *wp = MapSL(p16->lParam);
2210 p16->lParam = *(LPARAM *)(wp + 1);
2211 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
2216 UnMapLS(p16->lParam);
2221 LPMSG16 msg16 = MapSL(p16->lParam);
2223 msgp16.wParam=msg16->wParam;
2224 msgp16.lParam=msg16->lParam;
2225 WINPROC_UnmapMsg32ATo16(((LPMSG)lParam)->hwnd, ((LPMSG)lParam)->message,
2226 ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam,
2233 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
2234 next->hmenuNext = LOWORD(p16->lResult);
2235 next->hwndNext = HIWORD(p16->lResult);
2243 /**********************************************************************
2244 * WINPROC_MapMsg32WTo16
2246 * Map a message from 32-bit Unicode to 16-bit.
2247 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2249 INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
2250 UINT16 *pmsg16, WPARAM16 *pwparam16,
2256 *pmsg16 = LOWORD(msg32);
2257 *pwparam16 = LOWORD(wParam32);
2262 case LB_FINDSTRINGEXACT:
2263 case LB_INSERTSTRING:
2264 case LB_SELECTSTRING:
2268 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2269 if (!str) return -1;
2270 *plparam = (LPARAM)SEGPTR_GET(str);
2272 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2277 case CB_FINDSTRINGEXACT:
2278 case CB_INSERTSTRING:
2279 case CB_SELECTSTRING:
2282 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2283 if (!str) return -1;
2284 *plparam = (LPARAM)SEGPTR_GET(str);
2286 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2293 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2296 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
2297 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2298 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
2299 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
2300 cs->lpszName = SEGPTR_GET(name);
2301 cs->lpszClass = SEGPTR_GET(cls);
2302 *plparam = (LPARAM)SEGPTR_GET(cs);
2307 MDICREATESTRUCT16 *cs;
2308 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2311 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
2312 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2313 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
2314 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
2315 cs->szTitle = SEGPTR_GET(name);
2316 cs->szClass = SEGPTR_GET(cls);
2317 *plparam = (LPARAM)SEGPTR_GET(cs);
2322 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2323 if (!str) return -1;
2324 *plparam = (LPARAM)SEGPTR_GET(str);
2329 if ( WINPROC_TestLBForStr( hwnd ))
2331 LPSTR str = (LPSTR) SEGPTR_ALLOC( 256 ); /* fixme: fixed sized buffer */
2332 if (!str) return -1;
2333 *pmsg16 = (msg32 == LB_GETTEXT)? LB_GETTEXT16 : CB_GETLBTEXT16;
2334 *plparam = (LPARAM)SEGPTR_GET(str);
2339 wch = LOWORD(wParam32);
2340 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2342 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
2345 wch = LOWORD(wParam32);
2346 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2348 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
2353 case WM_SYSDEADCHAR:
2355 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2359 default: /* No Unicode translation needed (?) */
2360 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2361 pwparam16, plparam );
2366 /**********************************************************************
2367 * WINPROC_UnmapMsg32WTo16
2369 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2371 void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2377 case WM_ASKCBFORMATNAME:
2379 LPSTR str = MapSL(p16->lParam);
2380 p16->lParam = *((LPARAM *)str - 1);
2381 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)p16->lParam, 0x7fffffff );
2382 SEGPTR_FREE( (LPARAM *)str - 1 );
2387 if ( WINPROC_TestLBForStr( hwnd ))
2389 LPSTR str = MapSL(p16->lParam);
2390 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)lParam, 0x7fffffff );
2391 SEGPTR_FREE( (LPARAM *) str );
2395 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2401 /**********************************************************************
2402 * WINPROC_CallProc32ATo32W
2404 * Call a window procedure, translating args from Ansi to Unicode.
2406 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
2407 UINT msg, WPARAM wParam,
2413 if( (unmap = WINPROC_MapMsg32ATo32W( hwnd, msg, &wParam, &lParam )) == -1) {
2414 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2415 SPY_GetMsgName(msg), wParam, lParam );
2418 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2419 if (unmap) result = WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
2424 /**********************************************************************
2425 * WINPROC_CallProc32WTo32A
2427 * Call a window procedure, translating args from Unicode to Ansi.
2429 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
2430 UINT msg, WPARAM wParam,
2436 if ((unmap = WINPROC_MapMsg32WTo32A( hwnd, msg, &wParam, &lParam )) == -1) {
2437 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2438 SPY_GetMsgName(msg), wParam, lParam );
2441 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2442 if( unmap ) WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
2447 /**********************************************************************
2448 * WINPROC_CallProc16To32A
2450 * Call a 32-bit window procedure, translating the 16-bit args.
2452 static LRESULT WINPROC_CallProc16To32A( WNDPROC func, HWND16 hwnd,
2453 UINT16 msg, WPARAM16 wParam,
2460 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2462 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2463 return WINPROC_UnmapMsg16To32A( hwnd, msg32, wParam32, lParam, result );
2466 /**********************************************************************
2467 * WINPROC_Thunk16To32A
2469 static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args )
2471 HWND16 hwnd = *(HWND16 *)( args+8 );
2472 UINT16 msg = *(HWND16 *)( args+6 );
2473 WPARAM16 wParam = *(HWND16 *)( args+4 );
2474 LPARAM lParam = *(LPARAM *)( args+0 );
2476 return WINPROC_CallProc16To32A( func, hwnd, msg, wParam, lParam );
2480 /**********************************************************************
2481 * WINPROC_CallProc16To32W
2483 * Call a 32-bit window procedure, translating the 16-bit args.
2485 static LRESULT WINPROC_CallProc16To32W( WNDPROC func, HWND16 hwnd,
2486 UINT16 msg, WPARAM16 wParam,
2493 if (WINPROC_MapMsg16To32W( hwnd, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2496 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2498 return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result );
2501 /**********************************************************************
2502 * WINPROC_Thunk16To32W
2504 static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args )
2506 HWND16 hwnd = *(HWND16 *)( args+8 );
2507 UINT16 msg = *(HWND16 *)( args+6 );
2508 WPARAM16 wParam = *(HWND16 *)( args+4 );
2509 LPARAM lParam = *(LPARAM *)( args+0 );
2511 return WINPROC_CallProc16To32W( func, hwnd, msg, wParam, lParam );
2514 /**********************************************************************
2515 * WINPROC_CallProc32ATo16
2517 * Call a 16-bit window procedure, translating the 32-bit args.
2519 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
2520 UINT msg, WPARAM wParam,
2526 mp16.lParam = lParam;
2527 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
2528 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
2530 mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
2531 mp16.wParam, mp16.lParam );
2532 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
2533 return mp16.lResult;
2537 /**********************************************************************
2538 * WINPROC_CallProc32WTo16
2540 * Call a 16-bit window procedure, translating the 32-bit args.
2542 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
2543 UINT msg, WPARAM wParam,
2549 mp16.lParam = lParam;
2550 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
2551 &mp16.lParam ) == -1)
2553 mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
2554 mp16.wParam, mp16.lParam );
2555 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
2556 return mp16.lResult;
2560 /**********************************************************************
2561 * CallWindowProc (USER.122)
2562 * CallWindowProc16 (USER32.@)
2564 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
2565 WPARAM16 wParam, LPARAM lParam )
2567 WINDOWPROC *proc = WINPROC_GetPtr( func );
2570 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2573 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
2574 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2580 if (!proc->thunk.t_from32.proc) return 0;
2581 return WINPROC_CallWndProc16( proc->thunk.t_from32.proc,
2582 hwnd, msg, wParam, lParam );
2584 if (!proc->thunk.t_from16.proc) return 0;
2585 return WINPROC_CallProc16To32A( proc->thunk.t_from16.proc,
2586 hwnd, msg, wParam, lParam );
2588 if (!proc->thunk.t_from16.proc) return 0;
2589 return WINPROC_CallProc16To32W( proc->thunk.t_from16.proc,
2590 hwnd, msg, wParam, lParam );
2592 WARN_(relay)("Invalid proc %p\n", proc );
2598 /**********************************************************************
2599 * CallWindowProcA (USER32.@)
2601 * The CallWindowProc() function invokes the windows procedure _func_,
2602 * with _hwnd_ as the target window, the message specified by _msg_, and
2603 * the message parameters _wParam_ and _lParam_.
2605 * Some kinds of argument conversion may be done, I'm not sure what.
2607 * CallWindowProc() may be used for windows subclassing. Use
2608 * SetWindowLong() to set a new windows procedure for windows of the
2609 * subclass, and handle subclassed messages in the new windows
2610 * procedure. The new windows procedure may then use CallWindowProc()
2611 * with _func_ set to the parent class's windows procedure to dispatch
2612 * the message to the superclass.
2616 * The return value is message dependent.
2622 LRESULT WINAPI CallWindowProcA(
2623 WNDPROC func, /* [in] window procedure */
2624 HWND hwnd, /* [in] target window */
2625 UINT msg, /* [in] message */
2626 WPARAM wParam, /* [in] message dependent parameter */
2627 LPARAM lParam /* [in] message dependent parameter */
2629 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2631 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2634 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2635 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2641 if (!proc->thunk.t_from32.proc) return 0;
2642 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2643 hwnd, msg, wParam, lParam );
2645 if (!proc->thunk.t_from16.proc) return 0;
2646 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2647 hwnd, msg, wParam, lParam );
2649 if (!proc->thunk.t_from16.proc) return 0;
2650 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2651 hwnd, msg, wParam, lParam );
2653 WARN_(relay)("Invalid proc %p\n", proc );
2659 /**********************************************************************
2660 * CallWindowProcW (USER32.@)
2662 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
2663 WPARAM wParam, LPARAM lParam )
2665 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2667 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2670 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2671 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2677 if (!proc->thunk.t_from32.proc) return 0;
2678 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2679 hwnd, msg, wParam, lParam );
2681 if (!proc->thunk.t_from16.proc) return 0;
2682 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2683 hwnd, msg, wParam, lParam );
2685 if (!proc->thunk.t_from16.proc) return 0;
2686 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2687 hwnd, msg, wParam, lParam );
2689 WARN_(relay)("Invalid proc %p\n", proc );