2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/port.h"
31 #include "wine/winbase16.h"
32 #include "wine/winuser16.h"
33 #include "stackframe.h"
34 #include "selectors.h"
40 #include "wine/debug.h"
45 WINE_DECLARE_DEBUG_CHANNEL(msg);
46 WINE_DECLARE_DEBUG_CHANNEL(relay);
47 WINE_DECLARE_DEBUG_CHANNEL(win);
51 /* Window procedure 16-to-32-bit thunk */
54 BYTE popl_eax; /* popl %eax (return address) */
55 BYTE pushl_func; /* pushl $proc */
57 BYTE pushl_eax; /* pushl %eax */
58 BYTE ljmp; /* ljmp relay*/
59 DWORD relay_offset; /* __wine_call_wndproc_32A/W */
61 } WINPROC_THUNK_FROM16;
63 /* Window procedure 32-to-16-bit thunk */
66 BYTE popl_eax; /* popl %eax (return address) */
67 BYTE pushl_func; /* pushl $proc */
69 BYTE pushl_eax; /* pushl %eax */
70 BYTE jmp; /* jmp relay (relative jump)*/
71 void (*relay)(); /* WINPROC_CallProc32ATo16() */
72 } WINPROC_THUNK_FROM32;
74 /* Simple jmp to call 32-bit procedure directly */
77 BYTE jmp; /* jmp proc (relative jump) */
84 WINPROC_THUNK_FROM16 t_from16;
85 WINPROC_THUNK_FROM32 t_from32;
88 typedef struct tagWINDOWPROC
90 WINPROC_THUNK thunk; /* Thunk */
91 WINPROC_JUMP jmp; /* Jump */
92 struct tagWINDOWPROC *next; /* Next window proc */
93 UINT magic; /* Magic number */
94 WINDOWPROCTYPE type; /* Function type */
95 WINDOWPROCUSER user; /* Function user */
98 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
100 #define WINPROC_THUNKPROC(pproc) \
101 (((pproc)->type == WIN_PROC_16) ? \
102 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
103 (WNDPROC16)((pproc)->thunk.t_from16.proc))
105 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
106 UINT msg, WPARAM wParam,
108 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
109 UINT msg, WPARAM wParam,
112 static HANDLE WinProcHeap;
113 static WORD WinProcSel;
116 /**********************************************************************
119 BOOL WINPROC_Init(void)
121 WinProcHeap = HeapCreate( 0, 0x10000, 0x10000 );
122 WinProcSel = SELECTOR_AllocBlock( (void *)WinProcHeap, 0x10000,
123 WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT );
124 if (!WinProcHeap || !WinProcSel)
126 WARN_(relay)("Unable to create winproc heap\n" );
134 /* Some window procedures modify register they shouldn't, or are not
135 * properly declared stdcall; so we need a small assembly wrapper to
137 extern LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
138 WPARAM wParam, LPARAM lParam );
139 __ASM_GLOBAL_FUNC( WINPROC_wrapper,
149 "movl 8(%ebp),%eax\n\t"
151 "leal -12(%ebp),%esp\n\t"
158 static inline LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
159 WPARAM wParam, LPARAM lParam )
161 return proc( hwnd, msg, wParam, lParam );
163 #endif /* __i386__ */
165 /**********************************************************************
166 * WINPROC_CallWndProc32
168 * Call a 32-bit WndProc.
170 static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
171 WPARAM wParam, LPARAM lParam )
176 hwnd = WIN_GetFullHandle( hwnd );
178 DPRINTF( "%08lx:Call window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
179 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam );
180 /* To avoid any deadlocks, all the locks on the windows structures
181 must be suspended before the control is passed to the application */
182 iWndsLocks = WIN_SuspendWndsLock();
183 retvalue = WINPROC_wrapper( proc, hwnd, msg, wParam, lParam );
184 WIN_RestoreWndsLock(iWndsLocks);
187 DPRINTF( "%08lx:Ret window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
188 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam, retvalue );
192 /***********************************************************************
193 * WINPROC_CallWndProc16
195 * Call a 16-bit window procedure
197 static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
198 UINT16 msg, WPARAM16 wParam,
205 TEB *teb = NtCurrentTeb();
208 /* Window procedures want ax = hInstance, ds = es = ss */
210 memset(&context, '\0', sizeof(context));
211 context.SegDs = context.SegEs = SELECTOROF(teb->cur_stack);
212 if (!(context.Eax = GetWindowWord16( hwnd, GWL_HINSTANCE ))) context.Eax = context.SegDs;
213 context.SegCs = SELECTOROF(proc);
214 context.Eip = OFFSETOF(proc);
215 context.Ebp = OFFSETOF(teb->cur_stack)
216 + (WORD)&((STACK16FRAME*)0)->bp;
220 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
221 work if structures passed in lParam are placed in the stack/data
222 segment. Programmers easily make the mistake of converting lParam
223 to a near rather than a far pointer, since Windows apparently
224 allows this. We copy the structures to the 16 bit stack; this is
225 ugly but makes these programs work. */
230 offset = sizeof(CREATESTRUCT16); break;
232 offset = sizeof(DRAWITEMSTRUCT16); break;
234 offset = sizeof(COMPAREITEMSTRUCT16); break;
238 void *s = MapSL(lParam);
239 lParam = stack16_push( offset );
240 memcpy( MapSL(lParam), s, offset );
244 iWndsLocks = WIN_SuspendWndsLock();
246 args = (WORD *)THREAD_STACK16(teb) - 5;
247 args[0] = LOWORD(lParam);
248 args[1] = HIWORD(lParam);
253 wine_call_to_16_regs_short( &context, 5 * sizeof(WORD) );
254 ret = MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) );
255 if (offset) stack16_pop( offset );
257 WIN_RestoreWndsLock(iWndsLocks);
263 /**********************************************************************
266 * Return a pointer to the win proc.
268 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
273 /* ptr cannot be < 64K */
274 if (!HIWORD(handle)) return NULL;
276 /* Check for a linear pointer */
278 ptr = (BYTE *)handle;
279 /* First check if it is the jmp address */
280 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->jmp);
281 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
283 /* Now it must be the thunk address */
284 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->thunk);
285 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
288 /* Check for a segmented pointer */
290 if (!IsBadReadPtr16( (SEGPTR)handle, sizeof(proc->thunk) ))
292 ptr = MapSL( (SEGPTR)handle );
293 /* It must be the thunk address */
294 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->thunk);
295 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
303 /**********************************************************************
304 * WINPROC_AllocWinProc
306 * Allocate a new window procedure.
308 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
309 WINDOWPROCUSER user )
311 static FARPROC16 relay_32A, relay_32W;
313 WINDOWPROC *proc, *oldproc;
315 /* Allocate a window procedure */
317 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
319 /* Check if the function is already a win proc */
321 if ((oldproc = WINPROC_GetPtr( func )))
330 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
331 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
332 proc->thunk.t_from32.proc = func;
333 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
334 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
335 proc->thunk.t_from32.relay = /* relative jump */
336 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
337 (DWORD)(&proc->thunk.t_from32.relay + 1));
340 if (!relay_32A) relay_32A = GetProcAddress16( GetModuleHandle16("user"),
341 "__wine_call_wndproc_32A" );
342 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
343 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
344 proc->thunk.t_from16.proc = (WNDPROC)func;
345 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
346 proc->thunk.t_from16.ljmp = 0xea; /* ljmp relay*/
347 proc->thunk.t_from16.relay_offset = OFFSETOF(relay_32A);
348 proc->thunk.t_from16.relay_sel = SELECTOROF(relay_32A);
349 proc->jmp.jmp = 0xe9;
350 /* Fixup relative jump */
351 proc->jmp.proc = (WNDPROC)((DWORD)func - (DWORD)(&proc->jmp.proc + 1));
354 if (!relay_32W) relay_32W = GetProcAddress16( GetModuleHandle16("user"),
355 "__wine_call_wndproc_32W" );
356 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
357 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
358 proc->thunk.t_from16.proc = (WNDPROC)func;
359 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
360 proc->thunk.t_from16.ljmp = 0xea; /* ljmp relay*/
361 proc->thunk.t_from16.relay_offset = OFFSETOF(relay_32W);
362 proc->thunk.t_from16.relay_sel = SELECTOROF(relay_32W);
363 proc->jmp.jmp = 0xe9;
364 /* Fixup relative jump */
365 proc->jmp.proc = (WNDPROC)((DWORD)func - (DWORD)(&proc->jmp.proc + 1));
368 /* Should not happen */
371 proc->magic = WINPROC_MAGIC;
376 TRACE_(win)("(%08x,%d): returning %08x\n",
377 (UINT)func, type, (UINT)proc );
382 /**********************************************************************
385 * Get a window procedure pointer that can be passed to the Windows program.
387 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
389 WINDOWPROC *ptr = (WINDOWPROC *)proc;
391 if (!proc) return NULL;
392 if (type == WIN_PROC_16) /* We want a 16:16 address */
394 if (ptr->type == WIN_PROC_16)
395 return ptr->thunk.t_from32.proc;
397 return (WNDPROC16)MAKESEGPTR( WinProcSel, (char *)&ptr->thunk - (char *)WinProcHeap );
399 else /* We want a 32-bit address */
401 if (ptr->type == WIN_PROC_16)
402 return (WNDPROC16)&ptr->thunk;
403 else if (type != ptr->type)
404 /* Have to return the jmp address if types don't match */
405 return (WNDPROC16)&ptr->jmp;
407 /* Some Win16 programs want to get back the proc they set */
408 return (WNDPROC16)ptr->thunk.t_from16.proc;
413 /**********************************************************************
416 * Set the window procedure for a window or class. There are
417 * three tree classes of winproc callbacks:
419 * 1) class -> wp - not subclassed
420 * class -> wp -> wp -> wp -> wp - SetClassLong()
422 * 2) window -' / - not subclassed
423 * window -> wp -> wp ' - SetWindowLong()
425 * 3) timer -> wp - SetTimer()
427 * Initially, winproc of the window points to the current winproc
428 * thunk of its class. Subclassing prepends a new thunk to the
429 * window winproc chain at the head of the list. Thus, window thunk
430 * list includes class thunks and the latter are preserved when the
431 * window is destroyed.
434 BOOL WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
435 WINDOWPROCTYPE type, WINDOWPROCUSER user )
437 BOOL bRecycle = FALSE;
438 WINDOWPROC *proc, **ppPrev;
440 /* Check if function is already in the list */
442 ppPrev = (WINDOWPROC **)pFirst;
443 proc = WINPROC_GetPtr( func );
450 if ((*ppPrev)->user != user)
452 /* terminal thunk is being restored */
454 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
455 *(WINDOWPROC **)pFirst = *ppPrev;
464 if (((*ppPrev)->type == type) &&
465 (func == WINPROC_THUNKPROC(*ppPrev)))
467 if((*ppPrev)->user == user)
473 WINPROC_FreeProc( *ppPrev, user );
480 /* WPF_CLASS thunk terminates window thunk list */
481 if ((*ppPrev)->user != user) break;
482 ppPrev = &(*ppPrev)->next;
487 /* Extract this thunk from the list */
489 *ppPrev = proc->next;
491 else /* Allocate a new one */
493 if (proc) /* Was already a win proc */
496 func = WINPROC_THUNKPROC(proc);
498 proc = WINPROC_AllocWinProc( func, type, user );
499 if (!proc) return FALSE;
502 /* Add the win proc at the head of the list */
504 TRACE_(win)("(%08x,%08x,%d): res=%08x\n",
505 (UINT)*pFirst, (UINT)func, type, (UINT)proc );
506 proc->next = *(WINDOWPROC **)pFirst;
507 *(WINDOWPROC **)pFirst = proc;
512 /**********************************************************************
515 * Free a list of win procs.
517 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
521 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
522 if (((WINDOWPROC *)proc)->user != user) break;
523 TRACE_(win)("freeing %08x (%d)\n", (UINT)proc, user);
524 HeapFree( WinProcHeap, 0, proc );
530 /**********************************************************************
531 * WINPROC_GetProcType
533 * Return the window procedure type.
535 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
538 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
539 return WIN_PROC_INVALID;
540 return ((WINDOWPROC *)proc)->type;
542 /**********************************************************************
543 * WINPROC_TestCBForStr
545 * Return TRUE if the lparam is a string
547 inline static BOOL WINPROC_TestCBForStr( HWND hwnd )
549 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
550 return (!(style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) || (style & CBS_HASSTRINGS));
552 /**********************************************************************
553 * WINPROC_TestLBForStr
555 * Return TRUE if the lparam is a string
557 inline static BOOL WINPROC_TestLBForStr( HWND hwnd )
559 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
560 return (!(style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) || (style & LBS_HASSTRINGS));
563 /**********************************************************************
564 * WINPROC_MapMsg32ATo32W
566 * Map a message from Ansi to Unicode.
567 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
570 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
571 * the first four bytes are the handle of the icon
572 * when the WM_SETTEXT message has been used to set the icon
574 INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
579 case WM_ASKCBFORMATNAME:
581 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
582 *pwparam * sizeof(WCHAR) + sizeof(LPARAM) );
584 *ptr++ = *plparam; /* Store previous lParam */
585 *plparam = (LPARAM)ptr;
588 /* lparam is string (0-terminated) */
590 case WM_WININICHANGE:
591 case WM_DEVMODECHANGE:
596 if(!*plparam) return 0;
597 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
598 return (*plparam ? 1 : -1);
599 case WM_GETTEXTLENGTH:
600 case CB_GETLBTEXTLEN:
602 return 1; /* need to map result */
607 { CREATESTRUCTW cs; /* new structure */
608 LPCWSTR lpszName; /* allocated Name */
609 LPCWSTR lpszClass; /* allocated Class */
612 struct s *xs = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct s));
614 xs->cs = *(CREATESTRUCTW *)*plparam;
615 if (HIWORD(xs->cs.lpszName))
616 xs->lpszName = xs->cs.lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
617 (LPCSTR)xs->cs.lpszName );
618 if (HIWORD(xs->cs.lpszClass))
619 xs->lpszClass = xs->cs.lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
620 (LPCSTR)xs->cs.lpszClass );
621 *plparam = (LPARAM)xs;
626 MDICREATESTRUCTW *cs =
627 (MDICREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
629 *cs = *(MDICREATESTRUCTW *)*plparam;
630 if (HIWORD(cs->szClass))
631 cs->szClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
632 (LPCSTR)cs->szClass );
633 if (HIWORD(cs->szTitle))
634 cs->szTitle = HEAP_strdupAtoW( GetProcessHeap(), 0,
635 (LPCSTR)cs->szTitle );
636 *plparam = (LPARAM)cs;
642 case LB_INSERTSTRING:
644 case LB_FINDSTRINGEXACT:
645 case LB_SELECTSTRING:
646 if(!*plparam) return 0;
647 if ( WINPROC_TestLBForStr( hwnd ))
648 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
649 return (*plparam ? 1 : -1);
651 case LB_GETTEXT: /* FIXME: fixed sized buffer */
652 { if ( WINPROC_TestLBForStr( hwnd ))
653 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
655 *ptr++ = *plparam; /* Store previous lParam */
656 *plparam = (LPARAM)ptr;
663 case CB_INSERTSTRING:
664 case CB_FINDSTRINGEXACT:
666 case CB_SELECTSTRING:
667 if(!*plparam) return 0;
668 if ( WINPROC_TestCBForStr( hwnd ))
669 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
670 return (*plparam ? 1 : -1);
672 case CB_GETLBTEXT: /* FIXME: fixed sized buffer */
673 { if ( WINPROC_TestCBForStr( hwnd ))
674 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
676 *ptr++ = *plparam; /* Store previous lParam */
677 *plparam = (LPARAM)ptr;
684 { WORD len = (WORD)*plparam;
685 LPARAM *ptr = (LPARAM *) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
687 *ptr++ = *plparam; /* Store previous lParam */
688 *((WORD *) ptr) = len; /* Store the length */
689 *plparam = (LPARAM)ptr;
699 case EM_SETPASSWORDCHAR:
701 BYTE ch = LOWORD(*pwparam);
703 MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1);
704 *pwparam = MAKEWPARAM( wch, HIWORD(*pwparam) );
708 case WM_PAINTCLIPBOARD:
709 case WM_SIZECLIPBOARD:
710 FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg, hwnd), msg );
712 default: /* No translation needed */
718 /**********************************************************************
719 * WINPROC_UnmapMsg32ATo32W
721 * Unmap a message that was mapped from Ansi to Unicode.
723 LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
729 case WM_ASKCBFORMATNAME:
731 LPARAM *ptr = (LPARAM *)lParam - 1;
732 if (wParam > 0 && !WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
733 (LPSTR)*ptr, wParam, NULL, NULL ))
734 ((LPSTR)*ptr)[wParam-1] = 0;
735 HeapFree( GetProcessHeap(), 0, ptr );
738 case WM_GETTEXTLENGTH:
739 case CB_GETLBTEXTLEN:
741 /* there may be one DBCS char for each Unicode char */
747 { CREATESTRUCTW cs; /* new structure */
748 LPWSTR lpszName; /* allocated Name */
749 LPWSTR lpszClass; /* allocated Class */
751 struct s *xs = (struct s *)lParam;
752 if (xs->lpszName) HeapFree( GetProcessHeap(), 0, xs->lpszName );
753 if (xs->lpszClass) HeapFree( GetProcessHeap(), 0, xs->lpszClass );
754 HeapFree( GetProcessHeap(), 0, xs );
760 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
761 if (HIWORD(cs->szTitle))
762 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
763 if (HIWORD(cs->szClass))
764 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
765 HeapFree( GetProcessHeap(), 0, cs );
770 case WM_WININICHANGE:
771 case WM_DEVMODECHANGE:
776 HeapFree( GetProcessHeap(), 0, (void *)lParam );
781 case LB_INSERTSTRING:
783 case LB_FINDSTRINGEXACT:
784 case LB_SELECTSTRING:
785 if ( WINPROC_TestLBForStr( hwnd ))
786 HeapFree( GetProcessHeap(), 0, (void *)lParam );
790 { if ( WINPROC_TestLBForStr( hwnd ))
791 { LPARAM *ptr = (LPARAM *)lParam - 1;
792 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, (LPSTR)*ptr, 0x7fffffff, NULL, NULL );
793 HeapFree( GetProcessHeap(), 0, ptr );
800 case CB_INSERTSTRING:
802 case CB_FINDSTRINGEXACT:
803 case CB_SELECTSTRING:
804 if ( WINPROC_TestCBForStr( hwnd ))
805 HeapFree( GetProcessHeap(), 0, (void *)lParam );
809 { if ( WINPROC_TestCBForStr( hwnd ))
810 { LPARAM *ptr = (LPARAM *)lParam - 1;
811 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, (LPSTR)*ptr, 0x7fffffff, NULL, NULL );
812 HeapFree( GetProcessHeap(), 0, ptr );
819 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
820 WORD len = *(WORD *) lParam;
821 if (len > 0 && !WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
822 (LPSTR)*ptr, len, NULL, NULL ))
823 ((LPSTR)*ptr)[len-1] = 0;
824 HeapFree( GetProcessHeap(), 0, ptr );
832 /**********************************************************************
833 * WINPROC_MapMsg32WTo32A
835 * Map a message from Unicode to Ansi.
836 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
838 INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
843 case WM_ASKCBFORMATNAME:
845 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
846 *pwparam + sizeof(LPARAM) );
848 *ptr++ = *plparam; /* Store previous lParam */
849 *plparam = (LPARAM)ptr;
854 case WM_WININICHANGE:
855 case WM_DEVMODECHANGE:
860 if(!*plparam) return 0;
861 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
862 return (*plparam ? 1 : -1);
867 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0,
870 *cs = *(CREATESTRUCTA *)*plparam;
871 if (HIWORD(cs->lpszName))
872 cs->lpszName = HEAP_strdupWtoA( GetProcessHeap(), 0,
873 (LPCWSTR)cs->lpszName );
874 if (HIWORD(cs->lpszClass))
875 cs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
876 (LPCWSTR)cs->lpszClass);
877 *plparam = (LPARAM)cs;
882 MDICREATESTRUCTA *cs =
883 (MDICREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
885 *cs = *(MDICREATESTRUCTA *)*plparam;
886 if (HIWORD(cs->szTitle))
887 cs->szTitle = HEAP_strdupWtoA( GetProcessHeap(), 0,
888 (LPCWSTR)cs->szTitle );
889 if (HIWORD(cs->szClass))
890 cs->szClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
891 (LPCWSTR)cs->szClass );
892 *plparam = (LPARAM)cs;
898 case LB_INSERTSTRING:
900 case LB_FINDSTRINGEXACT:
901 case LB_SELECTSTRING:
902 if(!*plparam) return 0;
903 if ( WINPROC_TestLBForStr( hwnd ))
904 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
905 return (*plparam ? 1 : -1);
907 case LB_GETTEXT: /* FIXME: fixed sized buffer */
908 { if ( WINPROC_TestLBForStr( hwnd ))
909 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
911 *ptr++ = *plparam; /* Store previous lParam */
912 *plparam = (LPARAM)ptr;
919 case CB_INSERTSTRING:
921 case CB_FINDSTRINGEXACT:
922 case CB_SELECTSTRING:
923 if(!*plparam) return 0;
924 if ( WINPROC_TestCBForStr( hwnd ))
925 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
926 return (*plparam ? 1 : -1);
928 case CB_GETLBTEXT: /* FIXME: fixed sized buffer */
929 { if ( WINPROC_TestCBForStr( hwnd ))
930 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
932 *ptr++ = *plparam; /* Store previous lParam */
933 *plparam = (LPARAM)ptr;
940 { WORD len = (WORD)*plparam;
941 LPARAM *ptr = (LPARAM *) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
943 *ptr++ = *plparam; /* Store previous lParam */
944 *((WORD *) ptr) = len; /* Store the length */
945 *plparam = (LPARAM)ptr;
955 case EM_SETPASSWORDCHAR:
957 WCHAR wch = LOWORD(*pwparam);
959 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL );
960 *pwparam = MAKEWPARAM( ch, HIWORD(*pwparam) );
964 case WM_PAINTCLIPBOARD:
965 case WM_SIZECLIPBOARD:
966 FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg, hwnd),msg );
968 default: /* No translation needed */
974 /**********************************************************************
975 * WINPROC_UnmapMsg32WTo32A
977 * Unmap a message that was mapped from Unicode to Ansi.
979 void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
984 case WM_ASKCBFORMATNAME:
986 LPARAM *ptr = (LPARAM *)lParam - 1;
989 if (!MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, wParam ))
990 ((LPWSTR)*ptr)[wParam-1] = 0;
992 HeapFree( GetProcessHeap(), 0, ptr );
997 case WM_WININICHANGE:
998 case WM_DEVMODECHANGE:
1003 HeapFree( GetProcessHeap(), 0, (void *)lParam );
1009 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1010 if (HIWORD(cs->lpszName))
1011 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
1012 if (HIWORD(cs->lpszClass))
1013 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
1014 HeapFree( GetProcessHeap(), 0, cs );
1020 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1021 if (HIWORD(cs->szTitle))
1022 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
1023 if (HIWORD(cs->szClass))
1024 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
1025 HeapFree( GetProcessHeap(), 0, cs );
1031 case LB_INSERTSTRING:
1033 case LB_FINDSTRINGEXACT:
1034 case LB_SELECTSTRING:
1035 if ( WINPROC_TestLBForStr( hwnd ))
1036 HeapFree( GetProcessHeap(), 0, (void *)lParam );
1040 if ( WINPROC_TestLBForStr( hwnd ))
1042 LPARAM *ptr = (LPARAM *)lParam - 1;
1043 MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, 0x7fffffff );
1044 HeapFree( GetProcessHeap(), 0, ptr );
1050 case CB_INSERTSTRING:
1052 case CB_FINDSTRINGEXACT:
1053 case CB_SELECTSTRING:
1054 if ( WINPROC_TestCBForStr( hwnd ))
1055 HeapFree( GetProcessHeap(), 0, (void *)lParam );
1059 if ( WINPROC_TestCBForStr( hwnd ))
1061 LPARAM *ptr = (LPARAM *)lParam - 1;
1062 MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, 0x7fffffff );
1063 HeapFree( GetProcessHeap(), 0, ptr );
1067 /* Multiline edit */
1069 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lparam */
1070 WORD len = *(WORD *)ptr;
1073 if (!MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, len ))
1074 ((LPWSTR)*ptr)[len-1] = 0;
1076 HeapFree( GetProcessHeap(), 0, ptr );
1082 static HANDLE convert_handle_16_to_32(HANDLE16 src, unsigned int flags)
1085 UINT sz = GlobalSize16(src);
1088 if (!(dst = GlobalAlloc(flags, sz)))
1090 ptr16 = GlobalLock16(src);
1091 ptr32 = GlobalLock(dst);
1092 if (ptr16 != NULL && ptr32 != NULL) memcpy(ptr32, ptr16, sz);
1093 GlobalUnlock16(src);
1099 /**********************************************************************
1100 * WINPROC_MapMsg16To32A
1102 * Map a message from 16- to 32-bit Ansi.
1103 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1105 INT WINPROC_MapMsg16To32A( HWND hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1106 WPARAM *pwparam32, LPARAM *plparam )
1108 *pmsg32 = (UINT)msg16;
1109 *pwparam32 = (WPARAM)wParam16;
1116 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1117 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1121 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1122 *plparam = (LPARAM)WIN_Handle32( HIWORD(*plparam) );
1125 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
1126 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
1127 *pwparam32 = (WPARAM)HDC_32(wParam16);
1128 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1130 case WM_COMPAREITEM:
1132 COMPAREITEMSTRUCT16* cis16 = MapSL(*plparam);
1133 COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)
1134 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis));
1135 if (!cis) return -1;
1136 cis->CtlType = cis16->CtlType;
1137 cis->CtlID = cis16->CtlID;
1138 cis->hwndItem = WIN_Handle32( cis16->hwndItem );
1139 cis->itemID1 = cis16->itemID1;
1140 cis->itemData1 = cis16->itemData1;
1141 cis->itemID2 = cis16->itemID2;
1142 cis->itemData2 = cis16->itemData2;
1143 cis->dwLocaleId = 0; /* FIXME */
1144 *plparam = (LPARAM)cis;
1149 DELETEITEMSTRUCT16* dis16 = MapSL(*plparam);
1150 DELETEITEMSTRUCT *dis = (DELETEITEMSTRUCT *)
1151 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis));
1152 if (!dis) return -1;
1153 dis->CtlType = dis16->CtlType;
1154 dis->CtlID = dis16->CtlID;
1155 dis->hwndItem = WIN_Handle32( dis16->hwndItem );
1156 dis->itemData = dis16->itemData;
1157 *plparam = (LPARAM)dis;
1160 case WM_MEASUREITEM:
1162 MEASUREITEMSTRUCT16* mis16 = MapSL(*plparam);
1163 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)
1164 HeapAlloc(GetProcessHeap(), 0,
1165 sizeof(*mis) + sizeof(LPARAM));
1166 if (!mis) return -1;
1167 mis->CtlType = mis16->CtlType;
1168 mis->CtlID = mis16->CtlID;
1169 mis->itemID = mis16->itemID;
1170 mis->itemWidth = mis16->itemWidth;
1171 mis->itemHeight = mis16->itemHeight;
1172 mis->itemData = mis16->itemData;
1173 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1174 *plparam = (LPARAM)mis;
1179 DRAWITEMSTRUCT16* dis16 = MapSL(*plparam);
1180 DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)HeapAlloc(GetProcessHeap(), 0,
1182 if (!dis) return -1;
1183 dis->CtlType = dis16->CtlType;
1184 dis->CtlID = dis16->CtlID;
1185 dis->itemID = dis16->itemID;
1186 dis->itemAction = dis16->itemAction;
1187 dis->itemState = dis16->itemState;
1188 dis->hwndItem = (dis->CtlType == ODT_MENU) ? (HWND)HMENU_32(dis16->hwndItem)
1189 : WIN_Handle32( dis16->hwndItem );
1190 dis->hDC = dis16->hDC;
1191 dis->itemData = dis16->itemData;
1192 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
1193 *plparam = (LPARAM)dis;
1196 case WM_GETMINMAXINFO:
1198 MINMAXINFO *mmi = (MINMAXINFO *)HeapAlloc( GetProcessHeap(), 0,
1199 sizeof(*mmi) + sizeof(LPARAM));
1200 if (!mmi) return -1;
1201 STRUCT32_MINMAXINFO16to32( MapSL(*plparam), mmi );
1202 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1203 *plparam = (LPARAM)mmi;
1208 case WM_WININICHANGE:
1209 case WM_DEVMODECHANGE:
1210 case WM_ASKCBFORMATNAME:
1211 *plparam = (LPARAM)MapSL(*plparam);
1215 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1216 MDICREATESTRUCTA *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1218 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
1219 cs->szTitle = MapSL(cs16->szTitle);
1220 cs->szClass = MapSL(cs16->szClass);
1221 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1222 *plparam = (LPARAM)cs;
1225 case WM_MDIGETACTIVE:
1226 *plparam = (LPARAM)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL) );
1227 *(BOOL*)(*plparam) = 0;
1231 *pmsg32=WM_MDIREFRESHMENU;
1232 *pwparam32 = (WPARAM)HMENU_32(LOWORD(*plparam));
1233 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1236 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1237 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1240 if((LOWORD(*plparam) & MF_POPUP) && (LOWORD(*plparam) != 0xFFFF))
1242 HMENU hmenu=HMENU_32(HIWORD(*plparam));
1243 UINT Pos=MENU_FindSubMenu( &hmenu, wParam16);
1244 if(Pos==0xFFFF) Pos=0; /* NO_SELECTED_ITEM */
1245 *pwparam32 = MAKEWPARAM( Pos, LOWORD(*plparam) );
1247 else *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1248 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1250 case WM_MDIACTIVATE:
1253 *pwparam32 = (WPARAM)WIN_Handle32( HIWORD(*plparam) );
1254 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1256 else /* message sent to MDI client */
1257 *pwparam32 = wParam16;
1261 NCCALCSIZE_PARAMS16 *nc16;
1262 NCCALCSIZE_PARAMS *nc;
1264 nc = (NCCALCSIZE_PARAMS *)HeapAlloc( GetProcessHeap(), 0,
1265 sizeof(*nc) + sizeof(LPARAM) );
1267 nc16 = MapSL(*plparam);
1268 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
1271 nc->lppos = (WINDOWPOS *)HeapAlloc( GetProcessHeap(), 0,
1272 sizeof(*nc->lppos) );
1273 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
1274 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
1275 if (nc->lppos) STRUCT32_WINDOWPOS16to32( MapSL(nc16->lppos), nc->lppos );
1277 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1278 *plparam = (LPARAM)nc;
1284 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1285 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0,
1286 sizeof(*cs) + sizeof(LPARAM) );
1288 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
1289 cs->lpszName = MapSL(cs16->lpszName);
1290 cs->lpszClass = MapSL(cs16->lpszClass);
1291 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1292 *plparam = (LPARAM)cs;
1295 case WM_PARENTNOTIFY:
1296 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1298 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1299 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1302 case WM_WINDOWPOSCHANGING:
1303 case WM_WINDOWPOSCHANGED:
1305 WINDOWPOS *wp = (WINDOWPOS *)HeapAlloc( GetProcessHeap(), 0,
1306 sizeof(*wp) + sizeof(LPARAM) );
1308 STRUCT32_WINDOWPOS16to32( MapSL(*plparam), wp );
1309 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1310 *plparam = (LPARAM)wp;
1316 LPMSG16 msg16 = MapSL(*plparam);
1317 LPMSG msg32 = (LPMSG)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1319 if (!msg32) return -1;
1320 msg32->hwnd = WIN_Handle32( msg16->hwnd );
1321 msg32->lParam = msg16->lParam;
1322 msg32->time = msg16->time;
1323 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1324 /* this is right, right? */
1325 if (WINPROC_MapMsg16To32A( msg32->hwnd, msg16->message,msg16->wParam,
1326 &msg32->message,&msg32->wParam,
1327 &msg32->lParam)<0) {
1328 HeapFree( GetProcessHeap(), 0, msg32 );
1331 *plparam = (LPARAM)msg32;
1336 *plparam = (LPARAM)MapSL(*plparam);
1338 case WM_ACTIVATEAPP:
1339 /* We need this when SetActiveWindow sends a Sendmessage16() to
1340 * a 32bit window. Might be superflous with 32bit interprocess
1341 * message queues. */
1342 if (*plparam) *plparam = HTASK_32( *plparam );
1346 MDINEXTMENU *next = HeapAlloc( GetProcessHeap(), 0, sizeof(*next) );
1347 if (!next) return -1;
1348 next->hmenuIn = *plparam;
1349 next->hmenuNext = 0;
1351 *plparam = (LPARAM)next;
1354 case WM_PAINTCLIPBOARD:
1355 case WM_SIZECLIPBOARD:
1356 FIXME_(msg)("message %04x needs translation\n",msg16 );
1358 case WM_DDE_INITIATE:
1359 case WM_DDE_TERMINATE:
1360 case WM_DDE_UNADVISE:
1361 case WM_DDE_REQUEST:
1362 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1372 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1373 lo16 = LOWORD(*plparam);
1374 hi = HIWORD(*plparam);
1375 if (lo16 && !(lo32 = convert_handle_16_to_32(lo16, GMEM_DDESHARE)))
1377 *plparam = PackDDElParam(msg16, lo32, hi);
1379 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1386 *pwparam32 = (WPARAM)WIN_Handle32(wParam16);
1388 lo = LOWORD(*plparam);
1389 hi = HIWORD(*plparam);
1391 if (GlobalGetAtomNameA(hi, buf, 2) > 0) flag |= 1;
1392 if (GlobalSize16(hi) != 0) flag |= 2;
1398 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1403 break; /* atom, nothing to do */
1405 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi);
1408 hi = convert_handle_16_to_32(hi, GMEM_DDESHARE);
1411 *plparam = PackDDElParam(WM_DDE_ACK, lo, hi);
1413 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1414 case WM_DDE_EXECUTE:
1415 *plparam = convert_handle_16_to_32(*plparam, GMEM_DDESHARE);
1416 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1417 default: /* No translation needed */
1423 /**********************************************************************
1424 * WINPROC_UnmapMsg16To32A
1426 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1428 LRESULT WINPROC_UnmapMsg16To32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1433 case WM_COMPAREITEM:
1436 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
1438 case WM_MEASUREITEM:
1440 MEASUREITEMSTRUCT16 *mis16;
1441 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1442 lParam = *(LPARAM *)(mis + 1);
1443 mis16 = MapSL(lParam);
1444 mis16->itemWidth = (UINT16)mis->itemWidth;
1445 mis16->itemHeight = (UINT16)mis->itemHeight;
1446 HeapFree( GetProcessHeap(), 0, mis );
1449 case WM_GETMINMAXINFO:
1451 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1452 lParam = *(LPARAM *)(mmi + 1);
1453 STRUCT32_MINMAXINFO32to16( mmi, MapSL(lParam));
1454 HeapFree( GetProcessHeap(), 0, mmi );
1459 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1460 lParam = *(LPARAM *)(cs + 1);
1461 STRUCT32_MDICREATESTRUCT32Ato16( cs, MapSL(lParam) );
1462 HeapFree( GetProcessHeap(), 0, cs );
1465 case WM_MDIGETACTIVE:
1466 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1467 HeapFree( GetProcessHeap(), 0, (BOOL *)lParam );
1471 NCCALCSIZE_PARAMS16 *nc16;
1472 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1473 lParam = *(LPARAM *)(nc + 1);
1474 nc16 = MapSL(lParam);
1475 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
1478 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
1479 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
1482 STRUCT32_WINDOWPOS32to16( nc->lppos, MapSL(nc16->lppos));
1483 HeapFree( GetProcessHeap(), 0, nc->lppos );
1486 HeapFree( GetProcessHeap(), 0, nc );
1492 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1493 lParam = *(LPARAM *)(cs + 1);
1494 STRUCT32_CREATESTRUCT32Ato16( cs, MapSL(lParam) );
1495 HeapFree( GetProcessHeap(), 0, cs );
1498 case WM_WINDOWPOSCHANGING:
1499 case WM_WINDOWPOSCHANGED:
1501 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1502 lParam = *(LPARAM *)(wp + 1);
1503 STRUCT32_WINDOWPOS32to16(wp, MapSL(lParam));
1504 HeapFree( GetProcessHeap(), 0, wp );
1510 LPMSG msg32 = (LPMSG)lParam;
1512 WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1514 HeapFree( GetProcessHeap(), 0, msg32 );
1519 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
1520 result = MAKELONG( HMENU_16(next->hmenuNext), HWND_16(next->hwndNext) );
1521 HeapFree( GetProcessHeap(), 0, next );
1529 /**********************************************************************
1530 * WINPROC_MapMsg16To32W
1532 * Map a message from 16- to 32-bit Unicode.
1533 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1535 INT WINPROC_MapMsg16To32W( HWND hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1536 WPARAM *pwparam32, LPARAM *plparam )
1541 *pmsg32=(UINT)msg16;
1542 *pwparam32 = (WPARAM)wParam16;
1547 case WM_WININICHANGE:
1548 case WM_DEVMODECHANGE:
1549 case WM_ASKCBFORMATNAME:
1550 *plparam = (LPARAM)MapSL(*plparam);
1551 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, pwparam32, plparam );
1552 case WM_GETTEXTLENGTH:
1553 case CB_GETLBTEXTLEN:
1555 return 1; /* need to map result */
1559 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1560 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
1561 sizeof(*cs) + sizeof(LPARAM) );
1563 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1564 cs->lpszName = map_str_16_to_32W(cs16->lpszName);
1565 cs->lpszClass = map_str_16_to_32W(cs16->lpszClass);
1566 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1567 *plparam = (LPARAM)cs;
1572 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1573 MDICREATESTRUCTW *cs =
1574 (MDICREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
1575 sizeof(*cs) + sizeof(LPARAM) );
1577 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1578 cs->szTitle = map_str_16_to_32W(cs16->szTitle);
1579 cs->szClass = map_str_16_to_32W(cs16->szClass);
1580 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1581 *plparam = (LPARAM)cs;
1587 LPMSG16 msg16 = MapSL(*plparam);
1588 LPMSG msg32 = (LPMSG)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1590 if (!msg32) return -1;
1591 msg32->hwnd = WIN_Handle32( msg16->hwnd );
1592 msg32->lParam = msg16->lParam;
1593 msg32->time = msg16->time;
1594 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1595 /* this is right, right? */
1596 if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
1597 &msg32->message,&msg32->wParam,
1598 &msg32->lParam)<0) {
1599 HeapFree( GetProcessHeap(), 0, msg32 );
1602 *plparam = (LPARAM)msg32;
1609 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1610 *pwparam32 = MAKEWPARAM( wch, HIWORD(*plparam) );
1611 *plparam = (LPARAM)WIN_Handle32( LOWORD(*plparam) );
1615 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1616 *pwparam32 = MAKEWPARAM( wch, LOWORD(*plparam) );
1617 *plparam = (LPARAM)HMENU_32(HIWORD(*plparam));
1622 case WM_SYSDEADCHAR:
1624 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1628 default: /* No Unicode translation needed */
1629 return WINPROC_MapMsg16To32A( hwnd, msg16, wParam16, pmsg32,
1630 pwparam32, plparam );
1635 /**********************************************************************
1636 * WINPROC_UnmapMsg16To32W
1638 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1640 LRESULT WINPROC_UnmapMsg16To32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1647 case WM_GETTEXTLENGTH:
1648 case CB_GETLBTEXTLEN:
1650 case WM_ASKCBFORMATNAME:
1651 return WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
1655 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1656 lParam = *(LPARAM *)(cs + 1);
1657 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs, MapSL(lParam) );
1658 unmap_str_16_to_32W( cs->lpszName );
1659 unmap_str_16_to_32W( cs->lpszClass );
1660 HeapFree( GetProcessHeap(), 0, cs );
1665 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1666 lParam = *(LPARAM *)(cs + 1);
1667 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs, MapSL(lParam) );
1668 unmap_str_16_to_32W( cs->szTitle );
1669 unmap_str_16_to_32W( cs->szClass );
1670 HeapFree( GetProcessHeap(), 0, cs );
1676 LPMSG msg32 = (LPMSG)lParam;
1678 WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1680 HeapFree( GetProcessHeap(), 0, msg32 );
1684 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1689 static HANDLE16 convert_handle_32_to_16(HANDLE src, unsigned int flags)
1692 UINT sz = GlobalSize(src);
1695 if (!(dst = GlobalAlloc16(flags, sz)))
1697 ptr32 = GlobalLock(src);
1698 ptr16 = GlobalLock16(dst);
1699 if (ptr16 != NULL && ptr32 != NULL) memcpy(ptr16, ptr32, sz);
1701 GlobalUnlock16(dst);
1707 /**********************************************************************
1708 * WINPROC_MapMsg32ATo16
1710 * Map a message from 32-bit Ansi to 16-bit.
1711 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1713 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1714 UINT16 *pmsg16, WPARAM16 *pwparam16,
1717 *pmsg16 = (UINT16)msg32;
1718 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1726 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1735 case EM_SCROLLCARET:
1738 case EM_GETLINECOUNT:
1750 case EM_LINEFROMCHAR:
1751 case EM_SETTABSTOPS:
1752 case EM_SETPASSWORDCHAR:
1753 case EM_EMPTYUNDOBUFFER:
1754 case EM_GETFIRSTVISIBLELINE:
1755 case EM_SETREADONLY:
1756 case EM_SETWORDBREAKPROC:
1757 case EM_GETWORDBREAKPROC:
1758 case EM_GETPASSWORDCHAR:
1759 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1764 case LB_DELETESTRING:
1765 case LB_GETANCHORINDEX:
1766 case LB_GETCARETINDEX:
1769 case LB_GETHORIZONTALEXTENT:
1770 case LB_GETITEMDATA:
1771 case LB_GETITEMHEIGHT:
1773 case LB_GETSELCOUNT:
1775 case LB_GETTOPINDEX:
1776 case LB_RESETCONTENT:
1777 case LB_SELITEMRANGE:
1778 case LB_SELITEMRANGEEX:
1779 case LB_SETANCHORINDEX:
1780 case LB_SETCARETINDEX:
1781 case LB_SETCOLUMNWIDTH:
1783 case LB_SETHORIZONTALEXTENT:
1784 case LB_SETITEMDATA:
1785 case LB_SETITEMHEIGHT:
1787 case LB_SETTOPINDEX:
1788 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1790 case CB_DELETESTRING:
1792 case CB_GETLBTEXTLEN:
1794 case CB_RESETCONTENT:
1798 case CB_SHOWDROPDOWN:
1799 case CB_SETITEMDATA:
1800 case CB_SETITEMHEIGHT:
1801 case CB_GETITEMHEIGHT:
1802 case CB_SETEXTENDEDUI:
1803 case CB_GETEXTENDEDUI:
1804 case CB_GETDROPPEDSTATE:
1805 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1808 *pmsg16 = CB_GETEDITSEL16;
1813 case LB_FINDSTRINGEXACT:
1814 case LB_INSERTSTRING:
1815 case LB_SELECTSTRING:
1818 *plparam = (LPARAM)MapLS( (LPSTR)*plparam );
1819 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1824 case CB_FINDSTRINGEXACT:
1825 case CB_INSERTSTRING:
1826 case CB_SELECTSTRING:
1828 *plparam = (LPARAM)MapLS( (LPSTR)*plparam );
1829 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1832 case LB_GETITEMRECT:
1834 RECT16 *rect = HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16) + sizeof(LPARAM) );
1835 if (!rect) return -1;
1836 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1837 *plparam = MapLS( rect );
1839 *pmsg16 = LB_GETITEMRECT16;
1841 case LB_GETSELITEMS:
1844 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1845 if (!(items = HeapAlloc( GetProcessHeap(), 0,
1846 *pwparam16 * sizeof(INT16) + sizeof(LPARAM)))) return -1;
1847 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1848 *plparam = MapLS( items );
1850 *pmsg16 = LB_GETSELITEMS16;
1852 case LB_SETTABSTOPS:
1857 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1858 if (!(stops = HeapAlloc( GetProcessHeap(), 0,
1859 *pwparam16 * sizeof(INT16) + sizeof(LPARAM)))) return -1;
1860 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1861 *plparam = MapLS( stops );
1864 *pmsg16 = LB_SETTABSTOPS16;
1867 case CB_GETDROPPEDCONTROLRECT:
1869 RECT16 *rect = HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16) + sizeof(LPARAM) );
1870 if (!rect) return -1;
1871 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1872 *plparam = (LPARAM)MapLS(rect);
1874 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1878 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1879 *pmsg16 = LB_GETTEXT16;
1883 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1884 *pmsg16 = CB_GETLBTEXT16;
1889 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
1890 *pmsg16 = EM_SETSEL16;
1897 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1901 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1903 case WM_CTLCOLORMSGBOX:
1904 case WM_CTLCOLOREDIT:
1905 case WM_CTLCOLORLISTBOX:
1906 case WM_CTLCOLORBTN:
1907 case WM_CTLCOLORDLG:
1908 case WM_CTLCOLORSCROLLBAR:
1909 case WM_CTLCOLORSTATIC:
1910 *pmsg16 = WM_CTLCOLOR;
1911 *plparam = MAKELPARAM( (HWND16)*plparam,
1912 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1914 case WM_COMPAREITEM:
1916 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
1917 COMPAREITEMSTRUCT16 *cis = HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16));
1918 if (!cis) return -1;
1919 cis->CtlType = (UINT16)cis32->CtlType;
1920 cis->CtlID = (UINT16)cis32->CtlID;
1921 cis->hwndItem = HWND_16( cis32->hwndItem );
1922 cis->itemID1 = (UINT16)cis32->itemID1;
1923 cis->itemData1 = cis32->itemData1;
1924 cis->itemID2 = (UINT16)cis32->itemID2;
1925 cis->itemData2 = cis32->itemData2;
1926 *plparam = MapLS( cis );
1931 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
1932 DELETEITEMSTRUCT16 *dis = HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16) );
1933 if (!dis) return -1;
1934 dis->CtlType = (UINT16)dis32->CtlType;
1935 dis->CtlID = (UINT16)dis32->CtlID;
1936 dis->itemID = (UINT16)dis32->itemID;
1937 dis->hwndItem = (dis->CtlType == ODT_MENU) ? (HWND16)LOWORD(dis32->hwndItem)
1938 : HWND_16( dis32->hwndItem );
1939 dis->itemData = dis32->itemData;
1940 *plparam = MapLS( dis );
1945 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
1946 DRAWITEMSTRUCT16 *dis = HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16) );
1947 if (!dis) return -1;
1948 dis->CtlType = (UINT16)dis32->CtlType;
1949 dis->CtlID = (UINT16)dis32->CtlID;
1950 dis->itemID = (UINT16)dis32->itemID;
1951 dis->itemAction = (UINT16)dis32->itemAction;
1952 dis->itemState = (UINT16)dis32->itemState;
1953 dis->hwndItem = HWND_16( dis32->hwndItem );
1954 dis->hDC = HDC_16(dis32->hDC);
1955 dis->itemData = dis32->itemData;
1956 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1957 *plparam = MapLS( dis );
1960 case WM_MEASUREITEM:
1962 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
1963 MEASUREITEMSTRUCT16 *mis = HeapAlloc( GetProcessHeap(), 0, sizeof(*mis)+sizeof(LPARAM));
1964 if (!mis) return -1;
1965 mis->CtlType = (UINT16)mis32->CtlType;
1966 mis->CtlID = (UINT16)mis32->CtlID;
1967 mis->itemID = (UINT16)mis32->itemID;
1968 mis->itemWidth = (UINT16)mis32->itemWidth;
1969 mis->itemHeight = (UINT16)mis32->itemHeight;
1970 mis->itemData = mis32->itemData;
1971 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1972 *plparam = MapLS( mis );
1975 case WM_GETMINMAXINFO:
1977 MINMAXINFO16 *mmi = HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi) + sizeof(LPARAM) );
1978 if (!mmi) return -1;
1979 STRUCT32_MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
1980 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1981 *plparam = MapLS( mmi );
1985 case WM_ASKCBFORMATNAME:
1988 *pwparam16 = (WPARAM16)min( wParam32, 0xff80 ); /* Must be < 64K */
1989 if (!(str = HeapAlloc( GetProcessHeap(), 0, *pwparam16 + sizeof(LPARAM)))) return -1;
1990 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1991 *plparam = MapLS( str );
1996 MDICREATESTRUCT16 *cs;
1997 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
1999 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16) ))) return -1;
2000 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
2001 cs->szTitle = MapLS( cs32->szTitle );
2002 cs->szClass = MapLS( cs32->szClass );
2003 *plparam = MapLS( cs );
2006 case WM_MDIGETACTIVE:
2009 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
2010 (HMENU16)LOWORD(*plparam) );
2011 *pwparam16 = (*plparam == 0);
2014 if(HIWORD(wParam32) & MF_POPUP)
2017 if (((UINT)HIWORD(wParam32) != 0xFFFF) || (*plparam))
2019 if((hmenu = GetSubMenu((HMENU16)*plparam, *pwparam16)))
2025 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
2027 case WM_MDIACTIVATE:
2028 if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_MDICHILD)
2030 *pwparam16 = ((HWND)*plparam == hwnd);
2031 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
2032 (HWND16)LOWORD(wParam32) );
2036 *pwparam16 = HWND_16( (HWND)wParam32 );
2042 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
2043 NCCALCSIZE_PARAMS16 *nc = HeapAlloc( GetProcessHeap(), 0, sizeof(*nc) + sizeof(LPARAM));
2046 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
2050 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
2051 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
2052 if (!(wp = HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16) )))
2054 HeapFree( GetProcessHeap(), 0, nc );
2057 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
2058 nc->lppos = MapLS( wp );
2060 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
2061 *plparam = MapLS( nc );
2068 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
2070 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16) ))) return -1;
2071 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
2072 cs->lpszName = MapLS( cs32->lpszName );
2073 cs->lpszClass = MapLS( cs32->lpszClass );
2074 *plparam = MapLS( cs );
2077 case WM_PARENTNOTIFY:
2078 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
2079 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
2080 /* else nothing to do */
2083 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
2086 case WM_WININICHANGE:
2087 case WM_DEVMODECHANGE:
2088 *plparam = MapLS( (LPSTR)*plparam );
2090 case WM_WINDOWPOSCHANGING:
2091 case WM_WINDOWPOSCHANGED:
2093 WINDOWPOS16 *wp = HeapAlloc( GetProcessHeap(), 0, sizeof(*wp) + sizeof(LPARAM) );
2095 STRUCT32_WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
2096 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
2097 *plparam = MapLS( wp );
2102 LPMSG msg32 = (LPMSG) *plparam;
2103 LPMSG16 msg16 = HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16) );
2105 if (!msg16) return -1;
2106 msg16->hwnd = HWND_16( msg32->hwnd );
2107 msg16->lParam = msg32->lParam;
2108 msg16->time = msg32->time;
2109 CONV_POINT32TO16(&msg32->pt,&msg16->pt);
2110 /* this is right, right? */
2111 if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
2112 &msg16->message,&msg16->wParam, &msg16->lParam)<0)
2114 HeapFree( GetProcessHeap(), 0, msg16 );
2117 *plparam = MapLS( msg16 );
2122 case WM_ACTIVATEAPP:
2123 if (*plparam) *plparam = HTASK_16( (HANDLE)*plparam );
2127 MDINEXTMENU *next = (MDINEXTMENU *)*plparam;
2128 *plparam = next->hmenuIn;
2131 case WM_PAINTCLIPBOARD:
2132 case WM_SIZECLIPBOARD:
2133 FIXME_(msg)("message %04x needs translation\n", msg32 );
2135 /* following messages should not be sent to 16-bit apps */
2138 case WM_CAPTURECHANGED:
2139 case WM_STYLECHANGING:
2140 case WM_STYLECHANGED:
2142 case WM_DDE_INITIATE:
2143 case WM_DDE_TERMINATE:
2144 case WM_DDE_UNADVISE:
2145 case WM_DDE_REQUEST:
2146 *pwparam16 = HWND_16((HWND)wParam32);
2155 *pwparam16 = HWND_16((HWND)wParam32);
2156 UnpackDDElParam(msg32, *plparam, &lo32, &hi);
2157 if (lo32 && !(lo16 = convert_handle_32_to_16(lo32, GMEM_DDESHARE)))
2159 *plparam = MAKELPARAM(lo16, hi);
2161 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2168 *pwparam16 = HWND_16((HWND)wParam32);
2170 UnpackDDElParam(msg32, *plparam, &lo, &hi);
2172 if (GlobalGetAtomNameA((ATOM)hi, buf, sizeof(buf)) > 0) flag |= 1;
2173 if (GlobalSize(hi) != 0) flag |= 2;
2179 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
2184 break; /* atom, nothing to do */
2186 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi);
2189 hi = convert_handle_32_to_16(hi, GMEM_DDESHARE);
2192 *plparam = MAKELPARAM(lo, hi);
2194 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2195 case WM_DDE_EXECUTE:
2196 *plparam = convert_handle_32_to_16(*plparam, GMEM_DDESHARE);
2197 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2198 default: /* No translation needed */
2204 /**********************************************************************
2205 * WINPROC_UnmapMsg32ATo16
2207 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2209 void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2218 case LB_FINDSTRINGEXACT:
2219 case LB_INSERTSTRING:
2220 case LB_SELECTSTRING:
2224 case CB_FINDSTRINGEXACT:
2225 case CB_INSERTSTRING:
2226 case CB_SELECTSTRING:
2230 case WM_WININICHANGE:
2231 case WM_DEVMODECHANGE:
2232 UnMapLS( (SEGPTR)p16->lParam );
2234 case LB_SETTABSTOPS:
2235 case WM_COMPAREITEM:
2239 void *ptr = MapSL( p16->lParam );
2240 UnMapLS( p16->lParam );
2241 HeapFree( GetProcessHeap(), 0, ptr );
2244 case CB_GETDROPPEDCONTROLRECT:
2245 case LB_GETITEMRECT:
2247 RECT16 *rect = MapSL(p16->lParam);
2248 UnMapLS( p16->lParam );
2249 p16->lParam = *(LPARAM *)(rect + 1);
2250 CONV_RECT16TO32( rect, (RECT *)(p16->lParam));
2251 HeapFree( GetProcessHeap(), 0, rect );
2254 case LB_GETSELITEMS:
2257 LPINT16 items = MapSL(p16->lParam);
2258 UnMapLS( p16->lParam );
2259 p16->lParam = *((LPARAM *)items - 1);
2260 for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
2261 HeapFree( GetProcessHeap(), 0, (LPARAM *)items - 1 );
2267 *((PUINT)(wParam)) = LOWORD(p16->lResult);
2269 *((PUINT)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
2272 case WM_MEASUREITEM:
2274 MEASUREITEMSTRUCT16 *mis = MapSL(p16->lParam);
2275 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
2276 mis32->itemWidth = mis->itemWidth;
2277 mis32->itemHeight = mis->itemHeight;
2278 UnMapLS( p16->lParam );
2279 HeapFree( GetProcessHeap(), 0, mis );
2282 case WM_GETMINMAXINFO:
2284 MINMAXINFO16 *mmi = MapSL(p16->lParam);
2285 UnMapLS( p16->lParam );
2286 p16->lParam = *(LPARAM *)(mmi + 1);
2287 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
2288 HeapFree( GetProcessHeap(), 0, mmi );
2292 case WM_ASKCBFORMATNAME:
2294 LPSTR str = MapSL(p16->lParam);
2295 UnMapLS( p16->lParam );
2296 p16->lParam = *((LPARAM *)str - 1);
2297 lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
2298 HeapFree( GetProcessHeap(), 0, (LPARAM *)str - 1 );
2303 MDICREATESTRUCT16 *cs = MapSL(p16->lParam);
2304 UnMapLS( cs->szTitle );
2305 UnMapLS( cs->szClass );
2306 UnMapLS( p16->lParam );
2307 HeapFree( GetProcessHeap(), 0, cs );
2310 case WM_MDIGETACTIVE:
2311 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
2312 p16->lResult = (LRESULT)WIN_Handle32( LOWORD(p16->lResult) );
2316 NCCALCSIZE_PARAMS *nc32;
2317 NCCALCSIZE_PARAMS16 *nc = MapSL(p16->lParam);
2318 UnMapLS( p16->lParam );
2319 p16->lParam = *(LPARAM *)(nc + 1);
2320 nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
2321 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
2324 WINDOWPOS16 *pos = MapSL(nc->lppos);
2325 UnMapLS( nc->lppos );
2326 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
2327 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
2328 STRUCT32_WINDOWPOS16to32( pos, nc32->lppos );
2329 HeapFree( GetProcessHeap(), 0, pos );
2331 HeapFree( GetProcessHeap(), 0, nc );
2337 CREATESTRUCT16 *cs = MapSL(p16->lParam);
2338 UnMapLS( p16->lParam );
2339 UnMapLS( cs->lpszName );
2340 UnMapLS( cs->lpszClass );
2341 HeapFree( GetProcessHeap(), 0, cs );
2344 case WM_WINDOWPOSCHANGING:
2345 case WM_WINDOWPOSCHANGED:
2347 WINDOWPOS16 *wp = MapSL(p16->lParam);
2348 UnMapLS( p16->lParam );
2349 p16->lParam = *(LPARAM *)(wp + 1);
2350 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
2351 HeapFree( GetProcessHeap(), 0, wp );
2355 UnMapLS(p16->lParam);
2360 LPMSG16 msg16 = MapSL(p16->lParam);
2362 UnMapLS( p16->lParam );
2363 msgp16.wParam=msg16->wParam;
2364 msgp16.lParam=msg16->lParam;
2365 WINPROC_UnmapMsg32ATo16(((LPMSG)lParam)->hwnd, ((LPMSG)lParam)->message,
2366 ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam,
2368 HeapFree( GetProcessHeap(), 0, msg16 );
2373 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
2374 next->hmenuNext = LOWORD(p16->lResult);
2375 next->hwndNext = WIN_Handle32( HIWORD(p16->lResult) );
2383 /**********************************************************************
2384 * WINPROC_MapMsg32WTo16
2386 * Map a message from 32-bit Unicode to 16-bit.
2387 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2389 INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
2390 UINT16 *pmsg16, WPARAM16 *pwparam16,
2396 *pmsg16 = LOWORD(msg32);
2397 *pwparam16 = LOWORD(wParam32);
2402 case LB_FINDSTRINGEXACT:
2403 case LB_INSERTSTRING:
2404 case LB_SELECTSTRING:
2407 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2408 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2413 case CB_FINDSTRINGEXACT:
2414 case CB_INSERTSTRING:
2415 case CB_SELECTSTRING:
2417 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2418 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2425 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2427 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16) ))) return -1;
2428 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2429 cs->lpszName = map_str_32W_to_16( cs32->lpszName );
2430 cs->lpszClass = map_str_32W_to_16( cs32->lpszClass );
2431 *plparam = MapLS(cs);
2436 MDICREATESTRUCT16 *cs;
2437 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2439 if (!(cs = HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16) ))) return -1;
2440 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2441 cs->szTitle = map_str_32W_to_16( cs32->szTitle );
2442 cs->szClass = map_str_32W_to_16( cs32->szClass );
2443 *plparam = MapLS(cs);
2447 case WM_WININICHANGE:
2448 case WM_DEVMODECHANGE:
2449 *plparam = map_str_32W_to_16( (LPWSTR)*plparam );
2453 if ( WINPROC_TestLBForStr( hwnd ))
2455 LPSTR str = HeapAlloc( GetProcessHeap(), 0, 256 ); /* FIXME: fixed sized buffer */
2456 if (!str) return -1;
2457 *pmsg16 = (msg32 == LB_GETTEXT)? LB_GETTEXT16 : CB_GETLBTEXT16;
2458 *plparam = (LPARAM)MapLS(str);
2463 wch = LOWORD(wParam32);
2464 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2466 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
2469 wch = LOWORD(wParam32);
2470 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2472 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
2477 case WM_SYSDEADCHAR:
2479 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2483 default: /* No Unicode translation needed (?) */
2484 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2485 pwparam16, plparam );
2490 /**********************************************************************
2491 * WINPROC_UnmapMsg32WTo16
2493 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2495 void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2502 case LB_FINDSTRINGEXACT:
2503 case LB_INSERTSTRING:
2504 case LB_SELECTSTRING:
2509 case CB_FINDSTRINGEXACT:
2510 case CB_INSERTSTRING:
2511 case CB_SELECTSTRING:
2514 case WM_WININICHANGE:
2515 case WM_DEVMODECHANGE:
2516 unmap_str_32W_to_16( p16->lParam );
2521 CREATESTRUCT16 *cs = MapSL(p16->lParam);
2522 UnMapLS( p16->lParam );
2523 unmap_str_32W_to_16( cs->lpszName );
2524 unmap_str_32W_to_16( cs->lpszClass );
2525 HeapFree( GetProcessHeap(), 0, cs );
2530 MDICREATESTRUCT16 *cs = MapSL(p16->lParam);
2531 UnMapLS( p16->lParam );
2532 unmap_str_32W_to_16( cs->szTitle );
2533 unmap_str_32W_to_16( cs->szClass );
2534 HeapFree( GetProcessHeap(), 0, cs );
2538 case WM_ASKCBFORMATNAME:
2540 LPSTR str = MapSL(p16->lParam);
2541 UnMapLS( p16->lParam );
2542 p16->lParam = *((LPARAM *)str - 1);
2543 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)p16->lParam, 0x7fffffff );
2544 HeapFree( GetProcessHeap(), 0, (LPARAM *)str - 1 );
2549 if ( WINPROC_TestLBForStr( hwnd ))
2551 LPSTR str = MapSL(p16->lParam);
2552 UnMapLS( p16->lParam );
2553 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)lParam, 0x7fffffff );
2554 HeapFree( GetProcessHeap(), 0, (LPARAM *)str );
2558 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2564 /**********************************************************************
2565 * WINPROC_CallProc32ATo32W
2567 * Call a window procedure, translating args from Ansi to Unicode.
2569 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
2570 UINT msg, WPARAM wParam,
2576 TRACE_(msg)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2577 func, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
2579 if( (unmap = WINPROC_MapMsg32ATo32W( hwnd, msg, &wParam, &lParam )) == -1) {
2580 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2581 SPY_GetMsgName(msg, hwnd), wParam, lParam );
2584 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2585 if (unmap) result = WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
2590 /**********************************************************************
2591 * WINPROC_CallProc32WTo32A
2593 * Call a window procedure, translating args from Unicode to Ansi.
2595 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
2596 UINT msg, WPARAM wParam,
2602 TRACE_(msg)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2603 func, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
2605 if ((unmap = WINPROC_MapMsg32WTo32A( hwnd, msg, &wParam, &lParam )) == -1) {
2606 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2607 SPY_GetMsgName(msg, hwnd), wParam, lParam );
2610 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2611 if( unmap ) WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
2616 /**********************************************************************
2617 * __wine_call_wndproc_32A (USER.1010)
2619 LRESULT WINAPI __wine_call_wndproc_32A( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam,
2625 HWND hwnd32 = WIN_Handle32( hwnd );
2627 if (WINPROC_MapMsg16To32A( hwnd32, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2629 result = WINPROC_CallWndProc( func, hwnd32, msg32, wParam32, lParam );
2630 return WINPROC_UnmapMsg16To32A( hwnd32, msg32, wParam32, lParam, result );
2634 /**********************************************************************
2635 * __wine_call_wndproc_32W (USER.1011)
2637 LRESULT WINAPI __wine_call_wndproc_32W( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam,
2643 HWND hwnd32 = WIN_Handle32( hwnd );
2645 if (WINPROC_MapMsg16To32W( hwnd32, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2647 result = WINPROC_CallWndProc( func, hwnd32, msg32, wParam32, lParam );
2648 return WINPROC_UnmapMsg16To32W( hwnd32, msg32, wParam32, lParam, result );
2652 /**********************************************************************
2653 * WINPROC_CallProc32ATo16
2655 * Call a 16-bit window procedure, translating the 32-bit args.
2657 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
2658 UINT msg, WPARAM wParam,
2664 TRACE_(msg)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2665 func, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
2667 mp16.lParam = lParam;
2668 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1)
2670 mp16.lResult = WINPROC_CallWndProc16( func, HWND_16(hwnd), msg16,
2671 mp16.wParam, mp16.lParam );
2672 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
2673 return mp16.lResult;
2677 /**********************************************************************
2678 * WINPROC_CallProc32WTo16
2680 * Call a 16-bit window procedure, translating the 32-bit args.
2682 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
2683 UINT msg, WPARAM wParam,
2689 TRACE_(msg)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2690 func, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
2692 mp16.lParam = lParam;
2693 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
2694 &mp16.lParam ) == -1)
2696 mp16.lResult = WINPROC_CallWndProc16( func, HWND_16(hwnd), msg16,
2697 mp16.wParam, mp16.lParam );
2698 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
2699 return mp16.lResult;
2703 /**********************************************************************
2704 * CallWindowProc (USER.122)
2706 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
2707 WPARAM16 wParam, LPARAM lParam )
2711 if (!func) return 0;
2713 if (!(proc = WINPROC_GetPtr( func )))
2714 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2717 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
2718 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2724 if (!proc->thunk.t_from32.proc) return 0;
2725 return WINPROC_CallWndProc16( proc->thunk.t_from32.proc,
2726 hwnd, msg, wParam, lParam );
2728 if (!proc->thunk.t_from16.proc) return 0;
2729 return __wine_call_wndproc_32A( hwnd, msg, wParam, lParam, proc->thunk.t_from16.proc );
2731 if (!proc->thunk.t_from16.proc) return 0;
2732 return __wine_call_wndproc_32W( hwnd, msg, wParam, lParam, proc->thunk.t_from16.proc );
2734 WARN_(relay)("Invalid proc %p\n", proc );
2740 /**********************************************************************
2741 * CallWindowProcA (USER32.@)
2743 * The CallWindowProc() function invokes the windows procedure _func_,
2744 * with _hwnd_ as the target window, the message specified by _msg_, and
2745 * the message parameters _wParam_ and _lParam_.
2747 * Some kinds of argument conversion may be done, I'm not sure what.
2749 * CallWindowProc() may be used for windows subclassing. Use
2750 * SetWindowLong() to set a new windows procedure for windows of the
2751 * subclass, and handle subclassed messages in the new windows
2752 * procedure. The new windows procedure may then use CallWindowProc()
2753 * with _func_ set to the parent class's windows procedure to dispatch
2754 * the message to the superclass.
2758 * The return value is message dependent.
2764 LRESULT WINAPI CallWindowProcA(
2765 WNDPROC func, /* [in] window procedure */
2766 HWND hwnd, /* [in] target window */
2767 UINT msg, /* [in] message */
2768 WPARAM wParam, /* [in] message dependent parameter */
2769 LPARAM lParam /* [in] message dependent parameter */
2771 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2773 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2776 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2777 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2783 if (!proc->thunk.t_from32.proc) return 0;
2784 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2785 hwnd, msg, wParam, lParam );
2787 if (!proc->thunk.t_from16.proc) return 0;
2788 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2789 hwnd, msg, wParam, lParam );
2791 if (!proc->thunk.t_from16.proc) return 0;
2792 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2793 hwnd, msg, wParam, lParam );
2795 WARN_(relay)("Invalid proc %p\n", proc );
2801 /**********************************************************************
2802 * CallWindowProcW (USER32.@)
2804 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
2805 WPARAM wParam, LPARAM lParam )
2807 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2809 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2812 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2813 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2819 if (!proc->thunk.t_from32.proc) return 0;
2820 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2821 hwnd, msg, wParam, lParam );
2823 if (!proc->thunk.t_from16.proc) return 0;
2824 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2825 hwnd, msg, wParam, lParam );
2827 if (!proc->thunk.t_from16.proc) return 0;
2828 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2829 hwnd, msg, wParam, lParam );
2831 WARN_(relay)("Invalid proc %p\n", proc );