Small fix.
[wine/multimedia.git] / windows / winproc.c
blobe6ddfed12c7b52a3b1bd1c3ed2c1c1fa46b9f373
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 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
804 return 0;
805 case WM_MDICREATE:
807 MDICREATESTRUCT16 *cs16 =
808 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
809 MDICREATESTRUCT32A *cs =
810 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
811 sizeof(*cs) + sizeof(LPARAM) );
812 if (!cs) return -1;
813 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
814 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
815 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
816 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
817 *plparam = (LPARAM)cs;
819 return 1;
820 case WM_MDIGETACTIVE:
821 *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL32) );
822 return 1;
823 case WM_MDISETMENU:
824 if(wParam16==TRUE)
825 *pmsg32=WM_MDIREFRESHMENU;
826 *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
827 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
828 return 0;
829 case WM_MENUCHAR:
830 case WM_MENUSELECT:
831 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
832 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
833 return 0;
834 case WM_MDIACTIVATE:
835 if( *plparam )
837 *pwparam32 = (WPARAM32)(HWND32)HIWORD(*plparam);
838 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
840 else /* message sent to MDI client */
841 *pwparam32 = wParam16;
842 return 0;
843 case WM_NCCALCSIZE:
845 NCCALCSIZE_PARAMS16 *nc16;
846 NCCALCSIZE_PARAMS32 *nc;
848 nc = (NCCALCSIZE_PARAMS32 *)HeapAlloc( SystemHeap, 0,
849 sizeof(*nc) + sizeof(LPARAM) );
850 if (!nc) return -1;
851 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
852 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
853 if (wParam16)
855 nc->lppos = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
856 sizeof(*nc->lppos) );
857 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
858 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
859 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
861 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
862 *plparam = (LPARAM)nc;
864 return 1;
865 case WM_NCCREATE:
866 case WM_CREATE:
868 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
869 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
870 sizeof(*cs) + sizeof(LPARAM) );
871 if (!cs) return -1;
872 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
873 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
874 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
875 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
876 *plparam = (LPARAM)cs;
878 return 1;
879 case WM_PARENTNOTIFY:
880 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
882 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
883 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
885 return 0;
886 case WM_SETTEXT:
887 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
888 return 0;
889 case WM_WINDOWPOSCHANGING:
890 case WM_WINDOWPOSCHANGED:
892 WINDOWPOS32 *wp = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
893 sizeof(*wp) + sizeof(LPARAM) );
894 if (!wp) return -1;
895 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
896 wp );
897 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
898 *plparam = (LPARAM)wp;
900 return 1;
901 case WM_NOTIFY:
902 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
903 return 1;
904 case WM_ASKCBFORMATNAME:
905 case WM_DEVMODECHANGE:
906 case WM_PAINTCLIPBOARD:
907 case WM_SIZECLIPBOARD:
908 case WM_WININICHANGE:
909 FIXME( msg, "message %04x needs translation\n",msg16 );
910 return -1;
912 default: /* No translation needed */
913 return 0;
918 /**********************************************************************
919 * WINPROC_UnmapMsg16To32A
921 * Unmap a message that was mapped from 16- to 32-bit Ansi.
923 LRESULT WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
924 LRESULT result )
926 switch(msg)
928 case WM_COMPAREITEM:
929 case WM_DELETEITEM:
930 case WM_DRAWITEM:
931 HeapFree( SystemHeap, 0, (LPVOID)lParam );
932 break;
933 case WM_MEASUREITEM:
935 MEASUREITEMSTRUCT16 *mis16;
936 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)lParam;
937 lParam = *(LPARAM *)(mis + 1);
938 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
939 mis16->itemWidth = (UINT16)mis->itemWidth;
940 mis16->itemHeight = (UINT16)mis->itemHeight;
941 HeapFree( SystemHeap, 0, mis );
943 break;
944 case WM_GETMINMAXINFO:
946 MINMAXINFO32 *mmi = (MINMAXINFO32 *)lParam;
947 lParam = *(LPARAM *)(mmi + 1);
948 STRUCT32_MINMAXINFO32to16( mmi,
949 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
950 HeapFree( SystemHeap, 0, mmi );
952 break;
953 case WM_MDICREATE:
955 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
956 lParam = *(LPARAM *)(cs + 1);
957 STRUCT32_MDICREATESTRUCT32Ato16( cs,
958 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
959 HeapFree( SystemHeap, 0, cs );
961 break;
962 case WM_MDIGETACTIVE:
963 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL32 *)lParam) );
964 HeapFree( SystemHeap, 0, (BOOL32 *)lParam );
965 break;
966 case WM_NCCALCSIZE:
968 NCCALCSIZE_PARAMS16 *nc16;
969 NCCALCSIZE_PARAMS32 *nc = (NCCALCSIZE_PARAMS32 *)lParam;
970 lParam = *(LPARAM *)(nc + 1);
971 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
972 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
973 if (wParam)
975 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
976 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
977 if (nc->lppos)
979 STRUCT32_WINDOWPOS32to16( nc->lppos,
980 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
981 HeapFree( SystemHeap, 0, nc->lppos );
984 HeapFree( SystemHeap, 0, nc );
986 break;
987 case WM_NCCREATE:
988 case WM_CREATE:
990 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
991 lParam = *(LPARAM *)(cs + 1);
992 STRUCT32_CREATESTRUCT32Ato16( cs,
993 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
994 HeapFree( SystemHeap, 0, cs );
996 break;
997 case WM_WINDOWPOSCHANGING:
998 case WM_WINDOWPOSCHANGED:
1000 WINDOWPOS32 *wp = (WINDOWPOS32 *)lParam;
1001 lParam = *(LPARAM *)(wp + 1);
1002 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
1003 HeapFree( SystemHeap, 0, wp );
1005 break;
1007 return result;
1011 /**********************************************************************
1012 * WINPROC_MapMsg16To32W
1014 * Map a message from 16- to 32-bit Unicode.
1015 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1017 INT32 WINPROC_MapMsg16To32W( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
1018 WPARAM32 *pwparam32, LPARAM *plparam )
1020 switch(msg16)
1022 case WM_GETTEXT:
1023 case WM_SETTEXT:
1024 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1025 return WINPROC_MapMsg32ATo32W( *pmsg32, *pwparam32, plparam );
1026 case WM_NCCREATE:
1027 case WM_CREATE:
1029 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1030 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
1031 sizeof(*cs) + sizeof(LPARAM) );
1032 if (!cs) return -1;
1033 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCT32A *)cs );
1034 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1035 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1036 if (HIWORD(cs->lpszName))
1037 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
1038 (LPCSTR)cs->lpszName );
1039 if (HIWORD(cs->lpszClass))
1040 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
1041 (LPCSTR)cs->lpszClass );
1042 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1043 *plparam = (LPARAM)cs;
1045 return 1;
1046 case WM_MDICREATE:
1048 MDICREATESTRUCT16 *cs16 =
1049 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1050 MDICREATESTRUCT32W *cs =
1051 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
1052 sizeof(*cs) + sizeof(LPARAM) );
1053 if (!cs) return -1;
1054 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCT32A *)cs );
1055 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1056 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
1057 if (HIWORD(cs->szTitle))
1058 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
1059 (LPCSTR)cs->szTitle );
1060 if (HIWORD(cs->szClass))
1061 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
1062 (LPCSTR)cs->szClass );
1063 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1064 *plparam = (LPARAM)cs;
1066 return 1;
1067 default: /* No Unicode translation needed */
1068 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1069 pwparam32, plparam );
1074 /**********************************************************************
1075 * WINPROC_UnmapMsg16To32W
1077 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1079 LRESULT WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1080 LRESULT result )
1082 switch(msg)
1084 case WM_GETTEXT:
1085 case WM_SETTEXT:
1086 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1087 break;
1088 case WM_NCCREATE:
1089 case WM_CREATE:
1091 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
1092 lParam = *(LPARAM *)(cs + 1);
1093 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
1094 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1095 if (HIWORD(cs->lpszName))
1096 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1097 if (HIWORD(cs->lpszClass))
1098 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1099 HeapFree( SystemHeap, 0, cs );
1101 break;
1102 case WM_MDICREATE:
1104 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
1105 lParam = *(LPARAM *)(cs + 1);
1106 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
1107 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1108 if (HIWORD(cs->szTitle))
1109 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1110 if (HIWORD(cs->szClass))
1111 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1112 HeapFree( SystemHeap, 0, cs );
1114 break;
1115 default:
1116 return WINPROC_UnmapMsg16To32A( msg, wParam, lParam, result );
1118 return result;
1122 /**********************************************************************
1123 * WINPROC_MapMsg32ATo16
1125 * Map a message from 32-bit Ansi to 16-bit.
1126 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1128 INT32 WINPROC_MapMsg32ATo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1129 UINT16 *pmsg16, WPARAM16 *pwparam16,
1130 LPARAM *plparam )
1132 *pmsg16 = (UINT16)msg32;
1133 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1134 switch(msg32)
1136 case BM_GETCHECK32:
1137 case BM_SETCHECK32:
1138 case BM_GETSTATE32:
1139 case BM_SETSTATE32:
1140 case BM_SETSTYLE32:
1141 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK32);
1142 return 0;
1144 case EM_GETSEL32:
1145 case EM_GETRECT32:
1146 case EM_SETRECT32:
1147 case EM_SETRECTNP32:
1148 case EM_SCROLL32:
1149 case EM_LINESCROLL32:
1150 case EM_SCROLLCARET32:
1151 case EM_GETMODIFY32:
1152 case EM_SETMODIFY32:
1153 case EM_GETLINECOUNT32:
1154 case EM_LINEINDEX32:
1155 case EM_SETHANDLE32:
1156 case EM_GETHANDLE32:
1157 case EM_GETTHUMB32:
1158 case EM_LINELENGTH32:
1159 case EM_REPLACESEL32:
1160 case EM_GETLINE32:
1161 case EM_LIMITTEXT32:
1162 case EM_CANUNDO32:
1163 case EM_UNDO32:
1164 case EM_FMTLINES32:
1165 case EM_LINEFROMCHAR32:
1166 case EM_SETTABSTOPS32:
1167 case EM_SETPASSWORDCHAR32:
1168 case EM_EMPTYUNDOBUFFER32:
1169 case EM_GETFIRSTVISIBLELINE32:
1170 case EM_SETREADONLY32:
1171 case EM_SETWORDBREAKPROC32:
1172 case EM_GETWORDBREAKPROC32:
1173 case EM_GETPASSWORDCHAR32:
1174 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL32);
1175 return 0;
1177 case LB_CARETOFF32:
1178 case LB_CARETON32:
1179 case LB_DELETESTRING32:
1180 case LB_GETANCHORINDEX32:
1181 case LB_GETCARETINDEX32:
1182 case LB_GETCOUNT32:
1183 case LB_GETCURSEL32:
1184 case LB_GETHORIZONTALEXTENT32:
1185 case LB_GETITEMDATA32:
1186 case LB_GETITEMHEIGHT32:
1187 case LB_GETSEL32:
1188 case LB_GETSELCOUNT32:
1189 case LB_GETTEXTLEN32:
1190 case LB_GETTOPINDEX32:
1191 case LB_RESETCONTENT32:
1192 case LB_SELITEMRANGE32:
1193 case LB_SELITEMRANGEEX32:
1194 case LB_SETANCHORINDEX32:
1195 case LB_SETCARETINDEX32:
1196 case LB_SETCOLUMNWIDTH32:
1197 case LB_SETCURSEL32:
1198 case LB_SETHORIZONTALEXTENT32:
1199 case LB_SETITEMDATA32:
1200 case LB_SETITEMHEIGHT32:
1201 case LB_SETSEL32:
1202 case LB_SETTOPINDEX32:
1203 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1204 return 0;
1205 case CB_DELETESTRING32:
1206 case CB_GETCOUNT32:
1207 case CB_GETLBTEXTLEN32:
1208 case CB_LIMITTEXT32:
1209 case CB_RESETCONTENT32:
1210 case CB_SETEDITSEL32:
1211 case CB_GETCURSEL32:
1212 case CB_SETCURSEL32:
1213 case CB_SHOWDROPDOWN32:
1214 case CB_SETITEMDATA32:
1215 case CB_SETITEMHEIGHT32:
1216 case CB_GETITEMHEIGHT32:
1217 case CB_SETEXTENDEDUI32:
1218 case CB_GETEXTENDEDUI32:
1219 case CB_GETDROPPEDSTATE32:
1220 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1221 return 0;
1222 case CB_GETEDITSEL32:
1223 *pmsg16 = CB_GETEDITSEL16;
1224 return 1;
1226 case LB_ADDSTRING32:
1227 case LB_FINDSTRING32:
1228 case LB_FINDSTRINGEXACT32:
1229 case LB_INSERTSTRING32:
1230 case LB_SELECTSTRING32:
1231 case LB_DIR32:
1232 case LB_ADDFILE32:
1234 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1235 if (!str) return -1;
1236 *plparam = (LPARAM)SEGPTR_GET(str);
1238 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1239 return 1;
1241 case CB_ADDSTRING32:
1242 case CB_FINDSTRING32:
1243 case CB_FINDSTRINGEXACT32:
1244 case CB_INSERTSTRING32:
1245 case CB_SELECTSTRING32:
1246 case CB_DIR32:
1248 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1249 if (!str) return -1;
1250 *plparam = (LPARAM)SEGPTR_GET(str);
1252 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1253 return 1;
1255 case LB_GETITEMRECT32:
1257 RECT16 *rect;
1258 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1259 if (!rect) return -1;
1260 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1261 *plparam = (LPARAM)SEGPTR_GET(rect);
1263 *pmsg16 = LB_GETITEMRECT16;
1264 return 1;
1265 case LB_GETSELITEMS32:
1267 LPINT16 items;
1268 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1269 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1270 + sizeof(LPARAM)))) return -1;
1271 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1272 *plparam = (LPARAM)SEGPTR_GET(items);
1274 *pmsg16 = LB_GETSELITEMS16;
1275 return 1;
1276 case LB_SETTABSTOPS32:
1277 if (wParam32)
1279 INT32 i;
1280 LPINT16 stops;
1281 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1282 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1283 + sizeof(LPARAM)))) return -1;
1284 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT32)*plparam+i);
1285 *plparam = (LPARAM)SEGPTR_GET(stops);
1286 return 1;
1288 *pmsg16 = LB_SETTABSTOPS16;
1289 return 0;
1291 case CB_GETDROPPEDCONTROLRECT32:
1293 RECT16 *rect;
1294 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1295 if (!rect) return -1;
1296 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1297 *plparam = (LPARAM)SEGPTR_GET(rect);
1299 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1300 return 1;
1302 case LB_GETTEXT32:
1303 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1304 *pmsg16 = LB_GETTEXT16;
1305 return 1;
1307 case CB_GETLBTEXT32:
1308 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1309 *pmsg16 = CB_GETLBTEXT16;
1310 return 1;
1312 case EM_SETSEL32:
1313 *pwparam16 = 0;
1314 *plparam = MAKELONG( (INT16)(INT32)wParam32, (INT16)*plparam );
1315 *pmsg16 = EM_SETSEL16;
1316 return 0;
1318 case WM_ACTIVATE:
1319 case WM_CHARTOITEM:
1320 case WM_COMMAND:
1321 case WM_VKEYTOITEM:
1322 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1323 return 0;
1324 case WM_HSCROLL:
1325 case WM_VSCROLL:
1326 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1327 return 0;
1328 case WM_CTLCOLORMSGBOX:
1329 case WM_CTLCOLOREDIT:
1330 case WM_CTLCOLORLISTBOX:
1331 case WM_CTLCOLORBTN:
1332 case WM_CTLCOLORDLG:
1333 case WM_CTLCOLORSCROLLBAR:
1334 case WM_CTLCOLORSTATIC:
1335 *pmsg16 = WM_CTLCOLOR;
1336 *plparam = MAKELPARAM( (HWND16)*plparam,
1337 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1338 return 0;
1339 case WM_COMPAREITEM:
1341 COMPAREITEMSTRUCT32 *cis32 = (COMPAREITEMSTRUCT32 *)*plparam;
1342 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1343 if (!cis) return -1;
1344 cis->CtlType = (UINT16)cis32->CtlType;
1345 cis->CtlID = (UINT16)cis32->CtlID;
1346 cis->hwndItem = (HWND16)cis32->hwndItem;
1347 cis->itemID1 = (UINT16)cis32->itemID1;
1348 cis->itemData1 = cis32->itemData1;
1349 cis->itemID2 = (UINT16)cis32->itemID2;
1350 cis->itemData2 = cis32->itemData2;
1351 *plparam = (LPARAM)SEGPTR_GET(cis);
1353 return 1;
1354 case WM_DELETEITEM:
1356 DELETEITEMSTRUCT32 *dis32 = (DELETEITEMSTRUCT32 *)*plparam;
1357 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1358 if (!dis) return -1;
1359 dis->CtlType = (UINT16)dis32->CtlType;
1360 dis->CtlID = (UINT16)dis32->CtlID;
1361 dis->itemID = (UINT16)dis32->itemID;
1362 dis->hwndItem = (HWND16)dis32->hwndItem;
1363 dis->itemData = dis32->itemData;
1364 *plparam = (LPARAM)SEGPTR_GET(dis);
1366 return 1;
1367 case WM_DRAWITEM:
1369 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)*plparam;
1370 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1371 if (!dis) return -1;
1372 dis->CtlType = (UINT16)dis32->CtlType;
1373 dis->CtlID = (UINT16)dis32->CtlID;
1374 dis->itemID = (UINT16)dis32->itemID;
1375 dis->itemAction = (UINT16)dis32->itemAction;
1376 dis->itemState = (UINT16)dis32->itemState;
1377 dis->hwndItem = (HWND16)dis32->hwndItem;
1378 dis->hDC = (HDC16)dis32->hDC;
1379 dis->itemData = dis32->itemData;
1380 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1381 *plparam = (LPARAM)SEGPTR_GET(dis);
1383 return 1;
1384 case WM_MEASUREITEM:
1386 MEASUREITEMSTRUCT32 *mis32 = (MEASUREITEMSTRUCT32 *)*plparam;
1387 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1388 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1389 if (!mis) return -1;
1390 mis->CtlType = (UINT16)mis32->CtlType;
1391 mis->CtlID = (UINT16)mis32->CtlID;
1392 mis->itemID = (UINT16)mis32->itemID;
1393 mis->itemWidth = (UINT16)mis32->itemWidth;
1394 mis->itemHeight = (UINT16)mis32->itemHeight;
1395 mis->itemData = mis32->itemData;
1396 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1397 *plparam = (LPARAM)SEGPTR_GET(mis);
1399 return 1;
1400 case WM_GETMINMAXINFO:
1402 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1403 sizeof(LPARAM) );
1404 if (!mmi) return -1;
1405 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)*plparam, mmi );
1406 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1407 *plparam = (LPARAM)SEGPTR_GET(mmi);
1409 return 1;
1410 case WM_GETTEXT:
1412 LPSTR str;
1413 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1414 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1415 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1416 *plparam = (LPARAM)SEGPTR_GET(str);
1418 return 1;
1419 case WM_MDICREATE:
1421 MDICREATESTRUCT16 *cs;
1422 MDICREATESTRUCT32A *cs32 = (MDICREATESTRUCT32A *)*plparam;
1423 LPSTR name, cls;
1425 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1426 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1427 name = SEGPTR_STRDUP( cs32->szTitle );
1428 cls = SEGPTR_STRDUP( cs32->szClass );
1429 cs->szTitle = SEGPTR_GET(name);
1430 cs->szClass = SEGPTR_GET(cls);
1431 *plparam = (LPARAM)SEGPTR_GET(cs);
1433 return 1;
1434 case WM_MDIGETACTIVE:
1435 return 1;
1436 case WM_MDISETMENU:
1437 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1438 (HMENU16)LOWORD(*plparam) );
1439 *pwparam16 = (*plparam == 0);
1440 return 0;
1441 case WM_MENUCHAR:
1442 case WM_MENUSELECT:
1443 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1444 return 0;
1445 case WM_MDIACTIVATE:
1446 if( WIDGETS_IsControl32(WIN_FindWndPtr(hwnd), BIC32_MDICLIENT) )
1448 *pwparam16 = (HWND32)wParam32;
1449 *plparam = 0;
1451 else
1453 *pwparam16 = ((HWND32)*plparam == hwnd);
1454 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1455 (HWND16)LOWORD(wParam32) );
1457 return 0;
1458 case WM_NCCALCSIZE:
1460 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
1461 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1462 if (!nc) return -1;
1464 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1465 if (wParam32)
1467 WINDOWPOS16 *wp;
1468 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1469 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1470 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1472 SEGPTR_FREE(nc);
1473 return -1;
1475 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1476 nc->lppos = SEGPTR_GET(wp);
1478 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1479 *plparam = (LPARAM)SEGPTR_GET(nc);
1481 return 1;
1482 case WM_NCCREATE:
1483 case WM_CREATE:
1485 CREATESTRUCT16 *cs;
1486 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)*plparam;
1487 LPSTR name, cls;
1489 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1490 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1491 name = SEGPTR_STRDUP( cs32->lpszName );
1492 cls = SEGPTR_STRDUP( cs32->lpszClass );
1493 cs->lpszName = SEGPTR_GET(name);
1494 cs->lpszClass = SEGPTR_GET(cls);
1495 *plparam = (LPARAM)SEGPTR_GET(cs);
1497 return 1;
1498 case WM_PARENTNOTIFY:
1499 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1500 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1501 /* else nothing to do */
1502 return 0;
1503 case WM_NOTIFY:
1504 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
1505 return 1;
1506 case WM_SETTEXT:
1508 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1509 if (!str) return -1;
1510 *plparam = (LPARAM)SEGPTR_GET(str);
1512 return 1;
1513 case WM_WINDOWPOSCHANGING:
1514 case WM_WINDOWPOSCHANGED:
1516 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1517 sizeof(LPARAM) );
1518 if (!wp) return -1;
1519 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)*plparam, wp );
1520 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1521 *plparam = (LPARAM)SEGPTR_GET(wp);
1523 return 1;
1524 case WM_ASKCBFORMATNAME:
1525 case WM_DEVMODECHANGE:
1526 case WM_PAINTCLIPBOARD:
1527 case WM_SIZECLIPBOARD:
1528 case WM_WININICHANGE:
1529 WARN( msg, "message %04x needs translation\n", msg32 );
1530 return -1;
1532 default: /* No translation needed */
1533 return 0;
1538 /**********************************************************************
1539 * WINPROC_UnmapMsg32ATo16
1541 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1543 void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1544 MSGPARAM16* p16 )
1546 switch(msg)
1548 case LB_ADDFILE32:
1549 case LB_ADDSTRING32:
1550 case LB_DIR32:
1551 case LB_FINDSTRING32:
1552 case LB_FINDSTRINGEXACT32:
1553 case LB_INSERTSTRING32:
1554 case LB_SELECTSTRING32:
1555 case LB_SETTABSTOPS32:
1556 case CB_ADDSTRING32:
1557 case CB_FINDSTRING32:
1558 case CB_FINDSTRINGEXACT32:
1559 case CB_INSERTSTRING32:
1560 case CB_SELECTSTRING32:
1561 case CB_DIR32:
1562 case WM_COMPAREITEM:
1563 case WM_DELETEITEM:
1564 case WM_DRAWITEM:
1565 case WM_SETTEXT:
1566 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1567 break;
1569 case CB_GETDROPPEDCONTROLRECT32:
1570 case LB_GETITEMRECT32:
1572 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1573 p16->lParam = *(LPARAM *)(rect + 1);
1574 CONV_RECT16TO32( rect, (RECT32 *)(p16->lParam));
1575 SEGPTR_FREE( rect );
1577 break;
1578 case LB_GETSELITEMS32:
1580 INT32 i;
1581 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1582 p16->lParam = *((LPARAM *)items - 1);
1583 for (i = 0; i < p16->wParam; i++) *((LPINT32)(p16->lParam) + i) = items[i];
1584 SEGPTR_FREE( (LPARAM *)items - 1 );
1586 break;
1588 case CB_GETEDITSEL32:
1589 if( wParam )
1590 *((LPUINT32)(wParam)) = LOWORD(p16->lResult);
1591 if( lParam )
1592 *((LPUINT32)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1593 break;
1595 case LB_GETTEXT32:
1596 case CB_GETLBTEXT32:
1597 UnMapLS( (SEGPTR)(p16->lParam) );
1598 break;
1600 case WM_MEASUREITEM:
1602 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1603 MEASUREITEMSTRUCT32 *mis32 = *(MEASUREITEMSTRUCT32 **)(mis + 1);
1604 mis32->itemWidth = mis->itemWidth;
1605 mis32->itemHeight = mis->itemHeight;
1606 SEGPTR_FREE(mis);
1608 break;
1609 case WM_GETMINMAXINFO:
1611 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1612 p16->lParam = *(LPARAM *)(mmi + 1);
1613 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)(p16->lParam) );
1614 SEGPTR_FREE(mmi);
1616 break;
1617 case WM_GETTEXT:
1619 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1620 p16->lParam = *((LPARAM *)str - 1);
1621 lstrcpyn32A( (LPSTR)(p16->lParam), str, p16->wParam );
1622 SEGPTR_FREE( (LPARAM *)str - 1 );
1624 break;
1625 case WM_MDICREATE:
1627 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1628 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1629 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1630 SEGPTR_FREE( cs );
1632 break;
1633 case WM_MDIGETACTIVE:
1634 if (lParam) *(BOOL32 *)lParam = (BOOL16)HIWORD(p16->lResult);
1635 p16->lResult = (HWND32)LOWORD(p16->lResult);
1636 break;
1637 case WM_NCCALCSIZE:
1639 NCCALCSIZE_PARAMS32 *nc32;
1640 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
1641 p16->lParam = *(LPARAM *)(nc + 1);
1642 nc32 = (NCCALCSIZE_PARAMS32 *)(p16->lParam);
1643 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1644 if (p16->wParam)
1646 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1647 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1648 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1649 nc32->lppos );
1650 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1652 SEGPTR_FREE(nc);
1654 break;
1655 case WM_NCCREATE:
1656 case WM_CREATE:
1658 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1659 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1660 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1661 SEGPTR_FREE( cs );
1663 break;
1664 case WM_WINDOWPOSCHANGING:
1665 case WM_WINDOWPOSCHANGED:
1667 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
1668 p16->lParam = *(LPARAM *)(wp + 1);
1669 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)p16->lParam );
1670 SEGPTR_FREE(wp);
1672 break;
1673 case WM_NOTIFY:
1674 UnMapLS(p16->lParam);
1675 break;
1680 /**********************************************************************
1681 * WINPROC_MapMsg32WTo16
1683 * Map a message from 32-bit Unicode to 16-bit.
1684 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1686 INT32 WINPROC_MapMsg32WTo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1687 UINT16 *pmsg16, WPARAM16 *pwparam16,
1688 LPARAM *plparam )
1690 switch(msg32)
1692 case LB_ADDSTRING32:
1693 case LB_FINDSTRING32:
1694 case LB_FINDSTRINGEXACT32:
1695 case LB_INSERTSTRING32:
1696 case LB_SELECTSTRING32:
1697 case LB_DIR32:
1698 case LB_ADDFILE32:
1700 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1701 if (!str) return -1;
1702 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1703 *plparam = (LPARAM)SEGPTR_GET(str);
1705 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1706 return 1;
1708 case CB_ADDSTRING32:
1709 case CB_FINDSTRING32:
1710 case CB_FINDSTRINGEXACT32:
1711 case CB_INSERTSTRING32:
1712 case CB_SELECTSTRING32:
1713 case CB_DIR32:
1715 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1716 if (!str) return -1;
1717 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1718 *plparam = (LPARAM)SEGPTR_GET(str);
1720 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING32);
1721 return 1;
1723 case WM_NCCREATE:
1724 case WM_CREATE:
1726 CREATESTRUCT16 *cs;
1727 CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
1728 LPSTR name, cls;
1730 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1731 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
1732 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
1733 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
1734 cs->lpszName = SEGPTR_GET(name);
1735 cs->lpszClass = SEGPTR_GET(cls);
1736 *pmsg16 = (UINT16)msg32;
1737 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1738 *plparam = (LPARAM)SEGPTR_GET(cs);
1740 return 1;
1741 case WM_MDICREATE:
1743 MDICREATESTRUCT16 *cs;
1744 MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
1745 LPSTR name, cls;
1747 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1748 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
1749 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
1750 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
1751 cs->szTitle = SEGPTR_GET(name);
1752 cs->szClass = SEGPTR_GET(cls);
1753 *pmsg16 = (UINT16)msg32;
1754 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1755 *plparam = (LPARAM)SEGPTR_GET(cs);
1757 return 1;
1758 case WM_SETTEXT:
1760 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1761 if (!str) return -1;
1762 *pmsg16 = (UINT16)msg32;
1763 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1764 *plparam = (LPARAM)SEGPTR_GET(str);
1766 return 1;
1767 default: /* No Unicode translation needed */
1768 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
1769 pwparam16, plparam );
1774 /**********************************************************************
1775 * WINPROC_UnmapMsg32WTo16
1777 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1779 void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1780 MSGPARAM16* p16 )
1782 switch(msg)
1784 case WM_GETTEXT:
1786 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1787 p16->lParam = *((LPARAM *)str - 1);
1788 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
1789 SEGPTR_FREE( (LPARAM *)str - 1 );
1791 break;
1792 default:
1793 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, p16 );
1794 break;
1799 /**********************************************************************
1800 * WINPROC_CallProc32ATo32W
1802 * Call a window procedure, translating args from Ansi to Unicode.
1804 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
1805 UINT32 msg, WPARAM32 wParam,
1806 LPARAM lParam )
1808 LRESULT result;
1810 if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
1811 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1812 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1813 return result;
1817 /**********************************************************************
1818 * WINPROC_CallProc32WTo32A
1820 * Call a window procedure, translating args from Unicode to Ansi.
1822 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
1823 UINT32 msg, WPARAM32 wParam,
1824 LPARAM lParam )
1826 LRESULT result;
1828 if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
1829 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1830 WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
1831 return result;
1835 /**********************************************************************
1836 * WINPROC_CallProc16To32A
1838 * Call a 32-bit window procedure, translating the 16-bit args.
1840 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
1841 WPARAM16 wParam, LPARAM lParam,
1842 WNDPROC32 func )
1844 LRESULT result;
1845 UINT32 msg32;
1846 WPARAM32 wParam32;
1848 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1849 return 0;
1850 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1851 return WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam, result );
1855 /**********************************************************************
1856 * WINPROC_CallProc16To32W
1858 * Call a 32-bit window procedure, translating the 16-bit args.
1860 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
1861 WPARAM16 wParam, LPARAM lParam,
1862 WNDPROC32 func )
1864 LRESULT result;
1865 UINT32 msg32;
1866 WPARAM32 wParam32;
1868 if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1869 return 0;
1870 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1871 return WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam, result );
1875 /**********************************************************************
1876 * WINPROC_CallProc32ATo16
1878 * Call a 16-bit window procedure, translating the 32-bit args.
1880 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
1881 UINT32 msg, WPARAM32 wParam,
1882 LPARAM lParam )
1884 UINT16 msg16;
1885 MSGPARAM16 mp16;
1887 mp16.lParam = lParam;
1888 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
1889 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
1890 return 0;
1891 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1892 mp16.wParam, mp16.lParam );
1893 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, &mp16 );
1894 return mp16.lResult;
1898 /**********************************************************************
1899 * WINPROC_CallProc32WTo16
1901 * Call a 16-bit window procedure, translating the 32-bit args.
1903 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
1904 UINT32 msg, WPARAM32 wParam,
1905 LPARAM lParam )
1907 UINT16 msg16;
1908 MSGPARAM16 mp16;
1910 mp16.lParam = lParam;
1911 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
1912 &mp16.lParam ) == -1)
1913 return 0;
1914 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1915 mp16.wParam, mp16.lParam );
1916 WINPROC_UnmapMsg32WTo16( msg, wParam, lParam, &mp16 );
1917 return mp16.lResult;
1921 /**********************************************************************
1922 * CallWindowProc16 (USER.122)
1924 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
1925 WPARAM16 wParam, LPARAM lParam )
1927 WINDOWPROC *proc = WINPROC_GetPtr( func );
1929 if (!proc)
1930 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1932 #if testing
1933 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
1934 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1935 #endif
1937 switch(proc->type)
1939 case WIN_PROC_16:
1940 if (!proc->thunk.t_from32.proc) return 0;
1941 return Callbacks->CallWndProc( proc->thunk.t_from32.proc,
1942 hwnd, msg, wParam, lParam );
1943 case WIN_PROC_32A:
1944 if (!proc->thunk.t_from16.proc) return 0;
1945 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
1946 proc->thunk.t_from16.proc );
1947 case WIN_PROC_32W:
1948 if (!proc->thunk.t_from16.proc) return 0;
1949 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
1950 proc->thunk.t_from16.proc );
1951 default:
1952 WARN( relay, "Invalid proc %p\n", proc );
1953 return 0;
1958 /**********************************************************************
1959 * CallWindowProc32A (USER32.18)
1961 * The CallWindowProc() function invokes the windows procedure _func_,
1962 * with _hwnd_ as the target window, the message specified by _msg_, and
1963 * the message parameters _wParam_ and _lParam_.
1965 * Some kinds of argument conversion may be done, I'm not sure what.
1967 * CallWindowProc() may be used for windows subclassing. Use
1968 * SetWindowLong() to set a new windows procedure for windows of the
1969 * subclass, and handle subclassed messages in the new windows
1970 * procedure. The new windows procedure may then use CallWindowProc()
1971 * with _func_ set to the parent class's windows procedure to dispatch
1972 * the message to the superclass.
1974 * RETURNS
1976 * The return value is message dependent.
1978 * CONFORMANCE
1980 * ECMA-234, Win32
1982 LRESULT WINAPI CallWindowProc32A(
1983 WNDPROC32 func, /* window procedure */
1984 HWND32 hwnd, /* target window */
1985 UINT32 msg, /* message */
1986 WPARAM32 wParam, /* message dependent parameter */
1987 LPARAM lParam /* message dependent parameter */
1989 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1991 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1993 #if testing
1994 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
1995 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1996 #endif
1998 switch(proc->type)
2000 case WIN_PROC_16:
2001 if (!proc->thunk.t_from32.proc) return 0;
2002 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2003 hwnd, msg, wParam, lParam );
2004 case WIN_PROC_32A:
2005 if (!proc->thunk.t_from16.proc) return 0;
2006 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
2007 hwnd, msg, wParam, lParam );
2008 case WIN_PROC_32W:
2009 if (!proc->thunk.t_from16.proc) return 0;
2010 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2011 hwnd, msg, wParam, lParam );
2012 default:
2013 WARN( relay, "Invalid proc %p\n", proc );
2014 return 0;
2019 /**********************************************************************
2020 * CallWindowProc32W (USER32.19)
2022 LRESULT WINAPI CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
2023 WPARAM32 wParam, LPARAM lParam )
2025 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2027 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2029 #if testing
2030 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2031 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2032 #endif
2034 switch(proc->type)
2036 case WIN_PROC_16:
2037 if (!proc->thunk.t_from32.proc) return 0;
2038 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2039 hwnd, msg, wParam, lParam );
2040 case WIN_PROC_32A:
2041 if (!proc->thunk.t_from16.proc) return 0;
2042 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2043 hwnd, msg, wParam, lParam );
2044 case WIN_PROC_32W:
2045 if (!proc->thunk.t_from16.proc) return 0;
2046 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
2047 hwnd, msg, wParam, lParam );
2048 default:
2049 WARN( relay, "Invalid proc %p\n", proc );
2050 return 0;