2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
9 #include "wine/winbase16.h"
10 #include "wine/winuser16.h"
12 #include "stackframe.h"
13 #include "builtin16.h"
15 #include "selectors.h"
19 #include "debugtools.h"
26 DECLARE_DEBUG_CHANNEL(msg)
27 DECLARE_DEBUG_CHANNEL(relay)
28 DECLARE_DEBUG_CHANNEL(win)
30 /* Window procedure 16-to-32-bit thunk,
31 * see BuildSpec16Files() in tools/build.c */
36 WORD pushw_bp; /* pushw %bp */
37 BYTE pushl_func; /* pushl $proc */
39 WORD pushw_ax; /* pushw %ax */
40 BYTE pushl_relay; /* pushl $relay */
41 void (*relay)(); /* WINPROC_Thunk16To32A/W() */
42 BYTE lcall; /* lcall cs:glue */
43 void (*glue)(); /* CallFrom16Long */
44 WORD cs; /* __FLATCS */
45 WORD lret; /* lret $10 */
47 } WINPROC_THUNK_FROM16;
50 /* Window procedure 32-to-16-bit thunk,
51 * see BuildSpec32Files() in tools/build.c */
55 BYTE popl_eax; /* popl %eax (return address) */
56 BYTE pushl_func; /* pushl $proc */
57 WNDPROC16 proc WINE_PACKED;
58 BYTE pushl_eax; /* pushl %eax */
59 BYTE jmp; /* jmp relay (relative jump)*/
60 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
61 } WINPROC_THUNK_FROM32;
63 /* Simple jmp to call 32-bit procedure directly */
66 BYTE jmp; /* jmp proc (relative jump) */
67 WNDPROC proc WINE_PACKED;
72 WINPROC_THUNK_FROM16 t_from16;
73 WINPROC_THUNK_FROM32 t_from32;
76 typedef struct tagWINDOWPROC
78 WINPROC_THUNK thunk; /* Thunk */
79 WINPROC_JUMP jmp; /* Jump */
80 struct tagWINDOWPROC *next; /* Next window proc */
81 UINT magic; /* Magic number */
82 WINDOWPROCTYPE type; /* Function type */
83 WINDOWPROCUSER user; /* Function user */
86 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
88 #define WINPROC_THUNKPROC(pproc) \
89 (((pproc)->type == WIN_PROC_16) ? \
90 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
91 (WNDPROC16)((pproc)->thunk.t_from16.proc))
93 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
94 UINT msg, WPARAM wParam,
96 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
97 UINT msg, WPARAM wParam,
99 static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args );
100 static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args );
102 static HANDLE WinProcHeap;
105 /**********************************************************************
108 BOOL WINPROC_Init(void)
110 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
113 WARN_(relay)("Unable to create winproc heap\n" );
120 /**********************************************************************
121 * WINPROC_CallWndProc32
123 * Call a 32-bit WndProc.
125 static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
126 WPARAM wParam, LPARAM lParam )
131 TRACE_(relay)("(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
132 proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
133 /* To avoid any deadlocks, all the locks on the windows structures
134 must be suspended before the control is passed to the application */
135 iWndsLocks = WIN_SuspendWndsLock();
136 retvalue = proc( hwnd, msg, wParam, lParam );
137 WIN_RestoreWndsLock(iWndsLocks);
141 /***********************************************************************
142 * WINPROC_CallWndProc16
144 * Call a 16-bit window procedure
146 static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
147 UINT16 msg, WPARAM16 wParam,
153 WND *wndPtr = WIN_FindWndPtr( hwnd );
155 TEB *teb = NtCurrentTeb();
158 /* Window procedures want ax = hInstance, ds = es = ss */
160 memset(&context, '\0', sizeof(context));
161 DS_reg(&context) = SELECTOROF(teb->cur_stack);
162 ES_reg(&context) = DS_reg(&context);
163 EAX_reg(&context) = wndPtr ? wndPtr->hInstance : DS_reg(&context);
164 CS_reg(&context) = SELECTOROF(proc);
165 EIP_reg(&context) = OFFSETOF(proc);
166 EBP_reg(&context) = OFFSETOF(teb->cur_stack)
167 + (WORD)&((STACK16FRAME*)0)->bp;
169 WIN_ReleaseWndPtr(wndPtr);
173 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
174 work if structures passed in lParam are placed in the stack/data
175 segment. Programmers easily make the mistake of converting lParam
176 to a near rather than a far pointer, since Windows apparently
177 allows this. We copy the structures to the 16 bit stack; this is
178 ugly but makes these programs work. */
183 offset = sizeof(CREATESTRUCT16); break;
185 offset = sizeof(DRAWITEMSTRUCT16); break;
187 offset = sizeof(COMPAREITEMSTRUCT16); break;
191 void *s = PTR_SEG_TO_LIN(lParam);
192 lParam = stack16_push( offset );
193 memcpy( PTR_SEG_TO_LIN(lParam), s, offset );
197 iWndsLocks = WIN_SuspendWndsLock();
199 args = (WORD *)THREAD_STACK16(teb) - 5;
200 args[0] = LOWORD(lParam);
201 args[1] = HIWORD(lParam);
206 ret = CallTo16RegisterShort( &context, 5 * sizeof(WORD) );
207 if (offset) stack16_pop( offset );
209 WIN_RestoreWndsLock(iWndsLocks);
215 /**********************************************************************
218 * Return a pointer to the win proc.
220 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
225 /* Check for a linear pointer */
227 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
229 ptr = (BYTE *)handle;
230 /* First check if it is the jmp address */
231 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
232 (int)&((WINDOWPROC *)0)->thunk;
233 /* Now it must be the thunk address */
234 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
235 /* Now we have a pointer to the WINDOWPROC struct */
236 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
237 return (WINDOWPROC *)ptr;
240 /* Check for a segmented pointer */
242 if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
244 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
245 if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
246 /* It must be the thunk address */
247 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
248 /* Now we have a pointer to the WINDOWPROC struct */
249 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
250 return (WINDOWPROC *)ptr;
257 /**********************************************************************
258 * WINPROC_AllocWinProc
260 * Allocate a new window procedure.
262 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
263 WINDOWPROCUSER user )
265 WINDOWPROC *proc, *oldproc;
267 /* Allocate a window procedure */
269 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
271 /* Check if the function is already a win proc */
273 if ((oldproc = WINPROC_GetPtr( func )))
282 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
283 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
284 proc->thunk.t_from32.proc = func;
285 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
286 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
287 proc->thunk.t_from32.relay = /* relative jump */
288 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
289 (DWORD)(&proc->thunk.t_from32.relay + 1));
293 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
294 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
295 proc->thunk.t_from16.proc = (FARPROC)func;
296 proc->thunk.t_from16.pushw_ax = 0x5066; /* pushw %ax */
297 proc->thunk.t_from16.pushl_relay = 0x68; /* pushl $relay */
298 proc->thunk.t_from16.relay = (type == WIN_PROC_32A) ?
299 (void(*)())WINPROC_Thunk16To32A :
300 (void(*)())WINPROC_Thunk16To32W;
301 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:glue */
302 proc->thunk.t_from16.glue = (void*)CallFrom16Long;
303 GET_CS(proc->thunk.t_from16.cs);
304 proc->thunk.t_from16.lret = 0xca66;
305 proc->thunk.t_from16.nArgs = 10;
306 proc->jmp.jmp = 0xe9;
307 /* Fixup relative jump */
308 proc->jmp.proc = (WNDPROC)((DWORD)func -
309 (DWORD)(&proc->jmp.proc + 1));
312 /* Should not happen */
315 proc->magic = WINPROC_MAGIC;
320 TRACE_(win)("(%08x,%d): returning %08x\n",
321 (UINT)func, type, (UINT)proc );
326 /**********************************************************************
329 * Get a window procedure pointer that can be passed to the Windows program.
331 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
333 if (!proc) return NULL;
334 if (type == WIN_PROC_16) /* We want a 16:16 address */
336 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
337 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
339 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
340 &((WINDOWPROC *)proc)->thunk );
342 else /* We want a 32-bit address */
344 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
345 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
346 else if (type != ((WINDOWPROC *)proc)->type)
347 /* Have to return the jmp address if types don't match */
348 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
350 /* Some Win16 programs want to get back the proc they set */
351 return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc;
356 /**********************************************************************
359 * Set the window procedure for a window or class. There are
360 * three tree classes of winproc callbacks:
362 * 1) class -> wp - not subclassed
363 * class -> wp -> wp -> wp -> wp - SetClassLong()
365 * 2) window -' / - not subclassed
366 * window -> wp -> wp ' - SetWindowLong()
368 * 3) timer -> wp - SetTimer()
370 * Initially, winproc of the window points to the current winproc
371 * thunk of its class. Subclassing prepends a new thunk to the
372 * window winproc chain at the head of the list. Thus, window thunk
373 * list includes class thunks and the latter are preserved when the
374 * window is destroyed.
377 BOOL WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
378 WINDOWPROCTYPE type, WINDOWPROCUSER user )
380 BOOL bRecycle = FALSE;
381 WINDOWPROC *proc, **ppPrev;
383 /* Check if function is already in the list */
385 ppPrev = (WINDOWPROC **)pFirst;
386 proc = WINPROC_GetPtr( func );
393 if ((*ppPrev)->user != user)
395 /* terminal thunk is being restored */
397 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
398 *(WINDOWPROC **)pFirst = *ppPrev;
407 if (((*ppPrev)->type == type) &&
408 (func == WINPROC_THUNKPROC(*ppPrev)))
415 /* WPF_CLASS thunk terminates window thunk list */
416 if ((*ppPrev)->user != user) break;
417 ppPrev = &(*ppPrev)->next;
422 /* Extract this thunk from the list */
424 *ppPrev = proc->next;
426 else /* Allocate a new one */
428 if (proc) /* Was already a win proc */
431 func = WINPROC_THUNKPROC(proc);
433 proc = WINPROC_AllocWinProc( func, type, user );
434 if (!proc) return FALSE;
437 /* Add the win proc at the head of the list */
439 TRACE_(win)("(%08x,%08x,%d): res=%08x\n",
440 (UINT)*pFirst, (UINT)func, type, (UINT)proc );
441 proc->next = *(WINDOWPROC **)pFirst;
442 *(WINDOWPROC **)pFirst = proc;
447 /**********************************************************************
450 * Free a list of win procs.
452 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
456 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
457 if (((WINDOWPROC *)proc)->user != user) break;
458 TRACE_(win)("freeing %08x\n", (UINT)proc);
459 HeapFree( WinProcHeap, 0, proc );
465 /**********************************************************************
466 * WINPROC_GetProcType
468 * Return the window procedure type.
470 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
473 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
474 return WIN_PROC_INVALID;
475 return ((WINDOWPROC *)proc)->type;
477 /**********************************************************************
478 * WINPROC_TestCBForStr
480 * Return TRUE if the lparam is a string
482 static BOOL WINPROC_TestCBForStr ( HWND hwnd )
485 WND * wnd = WIN_FindWndPtr(hwnd);
486 retvalue = ( !(LOWORD(wnd->dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
487 (LOWORD(wnd->dwStyle) & CBS_HASSTRINGS) );
488 WIN_ReleaseWndPtr(wnd);
491 /**********************************************************************
492 * WINPROC_TestLBForStr
494 * Return TRUE if the lparam is a string
496 static BOOL WINPROC_TestLBForStr ( HWND hwnd )
499 WND * wnd = WIN_FindWndPtr(hwnd);
500 retvalue = ( !(LOWORD(wnd->dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) ||
501 (LOWORD(wnd->dwStyle) & LBS_HASSTRINGS) );
502 WIN_ReleaseWndPtr(wnd);
506 /**********************************************************************
507 * WINPROC_MapMsg32ATo32W
509 * Map a message from Ansi to Unicode.
510 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
513 * WM_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR, WM_SYSDEADCHAR
516 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
517 * the first four bytes are the handle of the icon
518 * when the WM_SETTEXT message has been used to set the icon
520 INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
526 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
527 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
529 *ptr++ = *plparam; /* Store previous lParam */
530 *plparam = (LPARAM)ptr;
533 /* lparam is string (0-terminated) */
535 case WM_WININICHANGE:
538 case CB_FINDSTRINGEXACT:
539 case CB_SELECTSTRING:
543 case LB_SELECTSTRING:
545 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
546 return (*plparam ? 1 : -1);
552 { CREATESTRUCTW cs; /* new structure */
553 LPCWSTR lpszName; /* allocated Name */
554 LPCWSTR lpszClass; /* allocated Class */
557 struct s *xs = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, sizeof(struct s));
559 xs->cs = *(CREATESTRUCTW *)*plparam;
560 if (HIWORD(xs->cs.lpszName))
561 xs->lpszName = xs->cs.lpszName = HEAP_strdupAtoW( SystemHeap, 0,
562 (LPCSTR)xs->cs.lpszName );
563 if (HIWORD(xs->cs.lpszClass))
564 xs->lpszClass = xs->cs.lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
565 (LPCSTR)xs->cs.lpszClass );
566 *plparam = (LPARAM)xs;
571 MDICREATESTRUCTW *cs =
572 (MDICREATESTRUCTW *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
574 *cs = *(MDICREATESTRUCTW *)*plparam;
575 if (HIWORD(cs->szClass))
576 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
577 (LPCSTR)cs->szClass );
578 if (HIWORD(cs->szTitle))
579 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
580 (LPCSTR)cs->szTitle );
581 *plparam = (LPARAM)cs;
587 case LB_INSERTSTRING:
588 if ( WINPROC_TestLBForStr( hwnd ))
589 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
590 return (*plparam ? 1 : -1);
592 case LB_GETTEXT: /* fixme: fixed sized buffer */
593 { if ( WINPROC_TestLBForStr( hwnd ))
594 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
596 *ptr++ = *plparam; /* Store previous lParam */
597 *plparam = (LPARAM)ptr;
604 case CB_INSERTSTRING:
605 if ( WINPROC_TestCBForStr( hwnd ))
606 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
607 return (*plparam ? 1 : -1);
609 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
610 { if ( WINPROC_TestCBForStr( hwnd ))
611 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
613 *ptr++ = *plparam; /* Store previous lParam */
614 *plparam = (LPARAM)ptr;
621 { WORD len = (WORD)*plparam;
622 LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
624 *ptr++ = *plparam; /* Store previous lParam */
625 *((WORD *) ptr) = len; /* Store the length */
626 *plparam = (LPARAM)ptr;
630 case WM_ASKCBFORMATNAME:
631 case WM_DEVMODECHANGE:
632 case WM_PAINTCLIPBOARD:
633 case WM_SIZECLIPBOARD:
634 case EM_SETPASSWORDCHAR:
635 FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg), msg );
637 default: /* No translation needed */
643 /**********************************************************************
644 * WINPROC_UnmapMsg32ATo32W
646 * Unmap a message that was mapped from Ansi to Unicode.
648 void WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
654 LPARAM *ptr = (LPARAM *)lParam - 1;
655 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)lParam, wParam );
656 HeapFree( SystemHeap, 0, ptr );
664 { CREATESTRUCTW cs; /* new structure */
665 LPWSTR lpszName; /* allocated Name */
666 LPWSTR lpszClass; /* allocated Class */
668 struct s *xs = (struct s *)lParam;
669 if (xs->lpszName) HeapFree( SystemHeap, 0, xs->lpszName );
670 if (xs->lpszClass) HeapFree( SystemHeap, 0, xs->lpszClass );
671 HeapFree( SystemHeap, 0, xs );
677 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
678 if (HIWORD(cs->szTitle))
679 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
680 if (HIWORD(cs->szClass))
681 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
682 HeapFree( SystemHeap, 0, cs );
687 case WM_WININICHANGE:
690 case CB_FINDSTRINGEXACT:
691 case CB_SELECTSTRING:
695 case LB_SELECTSTRING:
697 HeapFree( SystemHeap, 0, (void *)lParam );
702 case LB_INSERTSTRING:
703 if ( WINPROC_TestLBForStr( hwnd ))
704 HeapFree( SystemHeap, 0, (void *)lParam );
708 { if ( WINPROC_TestLBForStr( hwnd ))
709 { LPARAM *ptr = (LPARAM *)lParam - 1;
710 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
711 HeapFree( SystemHeap, 0, ptr );
718 case CB_INSERTSTRING:
719 if ( WINPROC_TestCBForStr( hwnd ))
720 HeapFree( SystemHeap, 0, (void *)lParam );
724 { if ( WINPROC_TestCBForStr( hwnd ))
725 { LPARAM *ptr = (LPARAM *)lParam - 1;
726 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
727 HeapFree( SystemHeap, 0, ptr );
734 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
735 WORD len = *(WORD *) lParam;
736 lstrcpynWtoA( (LPSTR)*ptr , (LPWSTR)lParam, len );
737 HeapFree( SystemHeap, 0, ptr );
744 /**********************************************************************
745 * WINPROC_MapMsg32WTo32A
747 * Map a message from Unicode to Ansi.
748 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
750 INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
755 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
756 wParam + sizeof(LPARAM) );
758 *ptr++ = *plparam; /* Store previous lParam */
759 *plparam = (LPARAM)ptr;
764 case WM_WININICHANGE:
767 case CB_FINDSTRINGEXACT:
768 case CB_SELECTSTRING:
772 case LB_SELECTSTRING:
774 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
775 return (*plparam ? 1 : -1);
780 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
783 *cs = *(CREATESTRUCTA *)*plparam;
784 if (HIWORD(cs->lpszName))
785 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
786 (LPCWSTR)cs->lpszName );
787 if (HIWORD(cs->lpszClass))
788 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
789 (LPCWSTR)cs->lpszClass);
790 *plparam = (LPARAM)cs;
795 MDICREATESTRUCTA *cs =
796 (MDICREATESTRUCTA *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
798 *cs = *(MDICREATESTRUCTA *)*plparam;
799 if (HIWORD(cs->szTitle))
800 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
801 (LPCWSTR)cs->szTitle );
802 if (HIWORD(cs->szClass))
803 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
804 (LPCWSTR)cs->szClass );
805 *plparam = (LPARAM)cs;
811 case LB_INSERTSTRING:
812 if ( WINPROC_TestLBForStr( hwnd ))
813 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
814 return (*plparam ? 1 : -1);
816 case LB_GETTEXT: /* fixme: fixed sized buffer */
817 { if ( WINPROC_TestLBForStr( hwnd ))
818 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
820 *ptr++ = *plparam; /* Store previous lParam */
821 *plparam = (LPARAM)ptr;
828 case CB_INSERTSTRING:
829 if ( WINPROC_TestCBForStr( hwnd ))
830 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
831 return (*plparam ? 1 : -1);
833 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
834 { if ( WINPROC_TestCBForStr( hwnd ))
835 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
837 *ptr++ = *plparam; /* Store previous lParam */
838 *plparam = (LPARAM)ptr;
845 { WORD len = (WORD)*plparam;
846 LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
848 *ptr++ = *plparam; /* Store previous lParam */
849 *((WORD *) ptr) = len; /* Store the length */
850 *plparam = (LPARAM)ptr;
854 case WM_ASKCBFORMATNAME:
855 case WM_DEVMODECHANGE:
856 case WM_PAINTCLIPBOARD:
857 case WM_SIZECLIPBOARD:
858 case EM_SETPASSWORDCHAR:
859 FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg),msg );
861 default: /* No translation needed */
867 /**********************************************************************
868 * WINPROC_UnmapMsg32WTo32A
870 * Unmap a message that was mapped from Unicode to Ansi.
872 void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
878 LPARAM *ptr = (LPARAM *)lParam - 1;
879 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)lParam, wParam );
880 HeapFree( SystemHeap, 0, ptr );
885 case WM_WININICHANGE:
888 case CB_FINDSTRINGEXACT:
889 case CB_SELECTSTRING:
893 case LB_SELECTSTRING:
895 HeapFree( SystemHeap, 0, (void *)lParam );
901 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
902 if (HIWORD(cs->lpszName))
903 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
904 if (HIWORD(cs->lpszClass))
905 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
906 HeapFree( SystemHeap, 0, cs );
912 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
913 if (HIWORD(cs->szTitle))
914 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
915 if (HIWORD(cs->szClass))
916 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
917 HeapFree( SystemHeap, 0, cs );
923 case LB_INSERTSTRING:
924 if ( WINPROC_TestLBForStr( hwnd ))
925 HeapFree( SystemHeap, 0, (void *)lParam );
929 { if ( WINPROC_TestLBForStr( hwnd ))
930 { LPARAM *ptr = (LPARAM *)lParam - 1;
931 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
932 HeapFree( SystemHeap, 0, ptr );
939 case CB_INSERTSTRING:
940 if ( WINPROC_TestCBForStr( hwnd ))
941 HeapFree( SystemHeap, 0, (void *)lParam );
945 { if ( WINPROC_TestCBForStr( hwnd ))
946 { LPARAM *ptr = (LPARAM *)lParam - 1;
947 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
948 HeapFree( SystemHeap, 0, ptr );
955 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lparam */
956 WORD len = *(WORD *)ptr;
957 lstrcpynAtoW( (LPWSTR) *ptr, (LPSTR)lParam, len );
958 HeapFree( SystemHeap, 0, ptr );
965 /**********************************************************************
966 * WINPROC_MapMsg16To32A
968 * Map a message from 16- to 32-bit Ansi.
969 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
971 INT WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
972 WPARAM *pwparam32, LPARAM *plparam )
974 *pmsg32 = (UINT)msg16;
975 *pwparam32 = (WPARAM)wParam16;
982 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
983 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
987 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
988 *plparam = (LPARAM)(HWND)HIWORD(*plparam);
991 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
992 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
993 *pwparam32 = (WPARAM)(HDC)wParam16;
994 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
998 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
999 COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)
1000 HeapAlloc(SystemHeap, 0, sizeof(*cis));
1001 if (!cis) return -1;
1002 cis->CtlType = cis16->CtlType;
1003 cis->CtlID = cis16->CtlID;
1004 cis->hwndItem = cis16->hwndItem;
1005 cis->itemID1 = cis16->itemID1;
1006 cis->itemData1 = cis16->itemData1;
1007 cis->itemID2 = cis16->itemID2;
1008 cis->itemData2 = cis16->itemData2;
1009 cis->dwLocaleId = 0; /* FIXME */
1010 *plparam = (LPARAM)cis;
1015 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1016 DELETEITEMSTRUCT *dis = (DELETEITEMSTRUCT *)
1017 HeapAlloc(SystemHeap, 0, sizeof(*dis));
1018 if (!dis) return -1;
1019 dis->CtlType = dis16->CtlType;
1020 dis->CtlID = dis16->CtlID;
1021 dis->hwndItem = dis16->hwndItem;
1022 dis->itemData = dis16->itemData;
1023 *plparam = (LPARAM)dis;
1026 case WM_MEASUREITEM:
1028 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1029 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)
1030 HeapAlloc(SystemHeap, 0,
1031 sizeof(*mis) + sizeof(LPARAM));
1032 if (!mis) return -1;
1033 mis->CtlType = mis16->CtlType;
1034 mis->CtlID = mis16->CtlID;
1035 mis->itemID = mis16->itemID;
1036 mis->itemWidth = mis16->itemWidth;
1037 mis->itemHeight = mis16->itemHeight;
1038 mis->itemData = mis16->itemData;
1039 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1040 *plparam = (LPARAM)mis;
1045 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1046 DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)HeapAlloc(SystemHeap, 0,
1048 if (!dis) return -1;
1049 dis->CtlType = dis16->CtlType;
1050 dis->CtlID = dis16->CtlID;
1051 dis->itemID = dis16->itemID;
1052 dis->itemAction = dis16->itemAction;
1053 dis->itemState = dis16->itemState;
1054 dis->hwndItem = dis16->hwndItem;
1055 dis->hDC = dis16->hDC;
1056 dis->itemData = dis16->itemData;
1057 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
1058 *plparam = (LPARAM)dis;
1061 case WM_GETMINMAXINFO:
1063 MINMAXINFO *mmi = (MINMAXINFO *)HeapAlloc( SystemHeap, 0,
1064 sizeof(*mmi) + sizeof(LPARAM));
1065 if (!mmi) return -1;
1066 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
1068 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1069 *plparam = (LPARAM)mmi;
1074 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1078 MDICREATESTRUCT16 *cs16 =
1079 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1080 MDICREATESTRUCTA *cs =
1081 (MDICREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
1082 sizeof(*cs) + sizeof(LPARAM) );
1084 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
1085 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1086 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
1087 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1088 *plparam = (LPARAM)cs;
1091 case WM_MDIGETACTIVE:
1092 *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL) );
1093 *(BOOL*)(*plparam) = 0;
1097 *pmsg32=WM_MDIREFRESHMENU;
1098 *pwparam32 = (WPARAM)(HMENU)LOWORD(*plparam);
1099 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1102 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1103 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1106 if((LOWORD(*plparam) & MF_POPUP) && (LOWORD(*plparam) != 0xFFFF))
1108 HMENU hmenu=(HMENU)HIWORD(*plparam);
1109 UINT Pos=MENU_FindSubMenu( &hmenu, wParam16);
1110 if(Pos==0xFFFF) Pos=0; /* NO_SELECTED_ITEM */
1111 *pwparam32 = MAKEWPARAM( Pos, LOWORD(*plparam) );
1113 else *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1114 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1116 case WM_MDIACTIVATE:
1119 *pwparam32 = (WPARAM)(HWND)HIWORD(*plparam);
1120 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1122 else /* message sent to MDI client */
1123 *pwparam32 = wParam16;
1127 NCCALCSIZE_PARAMS16 *nc16;
1128 NCCALCSIZE_PARAMS *nc;
1130 nc = (NCCALCSIZE_PARAMS *)HeapAlloc( SystemHeap, 0,
1131 sizeof(*nc) + sizeof(LPARAM) );
1133 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
1134 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
1137 nc->lppos = (WINDOWPOS *)HeapAlloc( SystemHeap, 0,
1138 sizeof(*nc->lppos) );
1139 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
1140 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
1141 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
1143 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1144 *plparam = (LPARAM)nc;
1150 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1151 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
1152 sizeof(*cs) + sizeof(LPARAM) );
1154 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
1155 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1156 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1157 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1158 *plparam = (LPARAM)cs;
1161 case WM_PARENTNOTIFY:
1162 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1164 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1165 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1168 case WM_WINDOWPOSCHANGING:
1169 case WM_WINDOWPOSCHANGED:
1171 WINDOWPOS *wp = (WINDOWPOS *)HeapAlloc( SystemHeap, 0,
1172 sizeof(*wp) + sizeof(LPARAM) );
1174 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
1176 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1177 *plparam = (LPARAM)wp;
1183 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1184 LPMSG msg32 = (LPMSG)HeapAlloc( SystemHeap, 0, sizeof(MSG) );
1186 if (!msg32) return -1;
1187 msg32->hwnd = msg16->hwnd;
1188 msg32->lParam = msg16->lParam;
1189 msg32->time = msg16->time;
1190 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1191 /* this is right, right? */
1192 if (WINPROC_MapMsg16To32A(msg16->message,msg16->wParam,
1193 &msg32->message,&msg32->wParam,
1194 &msg32->lParam)<0) {
1195 HeapFree( SystemHeap, 0, msg32 );
1198 *plparam = (LPARAM)msg32;
1203 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1205 case WM_ACTIVATEAPP:
1207 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1208 a 32bit window. Might be superflous with 32bit interprocess
1211 HTASK16 htask = (HTASK16) *plparam;
1212 DWORD idThread = (DWORD)((TDB*)GlobalLock16(htask))->teb->tid;
1213 *plparam = (LPARAM) idThread;
1216 case WM_ASKCBFORMATNAME:
1217 case WM_DEVMODECHANGE:
1218 case WM_PAINTCLIPBOARD:
1219 case WM_SIZECLIPBOARD:
1220 case WM_WININICHANGE:
1221 FIXME_(msg)("message %04x needs translation\n",msg16 );
1224 default: /* No translation needed */
1230 /**********************************************************************
1231 * WINPROC_UnmapMsg16To32A
1233 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1235 LRESULT WINPROC_UnmapMsg16To32A( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1240 case WM_COMPAREITEM:
1243 HeapFree( SystemHeap, 0, (LPVOID)lParam );
1245 case WM_MEASUREITEM:
1247 MEASUREITEMSTRUCT16 *mis16;
1248 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1249 lParam = *(LPARAM *)(mis + 1);
1250 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
1251 mis16->itemWidth = (UINT16)mis->itemWidth;
1252 mis16->itemHeight = (UINT16)mis->itemHeight;
1253 HeapFree( SystemHeap, 0, mis );
1256 case WM_GETMINMAXINFO:
1258 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1259 lParam = *(LPARAM *)(mmi + 1);
1260 STRUCT32_MINMAXINFO32to16( mmi,
1261 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
1262 HeapFree( SystemHeap, 0, mmi );
1267 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1268 lParam = *(LPARAM *)(cs + 1);
1269 STRUCT32_MDICREATESTRUCT32Ato16( cs,
1270 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1271 HeapFree( SystemHeap, 0, cs );
1274 case WM_MDIGETACTIVE:
1275 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1276 HeapFree( SystemHeap, 0, (BOOL *)lParam );
1280 NCCALCSIZE_PARAMS16 *nc16;
1281 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1282 lParam = *(LPARAM *)(nc + 1);
1283 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
1284 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
1287 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
1288 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
1291 STRUCT32_WINDOWPOS32to16( nc->lppos,
1292 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
1293 HeapFree( SystemHeap, 0, nc->lppos );
1296 HeapFree( SystemHeap, 0, nc );
1302 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1303 lParam = *(LPARAM *)(cs + 1);
1304 STRUCT32_CREATESTRUCT32Ato16( cs,
1305 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1306 HeapFree( SystemHeap, 0, cs );
1309 case WM_WINDOWPOSCHANGING:
1310 case WM_WINDOWPOSCHANGED:
1312 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1313 lParam = *(LPARAM *)(wp + 1);
1314 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
1315 HeapFree( SystemHeap, 0, wp );
1321 LPMSG msg32 = (LPMSG)lParam;
1323 WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1325 HeapFree( SystemHeap, 0, msg32 );
1333 /**********************************************************************
1334 * WINPROC_MapMsg16To32W
1336 * Map a message from 16- to 32-bit Unicode.
1337 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1339 INT WINPROC_MapMsg16To32W( HWND16 hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1340 WPARAM *pwparam32, LPARAM *plparam )
1346 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1347 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, *pwparam32, plparam );
1351 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1352 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
1353 sizeof(*cs) + sizeof(LPARAM) );
1355 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1356 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1357 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1358 if (HIWORD(cs->lpszName))
1359 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
1360 (LPCSTR)cs->lpszName );
1361 if (HIWORD(cs->lpszClass))
1362 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
1363 (LPCSTR)cs->lpszClass );
1364 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1365 *plparam = (LPARAM)cs;
1370 MDICREATESTRUCT16 *cs16 =
1371 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1372 MDICREATESTRUCTW *cs =
1373 (MDICREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
1374 sizeof(*cs) + sizeof(LPARAM) );
1376 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1377 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1378 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
1379 if (HIWORD(cs->szTitle))
1380 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
1381 (LPCSTR)cs->szTitle );
1382 if (HIWORD(cs->szClass))
1383 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
1384 (LPCSTR)cs->szClass );
1385 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1386 *plparam = (LPARAM)cs;
1392 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1393 LPMSG msg32 = (LPMSG)HeapAlloc( SystemHeap, 0, sizeof(MSG) );
1395 if (!msg32) return -1;
1396 msg32->hwnd = msg16->hwnd;
1397 msg32->lParam = msg16->lParam;
1398 msg32->time = msg16->time;
1399 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1400 /* this is right, right? */
1401 if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
1402 &msg32->message,&msg32->wParam,
1403 &msg32->lParam)<0) {
1404 HeapFree( SystemHeap, 0, msg32 );
1407 *plparam = (LPARAM)msg32;
1411 default: /* No Unicode translation needed */
1412 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1413 pwparam32, plparam );
1418 /**********************************************************************
1419 * WINPROC_UnmapMsg16To32W
1421 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1423 LRESULT WINPROC_UnmapMsg16To32W( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1430 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
1435 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1436 lParam = *(LPARAM *)(cs + 1);
1437 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs,
1438 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1439 if (HIWORD(cs->lpszName))
1440 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1441 if (HIWORD(cs->lpszClass))
1442 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1443 HeapFree( SystemHeap, 0, cs );
1448 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1449 lParam = *(LPARAM *)(cs + 1);
1450 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs,
1451 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1452 if (HIWORD(cs->szTitle))
1453 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1454 if (HIWORD(cs->szClass))
1455 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1456 HeapFree( SystemHeap, 0, cs );
1462 LPMSG msg32 = (LPMSG)lParam;
1464 WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1466 HeapFree( SystemHeap, 0, msg32 );
1470 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1476 /**********************************************************************
1477 * WINPROC_MapMsg32ATo16
1479 * Map a message from 32-bit Ansi to 16-bit.
1480 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1482 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1483 UINT16 *pmsg16, WPARAM16 *pwparam16,
1486 *pmsg16 = (UINT16)msg32;
1487 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1495 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1504 case EM_SCROLLCARET:
1507 case EM_GETLINECOUNT:
1519 case EM_LINEFROMCHAR:
1520 case EM_SETTABSTOPS:
1521 case EM_SETPASSWORDCHAR:
1522 case EM_EMPTYUNDOBUFFER:
1523 case EM_GETFIRSTVISIBLELINE:
1524 case EM_SETREADONLY:
1525 case EM_SETWORDBREAKPROC:
1526 case EM_GETWORDBREAKPROC:
1527 case EM_GETPASSWORDCHAR:
1528 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1533 case LB_DELETESTRING:
1534 case LB_GETANCHORINDEX:
1535 case LB_GETCARETINDEX:
1538 case LB_GETHORIZONTALEXTENT:
1539 case LB_GETITEMDATA:
1540 case LB_GETITEMHEIGHT:
1542 case LB_GETSELCOUNT:
1544 case LB_GETTOPINDEX:
1545 case LB_RESETCONTENT:
1546 case LB_SELITEMRANGE:
1547 case LB_SELITEMRANGEEX:
1548 case LB_SETANCHORINDEX:
1549 case LB_SETCARETINDEX:
1550 case LB_SETCOLUMNWIDTH:
1552 case LB_SETHORIZONTALEXTENT:
1553 case LB_SETITEMDATA:
1554 case LB_SETITEMHEIGHT:
1556 case LB_SETTOPINDEX:
1557 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1559 case CB_DELETESTRING:
1561 case CB_GETLBTEXTLEN:
1563 case CB_RESETCONTENT:
1567 case CB_SHOWDROPDOWN:
1568 case CB_SETITEMDATA:
1569 case CB_SETITEMHEIGHT:
1570 case CB_GETITEMHEIGHT:
1571 case CB_SETEXTENDEDUI:
1572 case CB_GETEXTENDEDUI:
1573 case CB_GETDROPPEDSTATE:
1574 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1577 *pmsg16 = CB_GETEDITSEL16;
1582 case LB_FINDSTRINGEXACT:
1583 case LB_INSERTSTRING:
1584 case LB_SELECTSTRING:
1588 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1589 if (!str) return -1;
1590 *plparam = (LPARAM)SEGPTR_GET(str);
1592 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1597 case CB_FINDSTRINGEXACT:
1598 case CB_INSERTSTRING:
1599 case CB_SELECTSTRING:
1602 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1603 if (!str) return -1;
1604 *plparam = (LPARAM)SEGPTR_GET(str);
1606 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1609 case LB_GETITEMRECT:
1612 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1613 if (!rect) return -1;
1614 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1615 *plparam = (LPARAM)SEGPTR_GET(rect);
1617 *pmsg16 = LB_GETITEMRECT16;
1619 case LB_GETSELITEMS:
1622 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1623 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1624 + sizeof(LPARAM)))) return -1;
1625 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1626 *plparam = (LPARAM)SEGPTR_GET(items);
1628 *pmsg16 = LB_GETSELITEMS16;
1630 case LB_SETTABSTOPS:
1635 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1636 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1637 + sizeof(LPARAM)))) return -1;
1638 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1639 *plparam = (LPARAM)SEGPTR_GET(stops);
1642 *pmsg16 = LB_SETTABSTOPS16;
1645 case CB_GETDROPPEDCONTROLRECT:
1648 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1649 if (!rect) return -1;
1650 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1651 *plparam = (LPARAM)SEGPTR_GET(rect);
1653 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1657 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1658 *pmsg16 = LB_GETTEXT16;
1662 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1663 *pmsg16 = CB_GETLBTEXT16;
1668 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
1669 *pmsg16 = EM_SETSEL16;
1676 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1680 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1682 case WM_CTLCOLORMSGBOX:
1683 case WM_CTLCOLOREDIT:
1684 case WM_CTLCOLORLISTBOX:
1685 case WM_CTLCOLORBTN:
1686 case WM_CTLCOLORDLG:
1687 case WM_CTLCOLORSCROLLBAR:
1688 case WM_CTLCOLORSTATIC:
1689 *pmsg16 = WM_CTLCOLOR;
1690 *plparam = MAKELPARAM( (HWND16)*plparam,
1691 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1693 case WM_COMPAREITEM:
1695 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
1696 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1697 if (!cis) return -1;
1698 cis->CtlType = (UINT16)cis32->CtlType;
1699 cis->CtlID = (UINT16)cis32->CtlID;
1700 cis->hwndItem = (HWND16)cis32->hwndItem;
1701 cis->itemID1 = (UINT16)cis32->itemID1;
1702 cis->itemData1 = cis32->itemData1;
1703 cis->itemID2 = (UINT16)cis32->itemID2;
1704 cis->itemData2 = cis32->itemData2;
1705 *plparam = (LPARAM)SEGPTR_GET(cis);
1710 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
1711 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1712 if (!dis) return -1;
1713 dis->CtlType = (UINT16)dis32->CtlType;
1714 dis->CtlID = (UINT16)dis32->CtlID;
1715 dis->itemID = (UINT16)dis32->itemID;
1716 dis->hwndItem = (HWND16)dis32->hwndItem;
1717 dis->itemData = dis32->itemData;
1718 *plparam = (LPARAM)SEGPTR_GET(dis);
1723 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
1724 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1725 if (!dis) return -1;
1726 dis->CtlType = (UINT16)dis32->CtlType;
1727 dis->CtlID = (UINT16)dis32->CtlID;
1728 dis->itemID = (UINT16)dis32->itemID;
1729 dis->itemAction = (UINT16)dis32->itemAction;
1730 dis->itemState = (UINT16)dis32->itemState;
1731 dis->hwndItem = (HWND16)dis32->hwndItem;
1732 dis->hDC = (HDC16)dis32->hDC;
1733 dis->itemData = dis32->itemData;
1734 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1735 *plparam = (LPARAM)SEGPTR_GET(dis);
1738 case WM_MEASUREITEM:
1740 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
1741 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1742 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1743 if (!mis) return -1;
1744 mis->CtlType = (UINT16)mis32->CtlType;
1745 mis->CtlID = (UINT16)mis32->CtlID;
1746 mis->itemID = (UINT16)mis32->itemID;
1747 mis->itemWidth = (UINT16)mis32->itemWidth;
1748 mis->itemHeight = (UINT16)mis32->itemHeight;
1749 mis->itemData = mis32->itemData;
1750 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1751 *plparam = (LPARAM)SEGPTR_GET(mis);
1754 case WM_GETMINMAXINFO:
1756 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1758 if (!mmi) return -1;
1759 STRUCT32_MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
1760 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1761 *plparam = (LPARAM)SEGPTR_GET(mmi);
1767 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1768 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1769 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1770 *plparam = (LPARAM)SEGPTR_GET(str);
1775 MDICREATESTRUCT16 *cs;
1776 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
1779 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1780 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1781 name = SEGPTR_STRDUP( cs32->szTitle );
1782 cls = SEGPTR_STRDUP( cs32->szClass );
1783 cs->szTitle = SEGPTR_GET(name);
1784 cs->szClass = SEGPTR_GET(cls);
1785 *plparam = (LPARAM)SEGPTR_GET(cs);
1788 case WM_MDIGETACTIVE:
1791 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1792 (HMENU16)LOWORD(*plparam) );
1793 *pwparam16 = (*plparam == 0);
1796 if(HIWORD(wParam32) & MF_POPUP)
1799 if((hmenu = GetSubMenu((HMENU16)*plparam, *pwparam16))) *pwparam16=hmenu;
1803 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1805 case WM_MDIACTIVATE:
1807 WND *tempWnd = WIN_FindWndPtr(hwnd);
1808 if( WIDGETS_IsControl(tempWnd, BIC32_MDICLIENT) )
1810 *pwparam16 = (HWND)wParam32;
1815 *pwparam16 = ((HWND)*plparam == hwnd);
1816 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1817 (HWND16)LOWORD(wParam32) );
1819 WIN_ReleaseWndPtr(tempWnd);
1824 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
1825 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1828 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1832 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1833 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1834 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1839 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1840 nc->lppos = SEGPTR_GET(wp);
1842 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1843 *plparam = (LPARAM)SEGPTR_GET(nc);
1850 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
1853 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1854 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1855 name = SEGPTR_STRDUP( cs32->lpszName );
1856 cls = SEGPTR_STRDUP( cs32->lpszClass );
1857 cs->lpszName = SEGPTR_GET(name);
1858 cs->lpszClass = SEGPTR_GET(cls);
1859 *plparam = (LPARAM)SEGPTR_GET(cs);
1862 case WM_PARENTNOTIFY:
1863 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1864 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1865 /* else nothing to do */
1868 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
1872 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1873 if (!str) return -1;
1874 *plparam = (LPARAM)SEGPTR_GET(str);
1877 case WM_WINDOWPOSCHANGING:
1878 case WM_WINDOWPOSCHANGED:
1880 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1883 STRUCT32_WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
1884 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1885 *plparam = (LPARAM)SEGPTR_GET(wp);
1890 LPMSG msg32 = (LPMSG) *plparam;
1891 LPMSG16 msg16 = (LPMSG16) SEGPTR_NEW( MSG16 );
1893 if (!msg16) return -1;
1894 msg16->hwnd = msg32->hwnd;
1895 msg16->lParam = msg32->lParam;
1896 msg16->time = msg32->time;
1897 CONV_POINT32TO16(&msg32->pt,&msg16->pt);
1898 /* this is right, right? */
1899 if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
1900 &msg16->message,&msg16->wParam, &msg16->lParam)<0) {
1901 SEGPTR_FREE( msg16 );
1904 *plparam = (LPARAM)SEGPTR_GET(msg16);
1909 case WM_ACTIVATEAPP:
1911 *plparam = (LPARAM)THREAD_IdToTEB((DWORD) *plparam)->htask16;
1914 case WM_ASKCBFORMATNAME:
1915 case WM_DEVMODECHANGE:
1916 case WM_PAINTCLIPBOARD:
1917 case WM_SIZECLIPBOARD:
1918 case WM_WININICHANGE:
1919 FIXME_(msg)("message %04x needs translation\n", msg32 );
1921 default: /* No translation needed */
1927 /**********************************************************************
1928 * WINPROC_UnmapMsg32ATo16
1930 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1932 void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1941 case LB_FINDSTRINGEXACT:
1942 case LB_INSERTSTRING:
1943 case LB_SELECTSTRING:
1944 case LB_SETTABSTOPS:
1947 case CB_FINDSTRINGEXACT:
1948 case CB_INSERTSTRING:
1949 case CB_SELECTSTRING:
1951 case WM_COMPAREITEM:
1955 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1958 case CB_GETDROPPEDCONTROLRECT:
1959 case LB_GETITEMRECT:
1961 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1962 p16->lParam = *(LPARAM *)(rect + 1);
1963 CONV_RECT16TO32( rect, (RECT *)(p16->lParam));
1964 SEGPTR_FREE( rect );
1967 case LB_GETSELITEMS:
1970 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1971 p16->lParam = *((LPARAM *)items - 1);
1972 for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
1973 SEGPTR_FREE( (LPARAM *)items - 1 );
1979 *((LPUINT)(wParam)) = LOWORD(p16->lResult);
1981 *((LPUINT)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1986 UnMapLS( (SEGPTR)(p16->lParam) );
1989 case WM_MEASUREITEM:
1991 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1992 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
1993 mis32->itemWidth = mis->itemWidth;
1994 mis32->itemHeight = mis->itemHeight;
1998 case WM_GETMINMAXINFO:
2000 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
2001 p16->lParam = *(LPARAM *)(mmi + 1);
2002 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
2008 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
2009 p16->lParam = *((LPARAM *)str - 1);
2010 lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
2011 SEGPTR_FREE( (LPARAM *)str - 1 );
2016 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
2017 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
2018 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
2022 case WM_MDIGETACTIVE:
2023 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
2024 p16->lResult = (HWND)LOWORD(p16->lResult);
2028 NCCALCSIZE_PARAMS *nc32;
2029 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
2030 p16->lParam = *(LPARAM *)(nc + 1);
2031 nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
2032 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
2035 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
2036 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
2037 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
2039 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
2047 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
2048 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
2049 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
2053 case WM_WINDOWPOSCHANGING:
2054 case WM_WINDOWPOSCHANGED:
2056 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
2057 p16->lParam = *(LPARAM *)(wp + 1);
2058 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
2063 UnMapLS(p16->lParam);
2068 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(p16->lParam);
2070 msgp16.wParam=msg16->wParam;
2071 msgp16.lParam=msg16->lParam;
2072 WINPROC_UnmapMsg32ATo16(((LPMSG)lParam)->hwnd, ((LPMSG)lParam)->message,
2073 ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam,
2082 /**********************************************************************
2083 * WINPROC_MapMsg32WTo16
2085 * Map a message from 32-bit Unicode to 16-bit.
2086 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2088 INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
2089 UINT16 *pmsg16, WPARAM16 *pwparam16,
2096 case LB_FINDSTRINGEXACT:
2097 case LB_INSERTSTRING:
2098 case LB_SELECTSTRING:
2102 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2103 if (!str) return -1;
2104 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2105 *plparam = (LPARAM)SEGPTR_GET(str);
2107 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2112 case CB_FINDSTRINGEXACT:
2113 case CB_INSERTSTRING:
2114 case CB_SELECTSTRING:
2117 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2118 if (!str) return -1;
2119 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2120 *plparam = (LPARAM)SEGPTR_GET(str);
2122 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2129 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2132 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
2133 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2134 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
2135 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
2136 cs->lpszName = SEGPTR_GET(name);
2137 cs->lpszClass = SEGPTR_GET(cls);
2138 *pmsg16 = (UINT16)msg32;
2139 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2140 *plparam = (LPARAM)SEGPTR_GET(cs);
2145 MDICREATESTRUCT16 *cs;
2146 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2149 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
2150 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2151 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
2152 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
2153 cs->szTitle = SEGPTR_GET(name);
2154 cs->szClass = SEGPTR_GET(cls);
2155 *pmsg16 = (UINT16)msg32;
2156 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2157 *plparam = (LPARAM)SEGPTR_GET(cs);
2162 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2163 if (!str) return -1;
2164 *pmsg16 = (UINT16)msg32;
2165 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2166 *plparam = (LPARAM)SEGPTR_GET(str);
2169 default: /* No Unicode translation needed */
2170 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2171 pwparam16, plparam );
2176 /**********************************************************************
2177 * WINPROC_UnmapMsg32WTo16
2179 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2181 void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2188 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
2189 p16->lParam = *((LPARAM *)str - 1);
2190 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
2191 SEGPTR_FREE( (LPARAM *)str - 1 );
2195 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2201 /**********************************************************************
2202 * WINPROC_CallProc32ATo32W
2204 * Call a window procedure, translating args from Ansi to Unicode.
2206 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
2207 UINT msg, WPARAM wParam,
2212 if (WINPROC_MapMsg32ATo32W( hwnd, msg, wParam, &lParam ) == -1) return 0;
2213 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2214 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
2219 /**********************************************************************
2220 * WINPROC_CallProc32WTo32A
2222 * Call a window procedure, translating args from Unicode to Ansi.
2224 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
2225 UINT msg, WPARAM wParam,
2230 if (WINPROC_MapMsg32WTo32A( hwnd, msg, wParam, &lParam ) == -1) return 0;
2231 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2232 WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
2237 /**********************************************************************
2238 * WINPROC_CallProc16To32A
2240 * Call a 32-bit window procedure, translating the 16-bit args.
2242 static LRESULT WINPROC_CallProc16To32A( WNDPROC func, HWND16 hwnd,
2243 UINT16 msg, WPARAM16 wParam,
2250 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2252 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2253 return WINPROC_UnmapMsg16To32A( hwnd, msg32, wParam32, lParam, result );
2256 /**********************************************************************
2257 * WINPROC_Thunk16To32A
2259 static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args )
2261 HWND16 hwnd = *(HWND16 *)( args+8 );
2262 UINT16 msg = *(HWND16 *)( args+6 );
2263 WPARAM16 wParam = *(HWND16 *)( args+4 );
2264 LPARAM lParam = *(LPARAM *)( args+0 );
2266 return WINPROC_CallProc16To32A( func, hwnd, msg, wParam, lParam );
2270 /**********************************************************************
2271 * WINPROC_CallProc16To32W
2273 * Call a 32-bit window procedure, translating the 16-bit args.
2275 static LRESULT WINPROC_CallProc16To32W( WNDPROC func, HWND16 hwnd,
2276 UINT16 msg, WPARAM16 wParam,
2283 if (WINPROC_MapMsg16To32W( hwnd, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2286 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2288 return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result );
2291 /**********************************************************************
2292 * WINPROC_Thunk16To32W
2294 static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args )
2296 HWND16 hwnd = *(HWND16 *)( args+8 );
2297 UINT16 msg = *(HWND16 *)( args+6 );
2298 WPARAM16 wParam = *(HWND16 *)( args+4 );
2299 LPARAM lParam = *(LPARAM *)( args+0 );
2301 return WINPROC_CallProc16To32W( func, hwnd, msg, wParam, lParam );
2304 /**********************************************************************
2305 * WINPROC_CallProc32ATo16
2307 * Call a 16-bit window procedure, translating the 32-bit args.
2309 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
2310 UINT msg, WPARAM wParam,
2316 mp16.lParam = lParam;
2317 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
2318 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
2320 mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
2321 mp16.wParam, mp16.lParam );
2322 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
2323 return mp16.lResult;
2327 /**********************************************************************
2328 * WINPROC_CallProc32WTo16
2330 * Call a 16-bit window procedure, translating the 32-bit args.
2332 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
2333 UINT msg, WPARAM wParam,
2339 mp16.lParam = lParam;
2340 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
2341 &mp16.lParam ) == -1)
2343 mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
2344 mp16.wParam, mp16.lParam );
2345 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
2346 return mp16.lResult;
2350 /**********************************************************************
2351 * CallWindowProc16 (USER.122)
2353 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
2354 WPARAM16 wParam, LPARAM lParam )
2356 WINDOWPROC *proc = WINPROC_GetPtr( func );
2359 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2362 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
2363 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2369 if (!proc->thunk.t_from32.proc) return 0;
2370 return WINPROC_CallWndProc16( proc->thunk.t_from32.proc,
2371 hwnd, msg, wParam, lParam );
2373 if (!proc->thunk.t_from16.proc) return 0;
2374 return WINPROC_CallProc16To32A( proc->thunk.t_from16.proc,
2375 hwnd, msg, wParam, lParam );
2377 if (!proc->thunk.t_from16.proc) return 0;
2378 return WINPROC_CallProc16To32W( proc->thunk.t_from16.proc,
2379 hwnd, msg, wParam, lParam );
2381 WARN_(relay)("Invalid proc %p\n", proc );
2387 /**********************************************************************
2388 * CallWindowProc32A (USER32.18)
2390 * The CallWindowProc() function invokes the windows procedure _func_,
2391 * with _hwnd_ as the target window, the message specified by _msg_, and
2392 * the message parameters _wParam_ and _lParam_.
2394 * Some kinds of argument conversion may be done, I'm not sure what.
2396 * CallWindowProc() may be used for windows subclassing. Use
2397 * SetWindowLong() to set a new windows procedure for windows of the
2398 * subclass, and handle subclassed messages in the new windows
2399 * procedure. The new windows procedure may then use CallWindowProc()
2400 * with _func_ set to the parent class's windows procedure to dispatch
2401 * the message to the superclass.
2405 * The return value is message dependent.
2411 LRESULT WINAPI CallWindowProcA(
2412 WNDPROC func, /* window procedure */
2413 HWND hwnd, /* target window */
2414 UINT msg, /* message */
2415 WPARAM wParam, /* message dependent parameter */
2416 LPARAM lParam /* message dependent parameter */
2418 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2420 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2423 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2424 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2430 if (!proc->thunk.t_from32.proc) return 0;
2431 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2432 hwnd, msg, wParam, lParam );
2434 if (!proc->thunk.t_from16.proc) return 0;
2435 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2436 hwnd, msg, wParam, lParam );
2438 if (!proc->thunk.t_from16.proc) return 0;
2439 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2440 hwnd, msg, wParam, lParam );
2442 WARN_(relay)("Invalid proc %p\n", proc );
2448 /**********************************************************************
2449 * CallWindowProc32W (USER32.19)
2451 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
2452 WPARAM wParam, LPARAM lParam )
2454 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2456 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2459 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2460 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2466 if (!proc->thunk.t_from32.proc) return 0;
2467 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2468 hwnd, msg, wParam, lParam );
2470 if (!proc->thunk.t_from16.proc) return 0;
2471 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2472 hwnd, msg, wParam, lParam );
2474 if (!proc->thunk.t_from16.proc) return 0;
2475 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2476 hwnd, msg, wParam, lParam );
2478 WARN_(relay)("Invalid proc %p\n", proc );