Fixed crashes with WM_GETDLGCODE translation.
[wine/multimedia.git] / windows / winproc.c
blob018055349004e0e04a85ba2aeeb2f3d5847972fe
1 /*
2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
6 */
8 #include "windows.h"
9 #include "callback.h"
10 #include "heap.h"
11 #include "selectors.h"
12 #include "struct32.h"
13 #include "win.h"
14 #include "winproc.h"
15 #include "debug.h"
16 #include "spy.h"
17 #include "commctrl.h"
19 /* Window procedure 16-to-32-bit thunk,
20 * see BuildSpec16Files() in tools/build.c */
22 typedef struct
24 BYTE popl_eax; /* popl %eax (return address) */
25 BYTE pushl_func; /* pushl $proc */
26 WNDPROC32 proc WINE_PACKED;
27 BYTE pushl_eax; /* pushl %eax */
28 WORD pushw_bp WINE_PACKED; /* pushw %bp */
29 BYTE pushl_thunk; /* pushl $thunkfrom16 */
30 void (*thunk32)() WINE_PACKED;
31 BYTE lcall; /* lcall cs:relay */
32 void (*relay)() WINE_PACKED; /* WINPROC_CallProc16To32A/W() */
33 WORD cs WINE_PACKED;
34 } WINPROC_THUNK_FROM16;
36 /* Window procedure 32-to-16-bit thunk,
37 * see BuildSpec32Files() in tools/build.c */
39 typedef struct
41 BYTE popl_eax; /* popl %eax (return address) */
42 BYTE pushl_func; /* pushl $proc */
43 WNDPROC16 proc WINE_PACKED;
44 BYTE pushl_eax; /* pushl %eax */
45 BYTE jmp; /* jmp relay (relative jump)*/
46 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
47 } WINPROC_THUNK_FROM32;
49 /* Simple jmp to call 32-bit procedure directly */
50 typedef struct
52 BYTE jmp; /* jmp proc (relative jump) */
53 WNDPROC32 proc WINE_PACKED;
54 } WINPROC_JUMP;
56 typedef union
58 WINPROC_THUNK_FROM16 t_from16;
59 WINPROC_THUNK_FROM32 t_from32;
60 } WINPROC_THUNK;
62 typedef struct tagWINDOWPROC
64 WINPROC_THUNK thunk; /* Thunk */
65 WINPROC_JUMP jmp; /* Jump */
66 struct tagWINDOWPROC *next; /* Next window proc */
67 UINT32 magic; /* Magic number */
68 WINDOWPROCTYPE type; /* Function type */
69 WINDOWPROCUSER user; /* Function user */
70 } WINDOWPROC;
72 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
74 #define WINPROC_THUNKPROC(pproc) \
75 (((pproc)->type == WIN_PROC_16) ? \
76 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
77 (WNDPROC16)((pproc)->thunk.t_from16.proc))
79 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
80 UINT32 msg, WPARAM32 wParam,
81 LPARAM lParam );
82 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
83 UINT32 msg, WPARAM32 wParam,
84 LPARAM lParam );
85 static LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
86 WPARAM16 wParam, LPARAM lParam,
87 WNDPROC32 func );
88 static LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
89 WPARAM16 wParam, LPARAM lParam,
90 WNDPROC32 func );
92 static HANDLE32 WinProcHeap;
95 /**********************************************************************
96 * WINPROC_Init
98 BOOL32 WINPROC_Init(void)
100 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
101 if (!WinProcHeap)
103 WARN(relay, "Unable to create winproc heap\n" );
104 return FALSE;
106 return TRUE;
110 /**********************************************************************
111 * WINPROC_CallWndProc32
113 * Call a 32-bit WndProc.
115 static LRESULT WINPROC_CallWndProc32( WNDPROC32 proc, HWND32 hwnd, UINT32 msg,
116 WPARAM32 wParam, LPARAM lParam )
118 TRACE(relay, "(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
119 proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
120 return proc( hwnd, msg, wParam, lParam );
124 /**********************************************************************
125 * WINPROC_GetPtr
127 * Return a pointer to the win proc.
129 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
131 BYTE *ptr;
132 WINDOWPROC *proc;
134 /* Check for a linear pointer */
136 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
138 ptr = (BYTE *)handle;
139 /* First check if it is the jmp address */
140 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
141 (int)&((WINDOWPROC *)0)->thunk;
142 /* Now it must be the thunk address */
143 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
144 /* Now we have a pointer to the WINDOWPROC struct */
145 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
146 return (WINDOWPROC *)ptr;
149 /* Check for a segmented pointer */
151 if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
153 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
154 if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
155 /* It must be the thunk address */
156 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
157 /* Now we have a pointer to the WINDOWPROC struct */
158 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
159 return (WINDOWPROC *)ptr;
162 return NULL;
166 /**********************************************************************
167 * WINPROC_AllocWinProc
169 * Allocate a new window procedure.
171 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
172 WINDOWPROCUSER user )
174 WINDOWPROC *proc, *oldproc;
176 /* Allocate a window procedure */
178 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
180 /* Check if the function is already a win proc */
182 if ((oldproc = WINPROC_GetPtr( func )))
184 *proc = *oldproc;
186 else
188 switch(type)
190 case WIN_PROC_16:
191 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
192 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
193 proc->thunk.t_from32.proc = func;
194 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
195 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
196 proc->thunk.t_from32.relay = /* relative jump */
197 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
198 (DWORD)(&proc->thunk.t_from32.relay + 1));
199 break;
200 case WIN_PROC_32A:
201 case WIN_PROC_32W:
202 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
203 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
204 proc->thunk.t_from16.proc = (FARPROC32)func;
205 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
206 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
207 proc->thunk.t_from16.pushl_thunk = 0x68; /* pushl $thunkfrom16 */
208 proc->thunk.t_from16.thunk32 = (type == WIN_PROC_32A) ?
209 (void(*)())WINPROC_CallProc16To32A :
210 (void(*)())WINPROC_CallProc16To32W;
211 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:relay */
212 proc->thunk.t_from16.relay = Callbacks->CallFrom16WndProc;
213 GET_CS(proc->thunk.t_from16.cs);
214 proc->jmp.jmp = 0xe9;
215 /* Fixup relative jump */
216 proc->jmp.proc = (WNDPROC32)((DWORD)func -
217 (DWORD)(&proc->jmp.proc + 1));
218 break;
219 default:
220 /* Should not happen */
221 break;
223 proc->magic = WINPROC_MAGIC;
224 proc->type = type;
225 proc->user = user;
227 proc->next = NULL;
228 TRACE(win, "(%08x,%d): returning %08x\n",
229 (UINT32)func, type, (UINT32)proc );
230 return proc;
234 /**********************************************************************
235 * WINPROC_GetProc
237 * Get a window procedure pointer that can be passed to the Windows program.
239 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
241 if (!proc) return NULL;
242 if (type == WIN_PROC_16) /* We want a 16:16 address */
244 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
245 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
246 else
247 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
248 &((WINDOWPROC *)proc)->thunk );
250 else /* We want a 32-bit address */
252 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
253 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
254 else if (type != ((WINDOWPROC *)proc)->type)
255 /* Have to return the jmp address if types don't match */
256 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
257 else
258 /* Some Win16 programs want to get back the proc they set */
259 return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc;
264 /**********************************************************************
265 * WINPROC_SetProc
267 * Set the window procedure for a window or class. There are
268 * three tree classes of winproc callbacks:
270 * 1) class -> wp - not subclassed
271 * class -> wp -> wp -> wp -> wp - SetClassLong()
272 * / /
273 * 2) window -' / - not subclassed
274 * window -> wp -> wp ' - SetWindowLong()
276 * 3) timer -> wp - SetTimer()
278 * Initially, winproc of the window points to the current winproc
279 * thunk of its class. Subclassing prepends a new thunk to the
280 * window winproc chain at the head of the list. Thus, window thunk
281 * list includes class thunks and the latter are preserved when the
282 * window is destroyed.
285 BOOL32 WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
286 WINDOWPROCTYPE type, WINDOWPROCUSER user )
288 BOOL32 bRecycle = FALSE;
289 WINDOWPROC *proc, **ppPrev;
291 /* Check if function is already in the list */
293 ppPrev = (WINDOWPROC **)pFirst;
294 proc = WINPROC_GetPtr( func );
295 while (*ppPrev)
297 if (proc)
299 if (*ppPrev == proc)
301 if ((*ppPrev)->user != user)
303 /* terminal thunk is being restored */
305 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
306 *(WINDOWPROC **)pFirst = *ppPrev;
307 return TRUE;
309 bRecycle = TRUE;
310 break;
313 else
315 if (((*ppPrev)->type == type) &&
316 (func == WINPROC_THUNKPROC(*ppPrev)))
318 bRecycle = TRUE;
319 break;
323 /* WPF_CLASS thunk terminates window thunk list */
324 if ((*ppPrev)->user != user) break;
325 ppPrev = &(*ppPrev)->next;
328 if (bRecycle)
330 /* Extract this thunk from the list */
331 proc = *ppPrev;
332 *ppPrev = proc->next;
334 else /* Allocate a new one */
336 if (proc) /* Was already a win proc */
338 type = proc->type;
339 func = WINPROC_THUNKPROC(proc);
341 proc = WINPROC_AllocWinProc( func, type, user );
342 if (!proc) return FALSE;
345 /* Add the win proc at the head of the list */
347 TRACE(win, "(%08x,%08x,%d): res=%08x\n",
348 (UINT32)*pFirst, (UINT32)func, type, (UINT32)proc );
349 proc->next = *(WINDOWPROC **)pFirst;
350 *(WINDOWPROC **)pFirst = proc;
351 return TRUE;
355 /**********************************************************************
356 * WINPROC_FreeProc
358 * Free a list of win procs.
360 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
362 while (proc)
364 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
365 if (((WINDOWPROC *)proc)->user != user) break;
366 TRACE(win, "freeing %08x\n", (UINT32)proc);
367 HeapFree( WinProcHeap, 0, proc );
368 proc = next;
373 /**********************************************************************
374 * WINPROC_GetProcType
376 * Return the window procedure type.
378 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
380 if (!proc ||
381 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
382 return WIN_PROC_INVALID;
383 return ((WINDOWPROC *)proc)->type;
387 /**********************************************************************
388 * WINPROC_MapMsg32ATo32W
390 * Map a message from Ansi to Unicode.
391 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
392 * fixme WM_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR,
393 * WM_SYSDEADCHAR ???
395 INT32 WINPROC_MapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
397 switch(msg)
399 case WM_GETTEXT:
401 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
402 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
403 if (!ptr) return -1;
404 *ptr++ = *plparam; /* Store previous lParam */
405 *plparam = (LPARAM)ptr;
407 return 1;
408 case LB_GETTEXT32:
409 case CB_GETLBTEXT32:
410 /* fixme: fixed sized buffer */
412 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
413 256 * sizeof(WCHAR) + sizeof(LPARAM) );
414 if (!ptr) return -1;
415 *ptr++ = *plparam; /* Store previous lParam */
416 *plparam = (LPARAM)ptr;
418 return 1;
419 case WM_SETTEXT:
420 case CB_ADDSTRING32:
421 case CB_DIR32:
422 case CB_FINDSTRING32:
423 case CB_FINDSTRINGEXACT32:
424 case CB_INSERTSTRING32:
425 case CB_SELECTSTRING32:
426 case LB_ADDSTRING32:
427 case LB_INSERTSTRING32:
428 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
429 return (*plparam ? 1 : -1);
430 case WM_NCCREATE:
431 case WM_CREATE:
433 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
434 sizeof(*cs) );
435 if (!cs) return -1;
436 *cs = *(CREATESTRUCT32W *)*plparam;
437 if (HIWORD(cs->lpszName))
438 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
439 (LPCSTR)cs->lpszName );
440 if (HIWORD(cs->lpszClass))
441 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
442 (LPCSTR)cs->lpszClass );
443 *plparam = (LPARAM)cs;
445 return 1;
446 case WM_MDICREATE:
448 MDICREATESTRUCT32W *cs =
449 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
450 if (!cs) return -1;
451 *cs = *(MDICREATESTRUCT32W *)*plparam;
452 if (HIWORD(cs->szClass))
453 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
454 (LPCSTR)cs->szClass );
455 if (HIWORD(cs->szTitle))
456 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
457 (LPCSTR)cs->szTitle );
458 *plparam = (LPARAM)cs;
460 return 1;
461 case WM_ASKCBFORMATNAME:
462 case WM_DEVMODECHANGE:
463 case WM_PAINTCLIPBOARD:
464 case WM_SIZECLIPBOARD:
465 case WM_WININICHANGE:
466 case EM_GETLINE32:
467 case EM_REPLACESEL32:
468 case EM_SETPASSWORDCHAR32:
469 case LB_ADDFILE32:
470 case LB_DIR32:
471 case LB_FINDSTRING32:
472 case LB_SELECTSTRING32:
473 FIXME(msg, "message %s (0x%x) needs translation\n", SPY_GetMsgName(msg), msg );
474 return -1;
475 default: /* No translation needed */
476 return 0;
481 /**********************************************************************
482 * WINPROC_UnmapMsg32ATo32W
484 * Unmap a message that was mapped from Ansi to Unicode.
486 void WINPROC_UnmapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
488 switch(msg)
490 case WM_GETTEXT:
492 LPARAM *ptr = (LPARAM *)lParam - 1;
493 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)(ptr + 1), wParam );
494 HeapFree( SystemHeap, 0, ptr );
496 break;
497 case LB_GETTEXT32:
498 case CB_GETLBTEXT32:
500 LPARAM *ptr = (LPARAM *)lParam - 1;
501 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(ptr + 1) );
502 HeapFree( SystemHeap, 0, ptr );
504 break;
506 case LB_ADDSTRING32:
507 case LB_INSERTSTRING32:
508 case CB_ADDSTRING32:
509 case CB_DIR32:
510 case CB_FINDSTRING32:
511 case CB_FINDSTRINGEXACT32:
512 case CB_INSERTSTRING32:
513 case CB_SELECTSTRING32:
514 case WM_SETTEXT:
515 HeapFree( SystemHeap, 0, (void *)lParam );
516 break;
517 case WM_NCCREATE:
518 case WM_CREATE:
520 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
521 if (HIWORD(cs->lpszName))
522 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
523 if (HIWORD(cs->lpszClass))
524 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
525 HeapFree( SystemHeap, 0, cs );
527 break;
528 case WM_MDICREATE:
530 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
531 if (HIWORD(cs->szTitle))
532 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
533 if (HIWORD(cs->szClass))
534 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
535 HeapFree( SystemHeap, 0, cs );
537 break;
542 /**********************************************************************
543 * WINPROC_MapMsg32WTo32A
545 * Map a message from Unicode to Ansi.
546 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
548 INT32 WINPROC_MapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
550 switch(msg)
552 case WM_GETTEXT:
554 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
555 wParam + sizeof(LPARAM) );
556 if (!ptr) return -1;
557 *ptr++ = *plparam; /* Store previous lParam */
558 *plparam = (LPARAM)ptr;
560 return 1;
562 case LB_GETTEXT32:
563 case CB_GETLBTEXT32:
564 /* fixme: fixed sized buffer */
566 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
567 256 + sizeof(LPARAM) );
568 if (!ptr) return -1;
569 *ptr++ = *plparam; /* Store previous lParam */
570 *plparam = (LPARAM)ptr;
572 return 1;
574 case LB_ADDSTRING32:
575 case LB_INSERTSTRING32:
576 case CB_ADDSTRING32:
577 case CB_DIR32:
578 case CB_FINDSTRING32:
579 case CB_FINDSTRINGEXACT32:
580 case CB_INSERTSTRING32:
581 case CB_SELECTSTRING32:
582 case WM_SETTEXT:
583 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
584 return (*plparam ? 1 : -1);
585 case WM_NCCREATE:
586 case WM_CREATE:
588 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
589 sizeof(*cs) );
590 if (!cs) return -1;
591 *cs = *(CREATESTRUCT32A *)*plparam;
592 if (HIWORD(cs->lpszName))
593 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
594 (LPCWSTR)cs->lpszName );
595 if (HIWORD(cs->lpszClass))
596 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
597 (LPCWSTR)cs->lpszClass);
598 *plparam = (LPARAM)cs;
600 return 1;
601 case WM_MDICREATE:
603 MDICREATESTRUCT32A *cs =
604 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
605 if (!cs) return -1;
606 *cs = *(MDICREATESTRUCT32A *)*plparam;
607 if (HIWORD(cs->szTitle))
608 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
609 (LPCWSTR)cs->szTitle );
610 if (HIWORD(cs->szClass))
611 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
612 (LPCWSTR)cs->szClass );
613 *plparam = (LPARAM)cs;
615 return 1;
616 case WM_ASKCBFORMATNAME:
617 case WM_DEVMODECHANGE:
618 case WM_PAINTCLIPBOARD:
619 case WM_SIZECLIPBOARD:
620 case WM_WININICHANGE:
621 case EM_GETLINE32:
622 case EM_REPLACESEL32:
623 case EM_SETPASSWORDCHAR32:
624 case LB_ADDFILE32:
625 case LB_DIR32:
626 case LB_FINDSTRING32:
627 case LB_SELECTSTRING32:
628 FIXME(msg, "message %04x needs translation\n",msg );
629 return -1;
630 default: /* No translation needed */
631 return 0;
636 /**********************************************************************
637 * WINPROC_UnmapMsg32WTo32A
639 * Unmap a message that was mapped from Unicode to Ansi.
641 void WINPROC_UnmapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
643 switch(msg)
645 case WM_GETTEXT:
647 LPARAM *ptr = (LPARAM *)lParam - 1;
648 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)(ptr + 1), wParam );
649 HeapFree( SystemHeap, 0, ptr );
651 break;
652 case LB_GETTEXT32:
653 case CB_GETLBTEXT32:
655 LPARAM *ptr = (LPARAM *)lParam - 1;
656 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(ptr + 1) );
657 HeapFree( SystemHeap, 0, ptr );
659 break;
660 case LB_ADDSTRING32:
661 case LB_INSERTSTRING32:
662 case CB_ADDSTRING32:
663 case CB_DIR32:
664 case CB_FINDSTRING32:
665 case CB_FINDSTRINGEXACT32:
666 case CB_INSERTSTRING32:
667 case CB_SELECTSTRING32:
668 case WM_SETTEXT:
669 HeapFree( SystemHeap, 0, (void *)lParam );
670 break;
671 case WM_NCCREATE:
672 case WM_CREATE:
674 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
675 if (HIWORD(cs->lpszName))
676 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
677 if (HIWORD(cs->lpszClass))
678 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
679 HeapFree( SystemHeap, 0, cs );
681 break;
682 case WM_MDICREATE:
684 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
685 if (HIWORD(cs->szTitle))
686 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
687 if (HIWORD(cs->szClass))
688 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
689 HeapFree( SystemHeap, 0, cs );
691 break;
696 /**********************************************************************
697 * WINPROC_MapMsg16To32A
699 * Map a message from 16- to 32-bit Ansi.
700 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
702 INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
703 WPARAM32 *pwparam32, LPARAM *plparam )
705 *pmsg32 = (UINT32)msg16;
706 *pwparam32 = (WPARAM32)wParam16;
707 switch(msg16)
709 case WM_ACTIVATE:
710 case WM_CHARTOITEM:
711 case WM_COMMAND:
712 case WM_VKEYTOITEM:
713 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
714 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
715 return 0;
716 case WM_HSCROLL:
717 case WM_VSCROLL:
718 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
719 *plparam = (LPARAM)(HWND32)HIWORD(*plparam);
720 return 0;
721 case WM_CTLCOLOR:
722 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
723 *pwparam32 = (WPARAM32)(HDC32)wParam16;
724 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
725 return 0;
726 case WM_COMPAREITEM:
728 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
729 COMPAREITEMSTRUCT32 *cis = (COMPAREITEMSTRUCT32 *)
730 HeapAlloc(SystemHeap, 0, sizeof(*cis));
731 if (!cis) return -1;
732 cis->CtlType = cis16->CtlType;
733 cis->CtlID = cis16->CtlID;
734 cis->hwndItem = cis16->hwndItem;
735 cis->itemID1 = cis16->itemID1;
736 cis->itemData1 = cis16->itemData1;
737 cis->itemID2 = cis16->itemID2;
738 cis->itemData2 = cis16->itemData2;
739 cis->dwLocaleId = 0; /* FIXME */
740 *plparam = (LPARAM)cis;
742 return 1;
743 case WM_DELETEITEM:
745 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
746 DELETEITEMSTRUCT32 *dis = (DELETEITEMSTRUCT32 *)
747 HeapAlloc(SystemHeap, 0, sizeof(*dis));
748 if (!dis) return -1;
749 dis->CtlType = dis16->CtlType;
750 dis->CtlID = dis16->CtlID;
751 dis->hwndItem = dis16->hwndItem;
752 dis->itemData = dis16->itemData;
753 *plparam = (LPARAM)dis;
755 return 1;
756 case WM_MEASUREITEM:
758 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
759 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)
760 HeapAlloc(SystemHeap, 0,
761 sizeof(*mis) + sizeof(LPARAM));
762 if (!mis) return -1;
763 mis->CtlType = mis16->CtlType;
764 mis->CtlID = mis16->CtlID;
765 mis->itemID = mis16->itemID;
766 mis->itemWidth = mis16->itemWidth;
767 mis->itemHeight = mis16->itemHeight;
768 mis->itemData = mis16->itemData;
769 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
770 *plparam = (LPARAM)mis;
772 return 1;
773 case WM_DRAWITEM:
775 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
776 DRAWITEMSTRUCT32 *dis = (DRAWITEMSTRUCT32*)HeapAlloc(SystemHeap, 0,
777 sizeof(*dis));
778 if (!dis) return -1;
779 dis->CtlType = dis16->CtlType;
780 dis->CtlID = dis16->CtlID;
781 dis->itemID = dis16->itemID;
782 dis->itemAction = dis16->itemAction;
783 dis->itemState = dis16->itemState;
784 dis->hwndItem = dis16->hwndItem;
785 dis->hDC = dis16->hDC;
786 dis->itemData = dis16->itemData;
787 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
788 *plparam = (LPARAM)dis;
790 return 1;
791 case WM_GETMINMAXINFO:
793 MINMAXINFO32 *mmi = (MINMAXINFO32 *)HeapAlloc( SystemHeap, 0,
794 sizeof(*mmi) + sizeof(LPARAM));
795 if (!mmi) return -1;
796 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
797 mmi );
798 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
799 *plparam = (LPARAM)mmi;
801 return 1;
802 case WM_GETTEXT:
803 case WM_SETTEXT:
804 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
805 return 0;
806 case WM_MDICREATE:
808 MDICREATESTRUCT16 *cs16 =
809 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
810 MDICREATESTRUCT32A *cs =
811 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
812 sizeof(*cs) + sizeof(LPARAM) );
813 if (!cs) return -1;
814 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
815 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
816 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
817 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
818 *plparam = (LPARAM)cs;
820 return 1;
821 case WM_MDIGETACTIVE:
822 *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL32) );
823 return 1;
824 case WM_MDISETMENU:
825 if(wParam16==TRUE)
826 *pmsg32=WM_MDIREFRESHMENU;
827 *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
828 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
829 return 0;
830 case WM_MENUCHAR:
831 case WM_MENUSELECT:
832 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
833 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
834 return 0;
835 case WM_MDIACTIVATE:
836 if( *plparam )
838 *pwparam32 = (WPARAM32)(HWND32)HIWORD(*plparam);
839 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
841 else /* message sent to MDI client */
842 *pwparam32 = wParam16;
843 return 0;
844 case WM_NCCALCSIZE:
846 NCCALCSIZE_PARAMS16 *nc16;
847 NCCALCSIZE_PARAMS32 *nc;
849 nc = (NCCALCSIZE_PARAMS32 *)HeapAlloc( SystemHeap, 0,
850 sizeof(*nc) + sizeof(LPARAM) );
851 if (!nc) return -1;
852 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
853 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
854 if (wParam16)
856 nc->lppos = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
857 sizeof(*nc->lppos) );
858 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
859 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
860 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
862 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
863 *plparam = (LPARAM)nc;
865 return 1;
866 case WM_NCCREATE:
867 case WM_CREATE:
869 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
870 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
871 sizeof(*cs) + sizeof(LPARAM) );
872 if (!cs) return -1;
873 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
874 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
875 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
876 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
877 *plparam = (LPARAM)cs;
879 return 1;
880 case WM_PARENTNOTIFY:
881 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
883 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
884 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
886 return 0;
887 case WM_WINDOWPOSCHANGING:
888 case WM_WINDOWPOSCHANGED:
890 WINDOWPOS32 *wp = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
891 sizeof(*wp) + sizeof(LPARAM) );
892 if (!wp) return -1;
893 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
894 wp );
895 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
896 *plparam = (LPARAM)wp;
898 return 1;
899 case WM_GETDLGCODE:
900 if (*plparam)
902 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
903 LPMSG32 msg32 = (LPMSG32)HeapAlloc( SystemHeap, 0, sizeof(MSG32) );
905 if (!msg32) return -1;
906 msg32->hwnd = msg16->hwnd;
907 msg32->lParam = msg16->lParam;
908 msg32->time = msg16->time;
909 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
910 /* this is right, right? */
911 if (WINPROC_MapMsg16To32A(msg16->message,msg16->wParam,
912 &msg32->message,&msg32->wParam,
913 &msg32->lParam)<0) {
914 HeapFree( SystemHeap, 0, msg32 );
915 return -1;
917 *plparam = (LPARAM)msg32;
918 return 1;
920 else return 0;
921 case WM_NOTIFY:
922 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
923 return 1;
924 case WM_ASKCBFORMATNAME:
925 case WM_DEVMODECHANGE:
926 case WM_PAINTCLIPBOARD:
927 case WM_SIZECLIPBOARD:
928 case WM_WININICHANGE:
929 FIXME( msg, "message %04x needs translation\n",msg16 );
930 return -1;
932 default: /* No translation needed */
933 return 0;
938 /**********************************************************************
939 * WINPROC_UnmapMsg16To32A
941 * Unmap a message that was mapped from 16- to 32-bit Ansi.
943 LRESULT WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
944 LRESULT result )
946 switch(msg)
948 case WM_COMPAREITEM:
949 case WM_DELETEITEM:
950 case WM_DRAWITEM:
951 HeapFree( SystemHeap, 0, (LPVOID)lParam );
952 break;
953 case WM_MEASUREITEM:
955 MEASUREITEMSTRUCT16 *mis16;
956 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)lParam;
957 lParam = *(LPARAM *)(mis + 1);
958 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
959 mis16->itemWidth = (UINT16)mis->itemWidth;
960 mis16->itemHeight = (UINT16)mis->itemHeight;
961 HeapFree( SystemHeap, 0, mis );
963 break;
964 case WM_GETMINMAXINFO:
966 MINMAXINFO32 *mmi = (MINMAXINFO32 *)lParam;
967 lParam = *(LPARAM *)(mmi + 1);
968 STRUCT32_MINMAXINFO32to16( mmi,
969 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
970 HeapFree( SystemHeap, 0, mmi );
972 break;
973 case WM_MDICREATE:
975 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
976 lParam = *(LPARAM *)(cs + 1);
977 STRUCT32_MDICREATESTRUCT32Ato16( cs,
978 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
979 HeapFree( SystemHeap, 0, cs );
981 break;
982 case WM_MDIGETACTIVE:
983 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL32 *)lParam) );
984 HeapFree( SystemHeap, 0, (BOOL32 *)lParam );
985 break;
986 case WM_NCCALCSIZE:
988 NCCALCSIZE_PARAMS16 *nc16;
989 NCCALCSIZE_PARAMS32 *nc = (NCCALCSIZE_PARAMS32 *)lParam;
990 lParam = *(LPARAM *)(nc + 1);
991 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
992 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
993 if (wParam)
995 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
996 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
997 if (nc->lppos)
999 STRUCT32_WINDOWPOS32to16( nc->lppos,
1000 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
1001 HeapFree( SystemHeap, 0, nc->lppos );
1004 HeapFree( SystemHeap, 0, nc );
1006 break;
1007 case WM_NCCREATE:
1008 case WM_CREATE:
1010 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
1011 lParam = *(LPARAM *)(cs + 1);
1012 STRUCT32_CREATESTRUCT32Ato16( cs,
1013 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1014 HeapFree( SystemHeap, 0, cs );
1016 break;
1017 case WM_WINDOWPOSCHANGING:
1018 case WM_WINDOWPOSCHANGED:
1020 WINDOWPOS32 *wp = (WINDOWPOS32 *)lParam;
1021 lParam = *(LPARAM *)(wp + 1);
1022 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
1023 HeapFree( SystemHeap, 0, wp );
1025 break;
1026 case WM_GETDLGCODE:
1027 if (lParam)
1029 LPMSG32 msg32 = (LPMSG32)lParam;
1031 WINPROC_UnmapMsg16To32A( msg32->message, msg32->wParam, msg32->lParam,
1032 result);
1033 HeapFree( SystemHeap, 0, msg32 );
1035 break;
1037 return result;
1041 /**********************************************************************
1042 * WINPROC_MapMsg16To32W
1044 * Map a message from 16- to 32-bit Unicode.
1045 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1047 INT32 WINPROC_MapMsg16To32W( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
1048 WPARAM32 *pwparam32, LPARAM *plparam )
1050 switch(msg16)
1052 case WM_GETTEXT:
1053 case WM_SETTEXT:
1054 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1055 return WINPROC_MapMsg32ATo32W( *pmsg32, *pwparam32, plparam );
1056 case WM_NCCREATE:
1057 case WM_CREATE:
1059 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1060 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
1061 sizeof(*cs) + sizeof(LPARAM) );
1062 if (!cs) return -1;
1063 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCT32A *)cs );
1064 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1065 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1066 if (HIWORD(cs->lpszName))
1067 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
1068 (LPCSTR)cs->lpszName );
1069 if (HIWORD(cs->lpszClass))
1070 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
1071 (LPCSTR)cs->lpszClass );
1072 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1073 *plparam = (LPARAM)cs;
1075 return 1;
1076 case WM_MDICREATE:
1078 MDICREATESTRUCT16 *cs16 =
1079 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1080 MDICREATESTRUCT32W *cs =
1081 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
1082 sizeof(*cs) + sizeof(LPARAM) );
1083 if (!cs) return -1;
1084 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCT32A *)cs );
1085 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1086 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
1087 if (HIWORD(cs->szTitle))
1088 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
1089 (LPCSTR)cs->szTitle );
1090 if (HIWORD(cs->szClass))
1091 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
1092 (LPCSTR)cs->szClass );
1093 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1094 *plparam = (LPARAM)cs;
1096 return 1;
1097 case WM_GETDLGCODE:
1098 if (*plparam)
1100 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1101 LPMSG32 msg32 = (LPMSG32)HeapAlloc( SystemHeap, 0, sizeof(MSG32) );
1103 if (!msg32) return -1;
1104 msg32->hwnd = msg16->hwnd;
1105 msg32->lParam = msg16->lParam;
1106 msg32->time = msg16->time;
1107 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1108 /* this is right, right? */
1109 if (WINPROC_MapMsg16To32W(msg16->message,msg16->wParam,
1110 &msg32->message,&msg32->wParam,
1111 &msg32->lParam)<0) {
1112 HeapFree( SystemHeap, 0, msg32 );
1113 return -1;
1115 *plparam = (LPARAM)msg32;
1116 return 1;
1118 else return 0;
1119 default: /* No Unicode translation needed */
1120 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1121 pwparam32, plparam );
1126 /**********************************************************************
1127 * WINPROC_UnmapMsg16To32W
1129 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1131 LRESULT WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1132 LRESULT result )
1134 switch(msg)
1136 case WM_GETTEXT:
1137 case WM_SETTEXT:
1138 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1139 break;
1140 case WM_NCCREATE:
1141 case WM_CREATE:
1143 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
1144 lParam = *(LPARAM *)(cs + 1);
1145 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
1146 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1147 if (HIWORD(cs->lpszName))
1148 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1149 if (HIWORD(cs->lpszClass))
1150 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1151 HeapFree( SystemHeap, 0, cs );
1153 break;
1154 case WM_MDICREATE:
1156 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
1157 lParam = *(LPARAM *)(cs + 1);
1158 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
1159 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1160 if (HIWORD(cs->szTitle))
1161 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1162 if (HIWORD(cs->szClass))
1163 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1164 HeapFree( SystemHeap, 0, cs );
1166 break;
1167 case WM_GETDLGCODE:
1168 if (lParam)
1170 LPMSG32 msg32 = (LPMSG32)lParam;
1172 WINPROC_UnmapMsg16To32W( msg32->message, msg32->wParam, msg32->lParam,
1173 result);
1174 HeapFree( SystemHeap, 0, msg32 );
1176 break;
1177 default:
1178 return WINPROC_UnmapMsg16To32A( msg, wParam, lParam, result );
1180 return result;
1184 /**********************************************************************
1185 * WINPROC_MapMsg32ATo16
1187 * Map a message from 32-bit Ansi to 16-bit.
1188 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1190 INT32 WINPROC_MapMsg32ATo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1191 UINT16 *pmsg16, WPARAM16 *pwparam16,
1192 LPARAM *plparam )
1194 *pmsg16 = (UINT16)msg32;
1195 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1196 switch(msg32)
1198 case BM_GETCHECK32:
1199 case BM_SETCHECK32:
1200 case BM_GETSTATE32:
1201 case BM_SETSTATE32:
1202 case BM_SETSTYLE32:
1203 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK32);
1204 return 0;
1206 case EM_GETSEL32:
1207 case EM_GETRECT32:
1208 case EM_SETRECT32:
1209 case EM_SETRECTNP32:
1210 case EM_SCROLL32:
1211 case EM_LINESCROLL32:
1212 case EM_SCROLLCARET32:
1213 case EM_GETMODIFY32:
1214 case EM_SETMODIFY32:
1215 case EM_GETLINECOUNT32:
1216 case EM_LINEINDEX32:
1217 case EM_SETHANDLE32:
1218 case EM_GETHANDLE32:
1219 case EM_GETTHUMB32:
1220 case EM_LINELENGTH32:
1221 case EM_REPLACESEL32:
1222 case EM_GETLINE32:
1223 case EM_LIMITTEXT32:
1224 case EM_CANUNDO32:
1225 case EM_UNDO32:
1226 case EM_FMTLINES32:
1227 case EM_LINEFROMCHAR32:
1228 case EM_SETTABSTOPS32:
1229 case EM_SETPASSWORDCHAR32:
1230 case EM_EMPTYUNDOBUFFER32:
1231 case EM_GETFIRSTVISIBLELINE32:
1232 case EM_SETREADONLY32:
1233 case EM_SETWORDBREAKPROC32:
1234 case EM_GETWORDBREAKPROC32:
1235 case EM_GETPASSWORDCHAR32:
1236 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL32);
1237 return 0;
1239 case LB_CARETOFF32:
1240 case LB_CARETON32:
1241 case LB_DELETESTRING32:
1242 case LB_GETANCHORINDEX32:
1243 case LB_GETCARETINDEX32:
1244 case LB_GETCOUNT32:
1245 case LB_GETCURSEL32:
1246 case LB_GETHORIZONTALEXTENT32:
1247 case LB_GETITEMDATA32:
1248 case LB_GETITEMHEIGHT32:
1249 case LB_GETSEL32:
1250 case LB_GETSELCOUNT32:
1251 case LB_GETTEXTLEN32:
1252 case LB_GETTOPINDEX32:
1253 case LB_RESETCONTENT32:
1254 case LB_SELITEMRANGE32:
1255 case LB_SELITEMRANGEEX32:
1256 case LB_SETANCHORINDEX32:
1257 case LB_SETCARETINDEX32:
1258 case LB_SETCOLUMNWIDTH32:
1259 case LB_SETCURSEL32:
1260 case LB_SETHORIZONTALEXTENT32:
1261 case LB_SETITEMDATA32:
1262 case LB_SETITEMHEIGHT32:
1263 case LB_SETSEL32:
1264 case LB_SETTOPINDEX32:
1265 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1266 return 0;
1267 case CB_DELETESTRING32:
1268 case CB_GETCOUNT32:
1269 case CB_GETLBTEXTLEN32:
1270 case CB_LIMITTEXT32:
1271 case CB_RESETCONTENT32:
1272 case CB_SETEDITSEL32:
1273 case CB_GETCURSEL32:
1274 case CB_SETCURSEL32:
1275 case CB_SHOWDROPDOWN32:
1276 case CB_SETITEMDATA32:
1277 case CB_SETITEMHEIGHT32:
1278 case CB_GETITEMHEIGHT32:
1279 case CB_SETEXTENDEDUI32:
1280 case CB_GETEXTENDEDUI32:
1281 case CB_GETDROPPEDSTATE32:
1282 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1283 return 0;
1284 case CB_GETEDITSEL32:
1285 *pmsg16 = CB_GETEDITSEL16;
1286 return 1;
1288 case LB_ADDSTRING32:
1289 case LB_FINDSTRING32:
1290 case LB_FINDSTRINGEXACT32:
1291 case LB_INSERTSTRING32:
1292 case LB_SELECTSTRING32:
1293 case LB_DIR32:
1294 case LB_ADDFILE32:
1296 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1297 if (!str) return -1;
1298 *plparam = (LPARAM)SEGPTR_GET(str);
1300 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1301 return 1;
1303 case CB_ADDSTRING32:
1304 case CB_FINDSTRING32:
1305 case CB_FINDSTRINGEXACT32:
1306 case CB_INSERTSTRING32:
1307 case CB_SELECTSTRING32:
1308 case CB_DIR32:
1310 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1311 if (!str) return -1;
1312 *plparam = (LPARAM)SEGPTR_GET(str);
1314 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1315 return 1;
1317 case LB_GETITEMRECT32:
1319 RECT16 *rect;
1320 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1321 if (!rect) return -1;
1322 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1323 *plparam = (LPARAM)SEGPTR_GET(rect);
1325 *pmsg16 = LB_GETITEMRECT16;
1326 return 1;
1327 case LB_GETSELITEMS32:
1329 LPINT16 items;
1330 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1331 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1332 + sizeof(LPARAM)))) return -1;
1333 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1334 *plparam = (LPARAM)SEGPTR_GET(items);
1336 *pmsg16 = LB_GETSELITEMS16;
1337 return 1;
1338 case LB_SETTABSTOPS32:
1339 if (wParam32)
1341 INT32 i;
1342 LPINT16 stops;
1343 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1344 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1345 + sizeof(LPARAM)))) return -1;
1346 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT32)*plparam+i);
1347 *plparam = (LPARAM)SEGPTR_GET(stops);
1348 return 1;
1350 *pmsg16 = LB_SETTABSTOPS16;
1351 return 0;
1353 case CB_GETDROPPEDCONTROLRECT32:
1355 RECT16 *rect;
1356 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1357 if (!rect) return -1;
1358 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1359 *plparam = (LPARAM)SEGPTR_GET(rect);
1361 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1362 return 1;
1364 case LB_GETTEXT32:
1365 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1366 *pmsg16 = LB_GETTEXT16;
1367 return 1;
1369 case CB_GETLBTEXT32:
1370 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1371 *pmsg16 = CB_GETLBTEXT16;
1372 return 1;
1374 case EM_SETSEL32:
1375 *pwparam16 = 0;
1376 *plparam = MAKELONG( (INT16)(INT32)wParam32, (INT16)*plparam );
1377 *pmsg16 = EM_SETSEL16;
1378 return 0;
1380 case WM_ACTIVATE:
1381 case WM_CHARTOITEM:
1382 case WM_COMMAND:
1383 case WM_VKEYTOITEM:
1384 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1385 return 0;
1386 case WM_HSCROLL:
1387 case WM_VSCROLL:
1388 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1389 return 0;
1390 case WM_CTLCOLORMSGBOX:
1391 case WM_CTLCOLOREDIT:
1392 case WM_CTLCOLORLISTBOX:
1393 case WM_CTLCOLORBTN:
1394 case WM_CTLCOLORDLG:
1395 case WM_CTLCOLORSCROLLBAR:
1396 case WM_CTLCOLORSTATIC:
1397 *pmsg16 = WM_CTLCOLOR;
1398 *plparam = MAKELPARAM( (HWND16)*plparam,
1399 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1400 return 0;
1401 case WM_COMPAREITEM:
1403 COMPAREITEMSTRUCT32 *cis32 = (COMPAREITEMSTRUCT32 *)*plparam;
1404 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1405 if (!cis) return -1;
1406 cis->CtlType = (UINT16)cis32->CtlType;
1407 cis->CtlID = (UINT16)cis32->CtlID;
1408 cis->hwndItem = (HWND16)cis32->hwndItem;
1409 cis->itemID1 = (UINT16)cis32->itemID1;
1410 cis->itemData1 = cis32->itemData1;
1411 cis->itemID2 = (UINT16)cis32->itemID2;
1412 cis->itemData2 = cis32->itemData2;
1413 *plparam = (LPARAM)SEGPTR_GET(cis);
1415 return 1;
1416 case WM_DELETEITEM:
1418 DELETEITEMSTRUCT32 *dis32 = (DELETEITEMSTRUCT32 *)*plparam;
1419 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1420 if (!dis) return -1;
1421 dis->CtlType = (UINT16)dis32->CtlType;
1422 dis->CtlID = (UINT16)dis32->CtlID;
1423 dis->itemID = (UINT16)dis32->itemID;
1424 dis->hwndItem = (HWND16)dis32->hwndItem;
1425 dis->itemData = dis32->itemData;
1426 *plparam = (LPARAM)SEGPTR_GET(dis);
1428 return 1;
1429 case WM_DRAWITEM:
1431 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)*plparam;
1432 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1433 if (!dis) return -1;
1434 dis->CtlType = (UINT16)dis32->CtlType;
1435 dis->CtlID = (UINT16)dis32->CtlID;
1436 dis->itemID = (UINT16)dis32->itemID;
1437 dis->itemAction = (UINT16)dis32->itemAction;
1438 dis->itemState = (UINT16)dis32->itemState;
1439 dis->hwndItem = (HWND16)dis32->hwndItem;
1440 dis->hDC = (HDC16)dis32->hDC;
1441 dis->itemData = dis32->itemData;
1442 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1443 *plparam = (LPARAM)SEGPTR_GET(dis);
1445 return 1;
1446 case WM_MEASUREITEM:
1448 MEASUREITEMSTRUCT32 *mis32 = (MEASUREITEMSTRUCT32 *)*plparam;
1449 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1450 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1451 if (!mis) return -1;
1452 mis->CtlType = (UINT16)mis32->CtlType;
1453 mis->CtlID = (UINT16)mis32->CtlID;
1454 mis->itemID = (UINT16)mis32->itemID;
1455 mis->itemWidth = (UINT16)mis32->itemWidth;
1456 mis->itemHeight = (UINT16)mis32->itemHeight;
1457 mis->itemData = mis32->itemData;
1458 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1459 *plparam = (LPARAM)SEGPTR_GET(mis);
1461 return 1;
1462 case WM_GETMINMAXINFO:
1464 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1465 sizeof(LPARAM) );
1466 if (!mmi) return -1;
1467 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)*plparam, mmi );
1468 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1469 *plparam = (LPARAM)SEGPTR_GET(mmi);
1471 return 1;
1472 case WM_GETTEXT:
1474 LPSTR str;
1475 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1476 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1477 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1478 *plparam = (LPARAM)SEGPTR_GET(str);
1480 return 1;
1481 case WM_MDICREATE:
1483 MDICREATESTRUCT16 *cs;
1484 MDICREATESTRUCT32A *cs32 = (MDICREATESTRUCT32A *)*plparam;
1485 LPSTR name, cls;
1487 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1488 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1489 name = SEGPTR_STRDUP( cs32->szTitle );
1490 cls = SEGPTR_STRDUP( cs32->szClass );
1491 cs->szTitle = SEGPTR_GET(name);
1492 cs->szClass = SEGPTR_GET(cls);
1493 *plparam = (LPARAM)SEGPTR_GET(cs);
1495 return 1;
1496 case WM_MDIGETACTIVE:
1497 return 1;
1498 case WM_MDISETMENU:
1499 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1500 (HMENU16)LOWORD(*plparam) );
1501 *pwparam16 = (*plparam == 0);
1502 return 0;
1503 case WM_MENUCHAR:
1504 case WM_MENUSELECT:
1505 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1506 return 0;
1507 case WM_MDIACTIVATE:
1508 if( WIDGETS_IsControl32(WIN_FindWndPtr(hwnd), BIC32_MDICLIENT) )
1510 *pwparam16 = (HWND32)wParam32;
1511 *plparam = 0;
1513 else
1515 *pwparam16 = ((HWND32)*plparam == hwnd);
1516 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1517 (HWND16)LOWORD(wParam32) );
1519 return 0;
1520 case WM_NCCALCSIZE:
1522 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
1523 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1524 if (!nc) return -1;
1526 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1527 if (wParam32)
1529 WINDOWPOS16 *wp;
1530 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1531 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1532 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1534 SEGPTR_FREE(nc);
1535 return -1;
1537 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1538 nc->lppos = SEGPTR_GET(wp);
1540 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1541 *plparam = (LPARAM)SEGPTR_GET(nc);
1543 return 1;
1544 case WM_NCCREATE:
1545 case WM_CREATE:
1547 CREATESTRUCT16 *cs;
1548 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)*plparam;
1549 LPSTR name, cls;
1551 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1552 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1553 name = SEGPTR_STRDUP( cs32->lpszName );
1554 cls = SEGPTR_STRDUP( cs32->lpszClass );
1555 cs->lpszName = SEGPTR_GET(name);
1556 cs->lpszClass = SEGPTR_GET(cls);
1557 *plparam = (LPARAM)SEGPTR_GET(cs);
1559 return 1;
1560 case WM_PARENTNOTIFY:
1561 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1562 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1563 /* else nothing to do */
1564 return 0;
1565 case WM_NOTIFY:
1566 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
1567 return 1;
1568 case WM_SETTEXT:
1570 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1571 if (!str) return -1;
1572 *plparam = (LPARAM)SEGPTR_GET(str);
1574 return 1;
1575 case WM_WINDOWPOSCHANGING:
1576 case WM_WINDOWPOSCHANGED:
1578 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1579 sizeof(LPARAM) );
1580 if (!wp) return -1;
1581 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)*plparam, wp );
1582 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1583 *plparam = (LPARAM)SEGPTR_GET(wp);
1585 return 1;
1586 case WM_ASKCBFORMATNAME:
1587 case WM_DEVMODECHANGE:
1588 case WM_PAINTCLIPBOARD:
1589 case WM_SIZECLIPBOARD:
1590 case WM_WININICHANGE:
1591 case WM_GETDLGCODE:
1592 FIXME( msg, "message %04x needs translation\n", msg32 );
1593 return -1;
1595 default: /* No translation needed */
1596 return 0;
1601 /**********************************************************************
1602 * WINPROC_UnmapMsg32ATo16
1604 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1606 void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1607 MSGPARAM16* p16 )
1609 switch(msg)
1611 case LB_ADDFILE32:
1612 case LB_ADDSTRING32:
1613 case LB_DIR32:
1614 case LB_FINDSTRING32:
1615 case LB_FINDSTRINGEXACT32:
1616 case LB_INSERTSTRING32:
1617 case LB_SELECTSTRING32:
1618 case LB_SETTABSTOPS32:
1619 case CB_ADDSTRING32:
1620 case CB_FINDSTRING32:
1621 case CB_FINDSTRINGEXACT32:
1622 case CB_INSERTSTRING32:
1623 case CB_SELECTSTRING32:
1624 case CB_DIR32:
1625 case WM_COMPAREITEM:
1626 case WM_DELETEITEM:
1627 case WM_DRAWITEM:
1628 case WM_SETTEXT:
1629 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1630 break;
1632 case CB_GETDROPPEDCONTROLRECT32:
1633 case LB_GETITEMRECT32:
1635 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1636 p16->lParam = *(LPARAM *)(rect + 1);
1637 CONV_RECT16TO32( rect, (RECT32 *)(p16->lParam));
1638 SEGPTR_FREE( rect );
1640 break;
1641 case LB_GETSELITEMS32:
1643 INT32 i;
1644 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1645 p16->lParam = *((LPARAM *)items - 1);
1646 for (i = 0; i < p16->wParam; i++) *((LPINT32)(p16->lParam) + i) = items[i];
1647 SEGPTR_FREE( (LPARAM *)items - 1 );
1649 break;
1651 case CB_GETEDITSEL32:
1652 if( wParam )
1653 *((LPUINT32)(wParam)) = LOWORD(p16->lResult);
1654 if( lParam )
1655 *((LPUINT32)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1656 break;
1658 case LB_GETTEXT32:
1659 case CB_GETLBTEXT32:
1660 UnMapLS( (SEGPTR)(p16->lParam) );
1661 break;
1663 case WM_MEASUREITEM:
1665 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1666 MEASUREITEMSTRUCT32 *mis32 = *(MEASUREITEMSTRUCT32 **)(mis + 1);
1667 mis32->itemWidth = mis->itemWidth;
1668 mis32->itemHeight = mis->itemHeight;
1669 SEGPTR_FREE(mis);
1671 break;
1672 case WM_GETMINMAXINFO:
1674 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1675 p16->lParam = *(LPARAM *)(mmi + 1);
1676 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)(p16->lParam) );
1677 SEGPTR_FREE(mmi);
1679 break;
1680 case WM_GETTEXT:
1682 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1683 p16->lParam = *((LPARAM *)str - 1);
1684 lstrcpyn32A( (LPSTR)(p16->lParam), str, p16->wParam );
1685 SEGPTR_FREE( (LPARAM *)str - 1 );
1687 break;
1688 case WM_MDICREATE:
1690 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1691 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1692 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1693 SEGPTR_FREE( cs );
1695 break;
1696 case WM_MDIGETACTIVE:
1697 if (lParam) *(BOOL32 *)lParam = (BOOL16)HIWORD(p16->lResult);
1698 p16->lResult = (HWND32)LOWORD(p16->lResult);
1699 break;
1700 case WM_NCCALCSIZE:
1702 NCCALCSIZE_PARAMS32 *nc32;
1703 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
1704 p16->lParam = *(LPARAM *)(nc + 1);
1705 nc32 = (NCCALCSIZE_PARAMS32 *)(p16->lParam);
1706 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1707 if (p16->wParam)
1709 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1710 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1711 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1712 nc32->lppos );
1713 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1715 SEGPTR_FREE(nc);
1717 break;
1718 case WM_NCCREATE:
1719 case WM_CREATE:
1721 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1722 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1723 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1724 SEGPTR_FREE( cs );
1726 break;
1727 case WM_WINDOWPOSCHANGING:
1728 case WM_WINDOWPOSCHANGED:
1730 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
1731 p16->lParam = *(LPARAM *)(wp + 1);
1732 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)p16->lParam );
1733 SEGPTR_FREE(wp);
1735 break;
1736 case WM_NOTIFY:
1737 UnMapLS(p16->lParam);
1738 break;
1743 /**********************************************************************
1744 * WINPROC_MapMsg32WTo16
1746 * Map a message from 32-bit Unicode to 16-bit.
1747 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1749 INT32 WINPROC_MapMsg32WTo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1750 UINT16 *pmsg16, WPARAM16 *pwparam16,
1751 LPARAM *plparam )
1753 switch(msg32)
1755 case LB_ADDSTRING32:
1756 case LB_FINDSTRING32:
1757 case LB_FINDSTRINGEXACT32:
1758 case LB_INSERTSTRING32:
1759 case LB_SELECTSTRING32:
1760 case LB_DIR32:
1761 case LB_ADDFILE32:
1763 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1764 if (!str) return -1;
1765 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1766 *plparam = (LPARAM)SEGPTR_GET(str);
1768 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1769 return 1;
1771 case CB_ADDSTRING32:
1772 case CB_FINDSTRING32:
1773 case CB_FINDSTRINGEXACT32:
1774 case CB_INSERTSTRING32:
1775 case CB_SELECTSTRING32:
1776 case CB_DIR32:
1778 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1779 if (!str) return -1;
1780 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1781 *plparam = (LPARAM)SEGPTR_GET(str);
1783 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING32);
1784 return 1;
1786 case WM_NCCREATE:
1787 case WM_CREATE:
1789 CREATESTRUCT16 *cs;
1790 CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
1791 LPSTR name, cls;
1793 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1794 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
1795 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
1796 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
1797 cs->lpszName = SEGPTR_GET(name);
1798 cs->lpszClass = SEGPTR_GET(cls);
1799 *pmsg16 = (UINT16)msg32;
1800 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1801 *plparam = (LPARAM)SEGPTR_GET(cs);
1803 return 1;
1804 case WM_MDICREATE:
1806 MDICREATESTRUCT16 *cs;
1807 MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
1808 LPSTR name, cls;
1810 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1811 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
1812 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
1813 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
1814 cs->szTitle = SEGPTR_GET(name);
1815 cs->szClass = SEGPTR_GET(cls);
1816 *pmsg16 = (UINT16)msg32;
1817 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1818 *plparam = (LPARAM)SEGPTR_GET(cs);
1820 return 1;
1821 case WM_SETTEXT:
1823 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1824 if (!str) return -1;
1825 *pmsg16 = (UINT16)msg32;
1826 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1827 *plparam = (LPARAM)SEGPTR_GET(str);
1829 return 1;
1830 default: /* No Unicode translation needed */
1831 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
1832 pwparam16, plparam );
1837 /**********************************************************************
1838 * WINPROC_UnmapMsg32WTo16
1840 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1842 void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1843 MSGPARAM16* p16 )
1845 switch(msg)
1847 case WM_GETTEXT:
1849 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1850 p16->lParam = *((LPARAM *)str - 1);
1851 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
1852 SEGPTR_FREE( (LPARAM *)str - 1 );
1854 break;
1855 default:
1856 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, p16 );
1857 break;
1862 /**********************************************************************
1863 * WINPROC_CallProc32ATo32W
1865 * Call a window procedure, translating args from Ansi to Unicode.
1867 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
1868 UINT32 msg, WPARAM32 wParam,
1869 LPARAM lParam )
1871 LRESULT result;
1873 if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
1874 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1875 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1876 return result;
1880 /**********************************************************************
1881 * WINPROC_CallProc32WTo32A
1883 * Call a window procedure, translating args from Unicode to Ansi.
1885 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
1886 UINT32 msg, WPARAM32 wParam,
1887 LPARAM lParam )
1889 LRESULT result;
1891 if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
1892 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1893 WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
1894 return result;
1898 /**********************************************************************
1899 * WINPROC_CallProc16To32A
1901 * Call a 32-bit window procedure, translating the 16-bit args.
1903 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
1904 WPARAM16 wParam, LPARAM lParam,
1905 WNDPROC32 func )
1907 LRESULT result;
1908 UINT32 msg32;
1909 WPARAM32 wParam32;
1911 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1912 return 0;
1913 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1914 return WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam, result );
1918 /**********************************************************************
1919 * WINPROC_CallProc16To32W
1921 * Call a 32-bit window procedure, translating the 16-bit args.
1923 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
1924 WPARAM16 wParam, LPARAM lParam,
1925 WNDPROC32 func )
1927 LRESULT result;
1928 UINT32 msg32;
1929 WPARAM32 wParam32;
1931 if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1932 return 0;
1933 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1934 return WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam, result );
1938 /**********************************************************************
1939 * WINPROC_CallProc32ATo16
1941 * Call a 16-bit window procedure, translating the 32-bit args.
1943 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
1944 UINT32 msg, WPARAM32 wParam,
1945 LPARAM lParam )
1947 UINT16 msg16;
1948 MSGPARAM16 mp16;
1950 mp16.lParam = lParam;
1951 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
1952 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
1953 return 0;
1954 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1955 mp16.wParam, mp16.lParam );
1956 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, &mp16 );
1957 return mp16.lResult;
1961 /**********************************************************************
1962 * WINPROC_CallProc32WTo16
1964 * Call a 16-bit window procedure, translating the 32-bit args.
1966 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
1967 UINT32 msg, WPARAM32 wParam,
1968 LPARAM lParam )
1970 UINT16 msg16;
1971 MSGPARAM16 mp16;
1973 mp16.lParam = lParam;
1974 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
1975 &mp16.lParam ) == -1)
1976 return 0;
1977 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1978 mp16.wParam, mp16.lParam );
1979 WINPROC_UnmapMsg32WTo16( msg, wParam, lParam, &mp16 );
1980 return mp16.lResult;
1984 /**********************************************************************
1985 * CallWindowProc16 (USER.122)
1987 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
1988 WPARAM16 wParam, LPARAM lParam )
1990 WINDOWPROC *proc = WINPROC_GetPtr( func );
1992 if (!proc)
1993 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1995 #if testing
1996 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
1997 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1998 #endif
2000 switch(proc->type)
2002 case WIN_PROC_16:
2003 if (!proc->thunk.t_from32.proc) return 0;
2004 return Callbacks->CallWndProc( proc->thunk.t_from32.proc,
2005 hwnd, msg, wParam, lParam );
2006 case WIN_PROC_32A:
2007 if (!proc->thunk.t_from16.proc) return 0;
2008 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
2009 proc->thunk.t_from16.proc );
2010 case WIN_PROC_32W:
2011 if (!proc->thunk.t_from16.proc) return 0;
2012 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
2013 proc->thunk.t_from16.proc );
2014 default:
2015 WARN( relay, "Invalid proc %p\n", proc );
2016 return 0;
2021 /**********************************************************************
2022 * CallWindowProc32A (USER32.18)
2024 * The CallWindowProc() function invokes the windows procedure _func_,
2025 * with _hwnd_ as the target window, the message specified by _msg_, and
2026 * the message parameters _wParam_ and _lParam_.
2028 * Some kinds of argument conversion may be done, I'm not sure what.
2030 * CallWindowProc() may be used for windows subclassing. Use
2031 * SetWindowLong() to set a new windows procedure for windows of the
2032 * subclass, and handle subclassed messages in the new windows
2033 * procedure. The new windows procedure may then use CallWindowProc()
2034 * with _func_ set to the parent class's windows procedure to dispatch
2035 * the message to the superclass.
2037 * RETURNS
2039 * The return value is message dependent.
2041 * CONFORMANCE
2043 * ECMA-234, Win32
2045 LRESULT WINAPI CallWindowProc32A(
2046 WNDPROC32 func, /* window procedure */
2047 HWND32 hwnd, /* target window */
2048 UINT32 msg, /* message */
2049 WPARAM32 wParam, /* message dependent parameter */
2050 LPARAM lParam /* message dependent parameter */
2052 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2054 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2056 #if testing
2057 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2058 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2059 #endif
2061 switch(proc->type)
2063 case WIN_PROC_16:
2064 if (!proc->thunk.t_from32.proc) return 0;
2065 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2066 hwnd, msg, wParam, lParam );
2067 case WIN_PROC_32A:
2068 if (!proc->thunk.t_from16.proc) return 0;
2069 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
2070 hwnd, msg, wParam, lParam );
2071 case WIN_PROC_32W:
2072 if (!proc->thunk.t_from16.proc) return 0;
2073 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2074 hwnd, msg, wParam, lParam );
2075 default:
2076 WARN( relay, "Invalid proc %p\n", proc );
2077 return 0;
2082 /**********************************************************************
2083 * CallWindowProc32W (USER32.19)
2085 LRESULT WINAPI CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
2086 WPARAM32 wParam, LPARAM lParam )
2088 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2090 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2092 #if testing
2093 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2094 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2095 #endif
2097 switch(proc->type)
2099 case WIN_PROC_16:
2100 if (!proc->thunk.t_from32.proc) return 0;
2101 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2102 hwnd, msg, wParam, lParam );
2103 case WIN_PROC_32A:
2104 if (!proc->thunk.t_from16.proc) return 0;
2105 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2106 hwnd, msg, wParam, lParam );
2107 case WIN_PROC_32W:
2108 if (!proc->thunk.t_from16.proc) return 0;
2109 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
2110 hwnd, msg, wParam, lParam );
2111 default:
2112 WARN( relay, "Invalid proc %p\n", proc );
2113 return 0;