Release 970509
[wine/multimedia.git] / windows / winproc.c
blob9e7e3b3a89dedd48e5b4b279eab06947b458734a
1 /*
2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
6 */
8 #include <stdio.h>
9 #include "windows.h"
10 #include "heap.h"
11 #include "selectors.h"
12 #include "stackframe.h"
13 #include "struct32.h"
14 #include "win.h"
15 #include "winproc.h"
16 #include "stddebug.h"
17 #include "debug.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 pushl_ebp; /* pushl %ebp */
46 BYTE pushl_name; /* pushl $name */
47 LPCSTR name WINE_PACKED;
48 BYTE pushl_thunk; /* pushl $thunkfrom32 */
49 void (*thunk32)() WINE_PACKED;
50 BYTE jmp; /* jmp relay (relative jump)*/
51 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
52 } WINPROC_THUNK_FROM32;
54 /* Simple jmp to call 32-bit procedure directly */
55 typedef struct
57 BYTE jmp; /* jmp proc (relative jump) */
58 WNDPROC32 proc WINE_PACKED;
59 } WINPROC_JUMP;
61 typedef union
63 WINPROC_THUNK_FROM16 t_from16;
64 WINPROC_THUNK_FROM32 t_from32;
65 } WINPROC_THUNK;
67 typedef struct tagWINDOWPROC
69 WINPROC_THUNK thunk; /* Thunk */
70 WINPROC_JUMP jmp; /* Jump */
71 struct tagWINDOWPROC *next; /* Next window proc */
72 UINT32 magic; /* Magic number */
73 WINDOWPROCTYPE type; /* Function type */
74 WINDOWPROCUSER user; /* Function user */
75 } WINDOWPROC;
77 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
79 #define WINPROC_THUNKPROC(pproc) \
80 (((pproc)->type == WIN_PROC_16) ? \
81 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
82 (WNDPROC16)((pproc)->thunk.t_from16.proc))
84 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
85 WPARAM16 wParam, LPARAM lParam,
86 WNDPROC32 func );
87 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
88 WPARAM16 wParam, LPARAM lParam,
89 WNDPROC32 func );
90 static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
91 UINT32 msg, WPARAM32 wParam,
92 LPARAM lParam );
93 static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
94 UINT32 msg, WPARAM32 wParam,
95 LPARAM lParam );
97 extern void CallFrom16_long_wwwll(void);
98 extern void CallFrom32_stdcall_5(void);
100 static HANDLE32 WinProcHeap;
102 static LRESULT WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, UINT16 msg,
103 WPARAM16 wParam, LPARAM lParam );
104 static LRESULT WINPROC_CallWndProc32( WNDPROC32 proc, HWND32 hwnd, UINT32 msg,
105 WPARAM32 wParam, LPARAM lParam );
107 static WINPROC_CALLWNDPROC16 WINPROC_CallWndProc16Ptr = WINPROC_CallWndProc16;
108 static WINPROC_CALLWNDPROC32 WINPROC_CallWndProc32Ptr = WINPROC_CallWndProc32;
111 /**********************************************************************
112 * WINPROC_Init
114 BOOL32 WINPROC_Init(void)
116 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
117 if (!WinProcHeap)
119 fprintf( stderr, "Unable to create winproc heap\n" );
120 return FALSE;
122 return TRUE;
126 /**********************************************************************
127 * WINPROC_CallWndProc16
129 * Call a 16-bit WndProc.
131 static LRESULT WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, UINT16 msg,
132 WPARAM16 wParam, LPARAM lParam )
134 return proc( hwnd, msg, wParam, lParam );
138 /**********************************************************************
139 * WINPROC_CallWndProc32
141 * Call a 32-bit WndProc.
143 static LRESULT WINPROC_CallWndProc32( WNDPROC32 proc, HWND32 hwnd, UINT32 msg,
144 WPARAM32 wParam, LPARAM lParam )
146 return proc( hwnd, msg, wParam, lParam );
150 /**********************************************************************
151 * WINPROC_SetCallWndProc16
153 void WINPROC_SetCallWndProc16( WINPROC_CALLWNDPROC16 proc )
155 WINPROC_CallWndProc16Ptr = proc;
159 /**********************************************************************
160 * WINPROC_SetCallWndProc32
162 void WINPROC_SetCallWndProc32( WINPROC_CALLWNDPROC32 proc )
164 WINPROC_CallWndProc32Ptr = proc;
168 /**********************************************************************
169 * WINPROC_GetPtr
171 * Return a pointer to the win proc.
173 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
175 BYTE *ptr;
176 WINDOWPROC *proc;
178 /* Check for a linear pointer */
180 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
182 ptr = (BYTE *)handle;
183 /* First check if it is the jmp address */
184 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
185 (int)&((WINDOWPROC *)0)->thunk;
186 /* Now it must be the thunk address */
187 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
188 /* Now we have a pointer to the WINDOWPROC struct */
189 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
190 return (WINDOWPROC *)ptr;
193 /* Check for a segmented pointer */
195 if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
197 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
198 if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
199 /* It must be the thunk address */
200 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
201 /* Now we have a pointer to the WINDOWPROC struct */
202 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
203 return (WINDOWPROC *)ptr;
206 return NULL;
210 /**********************************************************************
211 * WINPROC_AllocWinProc
213 * Allocate a new window procedure.
215 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
216 WINDOWPROCUSER user )
218 WINDOWPROC *proc, *oldproc;
220 /* Allocate a window procedure */
222 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
224 /* Check if the function is already a win proc */
226 if ((oldproc = WINPROC_GetPtr( func )))
228 *proc = *oldproc;
230 else
232 switch(type)
234 case WIN_PROC_16:
235 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
236 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
237 proc->thunk.t_from32.proc = func;
238 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
239 proc->thunk.t_from32.pushl_ebp = 0x55; /* pushl %ebp */
240 proc->thunk.t_from32.pushl_name = 0x68; /* pushl $name */
241 proc->thunk.t_from32.name = "WINPROC_CallProc32ATo16";
242 proc->thunk.t_from32.pushl_thunk = 0x68; /* pushl $thunkfrom32 */
243 proc->thunk.t_from32.thunk32 = (void(*)())WINPROC_CallProc32ATo16;
244 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
245 proc->thunk.t_from32.relay = /* relative jump */
246 (void (*)())((DWORD)CallFrom32_stdcall_5 -
247 (DWORD)(&proc->thunk.t_from32.relay + 1));
248 break;
249 case WIN_PROC_32A:
250 case WIN_PROC_32W:
251 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
252 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
253 proc->thunk.t_from16.proc = (FARPROC32)func;
254 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
255 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
256 proc->thunk.t_from16.pushl_thunk = 0x68; /* pushl $thunkfrom16 */
257 proc->thunk.t_from16.thunk32 = (type == WIN_PROC_32A) ?
258 (void(*)())WINPROC_CallProc16To32A :
259 (void(*)())WINPROC_CallProc16To32W;
260 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:relay */
261 proc->thunk.t_from16.relay = CallFrom16_long_wwwll;
262 proc->thunk.t_from16.cs = WINE_CODE_SELECTOR;
263 proc->jmp.jmp = 0xe9;
264 /* Fixup relative jump */
265 proc->jmp.proc = (WNDPROC32)((DWORD)func -
266 (DWORD)(&proc->jmp.proc + 1));
267 break;
268 default:
269 /* Should not happen */
270 break;
272 proc->magic = WINPROC_MAGIC;
273 proc->type = type;
274 proc->user = user;
276 proc->next = NULL;
277 dprintf_win( stddeb, "WINPROC_AllocWinProc(%08x,%d): returning %08x\n",
278 (UINT32)func, type, (UINT32)proc );
279 return proc;
283 /**********************************************************************
284 * WINPROC_GetProc
286 * Get a window procedure pointer that can be passed to the Windows program.
288 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
290 if (!proc) return NULL;
291 if (type == WIN_PROC_16) /* We want a 16:16 address */
293 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
294 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
295 else
296 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
297 &((WINDOWPROC *)proc)->thunk );
299 else /* We want a 32-bit address */
301 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
302 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
303 else
304 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
309 /**********************************************************************
310 * WINPROC_SetProc
312 * Set the window procedure for a window or class. There are
313 * three tree classes of winproc callbacks:
315 * 1) class -> wp - not subclassed
316 * class -> wp -> wp -> wp -> wp - SetClassLong()
317 * / /
318 * 2) window -' / - not subclassed
319 * window -> wp -> wp ' - SetWindowLong()
321 * 3) timer -> wp - SetTimer()
323 * Initially, winproc of the window points to the current winproc
324 * thunk of its class. Subclassing prepends a new thunk to the
325 * window winproc chain at the head of the list. Thus, window thunk
326 * list includes class thunks and the latter are preserved when the
327 * window is destroyed.
330 BOOL32 WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
331 WINDOWPROCTYPE type, WINDOWPROCUSER user )
333 BOOL32 bRecycle = FALSE;
334 WINDOWPROC *proc, **ppPrev;
336 /* Check if function is already in the list */
338 ppPrev = (WINDOWPROC **)pFirst;
339 proc = WINPROC_GetPtr( func );
340 while (*ppPrev)
342 if (proc)
344 if (*ppPrev == proc)
346 if ((*ppPrev)->user != user)
348 /* terminal thunk is being restored */
350 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
351 *(WINDOWPROC **)pFirst = *ppPrev;
352 return TRUE;
354 bRecycle = TRUE;
355 break;
358 else
360 if (((*ppPrev)->type == type) &&
361 (func == WINPROC_THUNKPROC(*ppPrev)))
363 bRecycle = TRUE;
364 break;
368 /* WPF_CLASS thunk terminates window thunk list */
369 if ((*ppPrev)->user != user) break;
370 ppPrev = &(*ppPrev)->next;
373 if (bRecycle)
375 /* Extract this thunk from the list */
376 proc = *ppPrev;
377 *ppPrev = proc->next;
379 else /* Allocate a new one */
381 if (proc) /* Was already a win proc */
383 type = proc->type;
384 func = WINPROC_THUNKPROC(proc);
386 proc = WINPROC_AllocWinProc( func, type, user );
387 if (!proc) return FALSE;
390 /* Add the win proc at the head of the list */
392 dprintf_win( stddeb, "WINPROC_SetProc(%08x,%08x,%d): res=%08x\n",
393 (UINT32)*pFirst, (UINT32)func, type, (UINT32)proc );
394 proc->next = *(WINDOWPROC **)pFirst;
395 *(WINDOWPROC **)pFirst = proc;
396 return TRUE;
400 /**********************************************************************
401 * WINPROC_FreeProc
403 * Free a list of win procs.
405 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
407 while (proc)
409 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
410 if (((WINDOWPROC *)proc)->user != user) break;
411 dprintf_win( stddeb, "WINPROC_FreeProc: freeing %08x\n", (UINT32)proc);
412 HeapFree( WinProcHeap, 0, proc );
413 proc = next;
418 /**********************************************************************
419 * WINPROC_GetProcType
421 * Return the window procedure type.
423 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
425 if (!proc ||
426 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
427 return WIN_PROC_INVALID;
428 return ((WINDOWPROC *)proc)->type;
432 /**********************************************************************
433 * WINPROC_MapMsg32ATo32W
435 * Map a message from Ansi to Unicode.
436 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
438 INT32 WINPROC_MapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
440 switch(msg)
442 case WM_GETTEXT:
444 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
445 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
446 if (!ptr) return -1;
447 *ptr++ = *plparam; /* Store previous lParam */
448 *plparam = (LPARAM)ptr;
450 return 1;
451 case WM_SETTEXT:
452 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
453 return (*plparam ? 1 : -1);
454 case WM_NCCREATE:
455 case WM_CREATE:
457 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
458 sizeof(*cs) );
459 if (!cs) return -1;
460 *cs = *(CREATESTRUCT32W *)*plparam;
461 if (HIWORD(cs->lpszName))
462 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
463 (LPCSTR)cs->lpszName );
464 if (HIWORD(cs->lpszClass))
465 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
466 (LPCSTR)cs->lpszClass );
467 *plparam = (LPARAM)cs;
469 return 1;
470 case WM_MDICREATE:
472 MDICREATESTRUCT32W *cs =
473 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
474 if (!cs) return -1;
475 *cs = *(MDICREATESTRUCT32W *)*plparam;
476 if (HIWORD(cs->szClass))
477 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
478 (LPCSTR)cs->szClass );
479 if (HIWORD(cs->szTitle))
480 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
481 (LPCSTR)cs->szTitle );
482 *plparam = (LPARAM)cs;
484 return 1;
485 case WM_ASKCBFORMATNAME:
486 case WM_DEVMODECHANGE:
487 case WM_MDIACTIVATE:
488 case WM_PAINTCLIPBOARD:
489 case WM_SIZECLIPBOARD:
490 case WM_WININICHANGE:
491 fprintf( stderr, "MapMsg32ATo32W: message %04x needs translation\n",
492 msg );
493 return -1;
494 default: /* No translation needed */
495 return 0;
500 /**********************************************************************
501 * WINPROC_UnmapMsg32ATo32W
503 * Unmap a message that was mapped from Ansi to Unicode.
505 void WINPROC_UnmapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
507 switch(msg)
509 case WM_GETTEXT:
511 LPARAM *ptr = (LPARAM *)lParam - 1;
512 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)(ptr + 1), wParam );
513 HeapFree( SystemHeap, 0, ptr );
515 break;
516 case WM_SETTEXT:
517 HeapFree( SystemHeap, 0, (void *)lParam );
518 break;
519 case WM_NCCREATE:
520 case WM_CREATE:
522 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
523 if (HIWORD(cs->lpszName))
524 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
525 if (HIWORD(cs->lpszClass))
526 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
527 HeapFree( SystemHeap, 0, cs );
529 break;
530 case WM_MDICREATE:
532 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
533 if (HIWORD(cs->szTitle))
534 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
535 if (HIWORD(cs->szClass))
536 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
537 HeapFree( SystemHeap, 0, cs );
539 break;
544 /**********************************************************************
545 * WINPROC_MapMsg32WTo32A
547 * Map a message from Unicode to Ansi.
548 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
550 INT32 WINPROC_MapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
552 switch(msg)
554 case WM_GETTEXT:
556 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
557 wParam + sizeof(LPARAM) );
558 if (!ptr) return -1;
559 *ptr++ = *plparam; /* Store previous lParam */
560 *plparam = (LPARAM)ptr;
562 return 1;
563 case WM_SETTEXT:
564 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
565 return (*plparam ? 1 : -1);
566 case WM_NCCREATE:
567 case WM_CREATE:
569 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
570 sizeof(*cs) );
571 if (!cs) return -1;
572 *cs = *(CREATESTRUCT32A *)*plparam;
573 if (HIWORD(cs->lpszName))
574 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
575 (LPCWSTR)cs->lpszName );
576 if (HIWORD(cs->lpszClass))
577 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
578 (LPCWSTR)cs->lpszClass);
579 *plparam = (LPARAM)cs;
581 return 1;
582 case WM_MDICREATE:
584 MDICREATESTRUCT32A *cs =
585 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
586 if (!cs) return -1;
587 *cs = *(MDICREATESTRUCT32A *)*plparam;
588 if (HIWORD(cs->szTitle))
589 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
590 (LPCWSTR)cs->szTitle );
591 if (HIWORD(cs->szClass))
592 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
593 (LPCWSTR)cs->szClass );
594 *plparam = (LPARAM)cs;
596 return 1;
597 case WM_ASKCBFORMATNAME:
598 case WM_DEVMODECHANGE:
599 case WM_MDIACTIVATE:
600 case WM_PAINTCLIPBOARD:
601 case WM_SIZECLIPBOARD:
602 case WM_WININICHANGE:
603 fprintf( stderr, "MapMsg32WTo32A: message %04x needs translation\n",
604 msg );
605 return -1;
606 default: /* No translation needed */
607 return 0;
612 /**********************************************************************
613 * WINPROC_UnmapMsg32WTo32A
615 * Unmap a message that was mapped from Unicode to Ansi.
617 void WINPROC_UnmapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
619 switch(msg)
621 case WM_GETTEXT:
623 LPARAM *ptr = (LPARAM *)lParam - 1;
624 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)(ptr + 1), wParam );
625 HeapFree( SystemHeap, 0, ptr );
627 break;
628 case WM_SETTEXT:
629 HeapFree( SystemHeap, 0, (void *)lParam );
630 break;
631 case WM_NCCREATE:
632 case WM_CREATE:
634 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
635 if (HIWORD(cs->lpszName))
636 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
637 if (HIWORD(cs->lpszClass))
638 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
639 HeapFree( SystemHeap, 0, cs );
641 break;
642 case WM_MDICREATE:
644 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
645 if (HIWORD(cs->szTitle))
646 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
647 if (HIWORD(cs->szClass))
648 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
649 HeapFree( SystemHeap, 0, cs );
651 break;
656 /**********************************************************************
657 * WINPROC_MapMsg16To32A
659 * Map a message from 16- to 32-bit Ansi.
660 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
662 INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
663 WPARAM32 *pwparam32, LPARAM *plparam )
665 *pmsg32 = (UINT32)msg16;
666 *pwparam32 = (WPARAM32)wParam16;
667 switch(msg16)
669 case WM_ACTIVATE:
670 case WM_CHARTOITEM:
671 case WM_COMMAND:
672 case WM_VKEYTOITEM:
673 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
674 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
675 return 0;
676 case WM_HSCROLL:
677 case WM_VSCROLL:
678 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
679 *plparam = (LPARAM)(HWND32)HIWORD(*plparam);
680 return 0;
681 case WM_CTLCOLOR:
682 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
683 *pwparam32 = (WPARAM32)(HDC32)wParam16;
684 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
685 return 0;
686 case WM_COMPAREITEM:
688 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
689 COMPAREITEMSTRUCT32 *cis = (COMPAREITEMSTRUCT32 *)
690 HeapAlloc(SystemHeap, 0, sizeof(*cis));
691 if (!cis) return -1;
692 cis->CtlType = cis16->CtlType;
693 cis->CtlID = cis16->CtlID;
694 cis->hwndItem = cis16->hwndItem;
695 cis->itemID1 = cis16->itemID1;
696 cis->itemData1 = cis16->itemData1;
697 cis->itemID2 = cis16->itemID2;
698 cis->itemData2 = cis16->itemData2;
699 cis->dwLocaleId = 0; /* FIXME */
700 *plparam = (LPARAM)cis;
702 return 1;
703 case WM_DELETEITEM:
705 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
706 DELETEITEMSTRUCT32 *dis = (DELETEITEMSTRUCT32 *)
707 HeapAlloc(SystemHeap, 0, sizeof(*dis));
708 if (!dis) return -1;
709 dis->CtlType = dis16->CtlType;
710 dis->CtlID = dis16->CtlID;
711 dis->hwndItem = dis16->hwndItem;
712 dis->itemData = dis16->itemData;
713 *plparam = (LPARAM)dis;
715 return 1;
716 case WM_MEASUREITEM:
718 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
719 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)
720 HeapAlloc(SystemHeap, 0,
721 sizeof(*mis) + sizeof(LPARAM));
722 if (!mis) return -1;
723 mis->CtlType = mis16->CtlType;
724 mis->CtlID = mis16->CtlID;
725 mis->itemID = mis16->itemID;
726 mis->itemWidth = mis16->itemWidth;
727 mis->itemHeight = mis16->itemHeight;
728 mis->itemData = mis16->itemData;
729 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
730 *plparam = (LPARAM)mis;
732 return 1;
733 case WM_DRAWITEM:
735 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
736 DRAWITEMSTRUCT32 *dis = (DRAWITEMSTRUCT32*)HeapAlloc(SystemHeap, 0,
737 sizeof(*dis));
738 if (!dis) return -1;
739 dis->CtlType = dis16->CtlType;
740 dis->CtlID = dis16->CtlID;
741 dis->itemID = dis16->itemID;
742 dis->itemAction = dis16->itemAction;
743 dis->itemState = dis16->itemState;
744 dis->hwndItem = dis16->hwndItem;
745 dis->hDC = dis16->hDC;
746 dis->itemData = dis16->itemData;
747 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
748 *plparam = (LPARAM)dis;
750 return 1;
751 case WM_GETMINMAXINFO:
753 MINMAXINFO32 *mmi = (MINMAXINFO32 *)HeapAlloc( SystemHeap, 0,
754 sizeof(*mmi) + sizeof(LPARAM));
755 if (!mmi) return -1;
756 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
757 mmi );
758 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
759 *plparam = (LPARAM)mmi;
761 return 1;
762 case WM_GETTEXT:
763 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
764 return 0;
765 case WM_MDICREATE:
767 MDICREATESTRUCT16 *cs16 =
768 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
769 MDICREATESTRUCT32A *cs =
770 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
771 sizeof(*cs) + sizeof(LPARAM) );
772 if (!cs) return -1;
773 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
774 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
775 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
776 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
777 *plparam = (LPARAM)cs;
779 return 1;
780 case WM_MDISETMENU:
781 *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
782 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
783 return 0;
784 case WM_MENUCHAR:
785 case WM_MENUSELECT:
786 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
787 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
788 return 0;
789 case WM_NCCALCSIZE:
791 NCCALCSIZE_PARAMS16 *nc16;
792 NCCALCSIZE_PARAMS32 *nc;
794 nc = (NCCALCSIZE_PARAMS32 *)HeapAlloc( SystemHeap, 0,
795 sizeof(*nc) + sizeof(LPARAM) );
796 if (!nc) return -1;
797 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
798 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
799 if (wParam16)
801 nc->lppos = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
802 sizeof(*nc->lppos) );
803 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
804 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
805 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
807 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
808 *plparam = (LPARAM)nc;
810 return 1;
811 case WM_NCCREATE:
812 case WM_CREATE:
814 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
815 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
816 sizeof(*cs) + sizeof(LPARAM) );
817 if (!cs) return -1;
818 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
819 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
820 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
821 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
822 *plparam = (LPARAM)cs;
824 return 1;
825 case WM_PARENTNOTIFY:
826 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
828 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
829 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
831 return 0;
832 case WM_SETTEXT:
833 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
834 return 0;
835 case WM_WINDOWPOSCHANGING:
836 case WM_WINDOWPOSCHANGED:
838 WINDOWPOS32 *wp = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
839 sizeof(*wp) + sizeof(LPARAM) );
840 if (!wp) return -1;
841 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
842 wp );
843 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
844 *plparam = (LPARAM)wp;
846 return 1;
847 case WM_ASKCBFORMATNAME:
848 case WM_DEVMODECHANGE:
849 case WM_MDIACTIVATE:
850 case WM_PAINTCLIPBOARD:
851 case WM_SIZECLIPBOARD:
852 case WM_WININICHANGE:
853 fprintf( stderr, "MapMsg16To32A: message %04x needs translation\n",
854 msg16 );
855 return -1;
857 default: /* No translation needed */
858 return 0;
863 /**********************************************************************
864 * WINPROC_UnmapMsg16To32A
866 * Unmap a message that was mapped from 16- to 32-bit Ansi.
868 void WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
870 switch(msg)
872 case WM_COMPAREITEM:
873 case WM_DELETEITEM:
874 case WM_DRAWITEM:
875 HeapFree( SystemHeap, 0, (LPVOID)lParam );
876 break;
877 case WM_MEASUREITEM:
879 MEASUREITEMSTRUCT16 *mis16;
880 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)lParam;
881 lParam = *(LPARAM *)(mis + 1);
882 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
883 mis16->itemWidth = (UINT16)mis->itemWidth;
884 mis16->itemHeight = (UINT16)mis->itemHeight;
885 HeapFree( SystemHeap, 0, mis );
887 break;
888 case WM_GETMINMAXINFO:
890 MINMAXINFO32 *mmi = (MINMAXINFO32 *)lParam;
891 lParam = *(LPARAM *)(mmi + 1);
892 STRUCT32_MINMAXINFO32to16( mmi,
893 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
894 HeapFree( SystemHeap, 0, mmi );
896 break;
897 case WM_MDICREATE:
899 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
900 lParam = *(LPARAM *)(cs + 1);
901 STRUCT32_MDICREATESTRUCT32Ato16( cs,
902 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
903 HeapFree( SystemHeap, 0, cs );
905 break;
906 case WM_NCCALCSIZE:
908 NCCALCSIZE_PARAMS16 *nc16;
909 NCCALCSIZE_PARAMS32 *nc = (NCCALCSIZE_PARAMS32 *)lParam;
910 lParam = *(LPARAM *)(nc + 1);
911 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
912 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
913 if (wParam)
915 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
916 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
917 if (nc->lppos)
919 STRUCT32_WINDOWPOS32to16( nc->lppos,
920 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
921 HeapFree( SystemHeap, 0, nc->lppos );
924 HeapFree( SystemHeap, 0, nc );
926 break;
927 case WM_NCCREATE:
928 case WM_CREATE:
930 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
931 lParam = *(LPARAM *)(cs + 1);
932 STRUCT32_CREATESTRUCT32Ato16( cs,
933 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
934 HeapFree( SystemHeap, 0, cs );
936 break;
937 case WM_WINDOWPOSCHANGING:
938 case WM_WINDOWPOSCHANGED:
940 WINDOWPOS32 *wp = (WINDOWPOS32 *)lParam;
941 lParam = *(LPARAM *)(wp + 1);
942 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
943 HeapFree( SystemHeap, 0, wp );
945 break;
950 /**********************************************************************
951 * WINPROC_MapMsg16To32W
953 * Map a message from 16- to 32-bit Unicode.
954 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
956 INT32 WINPROC_MapMsg16To32W( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
957 WPARAM32 *pwparam32, LPARAM *plparam )
959 switch(msg16)
961 case WM_GETTEXT:
962 case WM_SETTEXT:
963 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
964 return WINPROC_MapMsg32ATo32W( *pmsg32, *pwparam32, plparam );
965 case WM_NCCREATE:
966 case WM_CREATE:
968 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
969 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
970 sizeof(*cs) + sizeof(LPARAM) );
971 if (!cs) return -1;
972 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCT32A *)cs );
973 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
974 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
975 if (HIWORD(cs->lpszName))
976 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
977 (LPCSTR)cs->lpszName );
978 if (HIWORD(cs->lpszClass))
979 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
980 (LPCSTR)cs->lpszClass );
981 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
982 *plparam = (LPARAM)cs;
984 return 1;
985 case WM_MDICREATE:
987 MDICREATESTRUCT16 *cs16 =
988 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
989 MDICREATESTRUCT32W *cs =
990 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
991 sizeof(*cs) + sizeof(LPARAM) );
992 if (!cs) return -1;
993 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCT32A *)cs );
994 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
995 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
996 if (HIWORD(cs->szTitle))
997 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
998 (LPCSTR)cs->szTitle );
999 if (HIWORD(cs->szClass))
1000 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
1001 (LPCSTR)cs->szClass );
1002 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1003 *plparam = (LPARAM)cs;
1005 return 1;
1006 default: /* No Unicode translation needed */
1007 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1008 pwparam32, plparam );
1013 /**********************************************************************
1014 * WINPROC_UnmapMsg16To32W
1016 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1018 void WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
1020 switch(msg)
1022 case WM_GETTEXT:
1023 case WM_SETTEXT:
1024 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1025 break;
1026 case WM_NCCREATE:
1027 case WM_CREATE:
1029 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
1030 lParam = *(LPARAM *)(cs + 1);
1031 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
1032 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1033 if (HIWORD(cs->lpszName))
1034 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1035 if (HIWORD(cs->lpszClass))
1036 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1037 HeapFree( SystemHeap, 0, cs );
1039 break;
1040 case WM_MDICREATE:
1042 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
1043 lParam = *(LPARAM *)(cs + 1);
1044 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
1045 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1046 if (HIWORD(cs->szTitle))
1047 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1048 if (HIWORD(cs->szClass))
1049 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1050 HeapFree( SystemHeap, 0, cs );
1052 break;
1053 default:
1054 WINPROC_UnmapMsg16To32A( msg, wParam, lParam );
1055 break;
1060 /**********************************************************************
1061 * WINPROC_MapMsg32ATo16
1063 * Map a message from 32-bit Ansi to 16-bit.
1064 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1066 INT32 WINPROC_MapMsg32ATo16( UINT32 msg32, WPARAM32 wParam32, UINT16 *pmsg16,
1067 WPARAM16 *pwparam16, LPARAM *plparam )
1069 *pmsg16 = (UINT16)msg32;
1070 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1071 switch(msg32)
1073 case BM_GETCHECK32:
1074 case BM_SETCHECK32:
1075 case BM_GETSTATE32:
1076 case BM_SETSTATE32:
1077 case BM_SETSTYLE32:
1078 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK32);
1079 return 0;
1081 case EM_GETSEL32:
1082 case EM_GETRECT32:
1083 case EM_SETRECT32:
1084 case EM_SETRECTNP32:
1085 case EM_SCROLL32:
1086 case EM_LINESCROLL32:
1087 case EM_SCROLLCARET32:
1088 case EM_GETMODIFY32:
1089 case EM_SETMODIFY32:
1090 case EM_GETLINECOUNT32:
1091 case EM_LINEINDEX32:
1092 case EM_SETHANDLE32:
1093 case EM_GETHANDLE32:
1094 case EM_GETTHUMB32:
1095 case EM_LINELENGTH32:
1096 case EM_REPLACESEL32:
1097 case EM_GETLINE32:
1098 case EM_LIMITTEXT32:
1099 case EM_CANUNDO32:
1100 case EM_UNDO32:
1101 case EM_FMTLINES32:
1102 case EM_LINEFROMCHAR32:
1103 case EM_SETTABSTOPS32:
1104 case EM_SETPASSWORDCHAR32:
1105 case EM_EMPTYUNDOBUFFER32:
1106 case EM_GETFIRSTVISIBLELINE32:
1107 case EM_SETREADONLY32:
1108 case EM_SETWORDBREAKPROC32:
1109 case EM_GETWORDBREAKPROC32:
1110 case EM_GETPASSWORDCHAR32:
1111 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL32);
1112 return 0;
1114 case LB_CARETOFF32:
1115 case LB_CARETON32:
1116 case LB_DELETESTRING32:
1117 case LB_GETANCHORINDEX32:
1118 case LB_GETCARETINDEX32:
1119 case LB_GETCOUNT32:
1120 case LB_GETCURSEL32:
1121 case LB_GETHORIZONTALEXTENT32:
1122 case LB_GETITEMDATA32:
1123 case LB_GETITEMHEIGHT32:
1124 case LB_GETSEL32:
1125 case LB_GETSELCOUNT32:
1126 case LB_GETTEXTLEN32:
1127 case LB_GETTOPINDEX32:
1128 case LB_RESETCONTENT32:
1129 case LB_SELITEMRANGE32:
1130 case LB_SELITEMRANGEEX32:
1131 case LB_SETANCHORINDEX32:
1132 case LB_SETCARETINDEX32:
1133 case LB_SETCOLUMNWIDTH32:
1134 case LB_SETCURSEL32:
1135 case LB_SETHORIZONTALEXTENT32:
1136 case LB_SETITEMDATA32:
1137 case LB_SETITEMHEIGHT32:
1138 case LB_SETSEL32:
1139 case LB_SETTOPINDEX32:
1140 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1141 return 0;
1142 case CB_DELETESTRING32:
1143 case CB_GETCOUNT32:
1144 case CB_GETLBTEXTLEN32:
1145 case CB_LIMITTEXT32:
1146 case CB_RESETCONTENT32:
1147 case CB_SETEDITSEL32:
1148 case CB_GETCURSEL32:
1149 case CB_SETCURSEL32:
1150 case CB_SHOWDROPDOWN32:
1151 case CB_SETITEMDATA32:
1152 case CB_SETITEMHEIGHT32:
1153 case CB_GETITEMHEIGHT32:
1154 case CB_SETEXTENDEDUI32:
1155 case CB_GETEXTENDEDUI32:
1156 case CB_GETDROPPEDSTATE32:
1157 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1158 return 0;
1159 case CB_GETEDITSEL32:
1160 *pmsg16 = CB_GETEDITSEL16;
1161 return 1;
1163 case LB_ADDSTRING32:
1164 case LB_FINDSTRING32:
1165 case LB_FINDSTRINGEXACT32:
1166 case LB_INSERTSTRING32:
1167 case LB_SELECTSTRING32:
1168 case LB_DIR32:
1169 case LB_ADDFILE32:
1171 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1172 if (!str) return -1;
1173 *plparam = (LPARAM)SEGPTR_GET(str);
1175 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1176 return 1;
1178 case CB_ADDSTRING32:
1179 case CB_FINDSTRING32:
1180 case CB_FINDSTRINGEXACT32:
1181 case CB_INSERTSTRING32:
1182 case CB_SELECTSTRING32:
1183 case CB_DIR32:
1185 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1186 if (!str) return -1;
1187 *plparam = (LPARAM)SEGPTR_GET(str);
1189 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1190 return 1;
1192 case LB_GETITEMRECT32:
1194 RECT16 *rect;
1195 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1196 if (!rect) return -1;
1197 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1198 *plparam = (LPARAM)SEGPTR_GET(rect);
1200 *pmsg16 = LB_GETITEMRECT16;
1201 return 1;
1202 case LB_GETSELITEMS32:
1204 LPINT16 items;
1205 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1206 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1207 + sizeof(LPARAM)))) return -1;
1208 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1209 *plparam = (LPARAM)SEGPTR_GET(items);
1211 *pmsg16 = LB_GETSELITEMS16;
1212 return 1;
1213 case LB_SETTABSTOPS32:
1214 if (wParam32)
1216 INT32 i;
1217 LPINT16 stops;
1218 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1219 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1220 + sizeof(LPARAM)))) return -1;
1221 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT32)*plparam+i);
1222 *plparam = (LPARAM)SEGPTR_GET(stops);
1223 return 1;
1225 *pmsg16 = LB_SETTABSTOPS16;
1226 return 0;
1228 case CB_GETDROPPEDCONTROLRECT32:
1230 RECT16 *rect;
1231 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1232 if (!rect) return -1;
1233 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1234 *plparam = (LPARAM)SEGPTR_GET(rect);
1236 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1237 return 1;
1239 case LB_GETTEXT32:
1240 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1241 *pmsg16 = LB_GETTEXT16;
1242 return 1;
1244 case CB_GETLBTEXT32:
1245 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1246 *pmsg16 = CB_GETLBTEXT16;
1247 return 1;
1249 case EM_SETSEL32:
1250 *pwparam16 = 0;
1251 *plparam = MAKELONG( (INT16)(INT32)wParam32, (INT16)*plparam );
1252 *pmsg16 = EM_SETSEL16;
1253 return 0;
1255 case WM_ACTIVATE:
1256 case WM_CHARTOITEM:
1257 case WM_COMMAND:
1258 case WM_VKEYTOITEM:
1259 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1260 return 0;
1261 case WM_HSCROLL:
1262 case WM_VSCROLL:
1263 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1264 return 0;
1265 case WM_CTLCOLORMSGBOX:
1266 case WM_CTLCOLOREDIT:
1267 case WM_CTLCOLORLISTBOX:
1268 case WM_CTLCOLORBTN:
1269 case WM_CTLCOLORDLG:
1270 case WM_CTLCOLORSCROLLBAR:
1271 case WM_CTLCOLORSTATIC:
1272 *pmsg16 = WM_CTLCOLOR;
1273 *plparam = MAKELPARAM( (HWND16)*plparam,
1274 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1275 return 0;
1276 case WM_COMPAREITEM:
1278 COMPAREITEMSTRUCT32 *cis32 = (COMPAREITEMSTRUCT32 *)*plparam;
1279 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1280 if (!cis) return -1;
1281 cis->CtlType = (UINT16)cis32->CtlType;
1282 cis->CtlID = (UINT16)cis32->CtlID;
1283 cis->hwndItem = (HWND16)cis32->hwndItem;
1284 cis->itemID1 = (UINT16)cis32->itemID1;
1285 cis->itemData1 = cis32->itemData1;
1286 cis->itemID2 = (UINT16)cis32->itemID2;
1287 cis->itemData2 = cis32->itemData2;
1288 *plparam = (LPARAM)SEGPTR_GET(cis);
1290 return 1;
1291 case WM_DELETEITEM:
1293 DELETEITEMSTRUCT32 *dis32 = (DELETEITEMSTRUCT32 *)*plparam;
1294 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1295 if (!dis) return -1;
1296 dis->CtlType = (UINT16)dis32->CtlType;
1297 dis->CtlID = (UINT16)dis32->CtlID;
1298 dis->itemID = (UINT16)dis32->itemID;
1299 dis->hwndItem = (HWND16)dis32->hwndItem;
1300 dis->itemData = dis32->itemData;
1301 *plparam = (LPARAM)SEGPTR_GET(dis);
1303 return 1;
1304 case WM_DRAWITEM:
1306 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)*plparam;
1307 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1308 if (!dis) return -1;
1309 dis->CtlType = (UINT16)dis32->CtlType;
1310 dis->CtlID = (UINT16)dis32->CtlID;
1311 dis->itemID = (UINT16)dis32->itemID;
1312 dis->itemAction = (UINT16)dis32->itemAction;
1313 dis->itemState = (UINT16)dis32->itemState;
1314 dis->hwndItem = (HWND16)dis32->hwndItem;
1315 dis->hDC = (HDC16)dis32->hDC;
1316 dis->itemData = dis32->itemData;
1317 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1318 *plparam = (LPARAM)SEGPTR_GET(dis);
1320 return 1;
1321 case WM_MEASUREITEM:
1323 MEASUREITEMSTRUCT32 *mis32 = (MEASUREITEMSTRUCT32 *)*plparam;
1324 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1325 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1326 if (!mis) return -1;
1327 mis->CtlType = (UINT16)mis32->CtlType;
1328 mis->CtlID = (UINT16)mis32->CtlID;
1329 mis->itemID = (UINT16)mis32->itemID;
1330 mis->itemWidth = (UINT16)mis32->itemWidth;
1331 mis->itemHeight = (UINT16)mis32->itemHeight;
1332 mis->itemData = mis32->itemData;
1333 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1334 *plparam = (LPARAM)SEGPTR_GET(mis);
1336 return 1;
1337 case WM_GETMINMAXINFO:
1339 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1340 sizeof(LPARAM) );
1341 if (!mmi) return -1;
1342 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)*plparam, mmi );
1343 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1344 *plparam = (LPARAM)SEGPTR_GET(mmi);
1346 return 1;
1347 case WM_GETTEXT:
1349 LPSTR str;
1350 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1351 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1352 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1353 *plparam = (LPARAM)SEGPTR_GET(str);
1355 return 1;
1356 case WM_MDICREATE:
1358 MDICREATESTRUCT16 *cs;
1359 MDICREATESTRUCT32A *cs32 = (MDICREATESTRUCT32A *)*plparam;
1360 LPSTR name, cls;
1362 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1363 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1364 name = SEGPTR_STRDUP( cs32->szTitle );
1365 cls = SEGPTR_STRDUP( cs32->szClass );
1366 cs->szTitle = SEGPTR_GET(name);
1367 cs->szClass = SEGPTR_GET(cls);
1368 *plparam = (LPARAM)SEGPTR_GET(cs);
1370 return 1;
1371 case WM_MDISETMENU:
1372 *pwparam16 = TRUE; /* FIXME? */
1373 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1374 (HMENU16)LOWORD(*plparam) );
1375 return 0;
1376 case WM_MENUCHAR:
1377 case WM_MENUSELECT:
1378 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1379 return 0;
1380 case WM_NCCALCSIZE:
1382 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
1383 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1384 if (!nc) return -1;
1386 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1387 if (wParam32)
1389 WINDOWPOS16 *wp;
1390 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1391 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1392 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1394 SEGPTR_FREE(nc);
1395 return -1;
1397 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1398 nc->lppos = SEGPTR_GET(wp);
1400 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1401 *plparam = (LPARAM)SEGPTR_GET(nc);
1403 return 1;
1404 case WM_NCCREATE:
1405 case WM_CREATE:
1407 CREATESTRUCT16 *cs;
1408 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)*plparam;
1409 LPSTR name, cls;
1411 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1412 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1413 name = SEGPTR_STRDUP( cs32->lpszName );
1414 cls = SEGPTR_STRDUP( cs32->lpszClass );
1415 cs->lpszName = SEGPTR_GET(name);
1416 cs->lpszClass = SEGPTR_GET(cls);
1417 *plparam = (LPARAM)SEGPTR_GET(cs);
1419 return 1;
1420 case WM_PARENTNOTIFY:
1421 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1422 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1423 /* else nothing to do */
1424 return 0;
1425 case WM_SETTEXT:
1427 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1428 if (!str) return -1;
1429 *plparam = (LPARAM)SEGPTR_GET(str);
1431 return 1;
1432 case WM_WINDOWPOSCHANGING:
1433 case WM_WINDOWPOSCHANGED:
1435 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1436 sizeof(LPARAM) );
1437 if (!wp) return -1;
1438 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)*plparam, wp );
1439 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1440 *plparam = (LPARAM)SEGPTR_GET(wp);
1442 return 1;
1443 case WM_ASKCBFORMATNAME:
1444 case WM_DEVMODECHANGE:
1445 case WM_MDIACTIVATE:
1446 case WM_PAINTCLIPBOARD:
1447 case WM_SIZECLIPBOARD:
1448 case WM_WININICHANGE:
1449 fprintf( stderr, "MapMsg32ATo16: message %04x needs translation\n",
1450 msg32 );
1451 return -1;
1453 default: /* No translation needed */
1454 return 0;
1459 /**********************************************************************
1460 * WINPROC_UnmapMsg32ATo16
1462 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1464 void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM32 wParam,
1465 LPARAM lParam, MSGPARAM16* p16 )
1467 switch(msg)
1469 case LB_ADDFILE32:
1470 case LB_ADDSTRING32:
1471 case LB_DIR32:
1472 case LB_FINDSTRING32:
1473 case LB_FINDSTRINGEXACT32:
1474 case LB_INSERTSTRING32:
1475 case LB_SELECTSTRING32:
1476 case LB_SETTABSTOPS32:
1477 case CB_ADDSTRING32:
1478 case CB_FINDSTRING32:
1479 case CB_FINDSTRINGEXACT32:
1480 case CB_INSERTSTRING32:
1481 case CB_SELECTSTRING32:
1482 case CB_DIR32:
1483 case WM_COMPAREITEM:
1484 case WM_DELETEITEM:
1485 case WM_DRAWITEM:
1486 case WM_SETTEXT:
1487 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1488 break;
1490 case CB_GETDROPPEDCONTROLRECT32:
1491 case LB_GETITEMRECT32:
1493 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1494 p16->lParam = *(LPARAM *)(rect + 1);
1495 CONV_RECT16TO32( rect, (RECT32 *)(p16->lParam));
1496 SEGPTR_FREE( rect );
1498 break;
1499 case LB_GETSELITEMS32:
1501 INT32 i;
1502 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1503 p16->lParam = *((LPARAM *)items - 1);
1504 for (i = 0; i < p16->wParam; i++) *((LPINT32)(p16->lParam) + i) = items[i];
1505 SEGPTR_FREE( (LPARAM *)items - 1 );
1507 break;
1509 case CB_GETEDITSEL32:
1510 if( wParam )
1511 *((LPUINT32)(wParam)) = LOWORD(p16->lResult);
1512 if( lParam )
1513 *((LPUINT32)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1514 break;
1516 case LB_GETTEXT32:
1517 case CB_GETLBTEXT32:
1518 UnMapLS( (SEGPTR)(p16->lParam) );
1519 break;
1521 case WM_MEASUREITEM:
1523 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1524 MEASUREITEMSTRUCT32 *mis32 = *(MEASUREITEMSTRUCT32 **)(mis + 1);
1525 mis32->itemWidth = mis->itemWidth;
1526 mis32->itemHeight = mis->itemHeight;
1527 SEGPTR_FREE(mis);
1529 break;
1530 case WM_GETMINMAXINFO:
1532 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1533 p16->lParam = *(LPARAM *)(mmi + 1);
1534 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)(p16->lParam) );
1535 SEGPTR_FREE(mmi);
1537 break;
1538 case WM_GETTEXT:
1540 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1541 p16->lParam = *((LPARAM *)str - 1);
1542 lstrcpyn32A( (LPSTR)(p16->lParam), str, p16->wParam );
1543 SEGPTR_FREE( (LPARAM *)str - 1 );
1545 break;
1546 case WM_MDICREATE:
1548 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1549 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1550 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1551 SEGPTR_FREE( cs );
1553 break;
1554 case WM_NCCALCSIZE:
1556 NCCALCSIZE_PARAMS32 *nc32;
1557 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
1558 p16->lParam = *(LPARAM *)(nc + 1);
1559 nc32 = (NCCALCSIZE_PARAMS32 *)(p16->lParam);
1560 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1561 if (p16->wParam)
1563 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1564 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1565 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1566 nc32->lppos );
1567 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1569 SEGPTR_FREE(nc);
1571 break;
1572 case WM_NCCREATE:
1573 case WM_CREATE:
1575 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1576 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1577 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1578 SEGPTR_FREE( cs );
1580 break;
1581 case WM_WINDOWPOSCHANGING:
1582 case WM_WINDOWPOSCHANGED:
1584 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
1585 p16->lParam = *(LPARAM *)(wp + 1);
1586 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)p16->lParam );
1587 SEGPTR_FREE(wp);
1589 break;
1594 /**********************************************************************
1595 * WINPROC_MapMsg32WTo16
1597 * Map a message from 32-bit Unicode to 16-bit.
1598 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1600 INT32 WINPROC_MapMsg32WTo16( UINT32 msg32, WPARAM32 wParam32, UINT16 *pmsg16,
1601 WPARAM16 *pwparam16, LPARAM *plparam )
1603 switch(msg32)
1605 case LB_ADDSTRING32:
1606 case LB_FINDSTRING32:
1607 case LB_FINDSTRINGEXACT32:
1608 case LB_INSERTSTRING32:
1609 case LB_SELECTSTRING32:
1610 case LB_DIR32:
1611 case LB_ADDFILE32:
1613 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1614 if (!str) return -1;
1615 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1616 *plparam = (LPARAM)SEGPTR_GET(str);
1618 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1619 return 1;
1621 case CB_ADDSTRING32:
1622 case CB_FINDSTRING32:
1623 case CB_FINDSTRINGEXACT32:
1624 case CB_INSERTSTRING32:
1625 case CB_SELECTSTRING32:
1626 case CB_DIR32:
1628 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1629 if (!str) return -1;
1630 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1631 *plparam = (LPARAM)SEGPTR_GET(str);
1633 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING32);
1634 return 1;
1636 case WM_NCCREATE:
1637 case WM_CREATE:
1639 CREATESTRUCT16 *cs;
1640 CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
1641 LPSTR name, cls;
1643 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1644 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
1645 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
1646 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
1647 cs->lpszName = SEGPTR_GET(name);
1648 cs->lpszClass = SEGPTR_GET(cls);
1649 *pmsg16 = (UINT16)msg32;
1650 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1651 *plparam = (LPARAM)SEGPTR_GET(cs);
1653 return 1;
1654 case WM_MDICREATE:
1656 MDICREATESTRUCT16 *cs;
1657 MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
1658 LPSTR name, cls;
1660 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1661 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
1662 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
1663 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
1664 cs->szTitle = SEGPTR_GET(name);
1665 cs->szClass = SEGPTR_GET(cls);
1666 *pmsg16 = (UINT16)msg32;
1667 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1668 *plparam = (LPARAM)SEGPTR_GET(cs);
1670 return 1;
1671 case WM_SETTEXT:
1673 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1674 if (!str) return -1;
1675 *pmsg16 = (UINT16)msg32;
1676 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1677 *plparam = (LPARAM)SEGPTR_GET(str);
1679 return 1;
1680 default: /* No Unicode translation needed */
1681 return WINPROC_MapMsg32ATo16( msg32, wParam32, pmsg16,
1682 pwparam16, plparam );
1687 /**********************************************************************
1688 * WINPROC_UnmapMsg32WTo16
1690 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1692 void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam,
1693 LPARAM lParam, MSGPARAM16* p16 )
1695 switch(msg)
1697 case WM_GETTEXT:
1699 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1700 p16->lParam = *((LPARAM *)str - 1);
1701 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
1702 SEGPTR_FREE( (LPARAM *)str - 1 );
1704 break;
1705 default:
1706 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, p16 );
1707 break;
1712 /**********************************************************************
1713 * WINPROC_CallProc32ATo32W
1715 * Call a window procedure, translating args from Ansi to Unicode.
1717 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
1718 UINT32 msg, WPARAM32 wParam,
1719 LPARAM lParam )
1721 LRESULT result;
1723 if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
1724 result = WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
1725 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1726 return result;
1730 /**********************************************************************
1731 * WINPROC_CallProc32WTo32A
1733 * Call a window procedure, translating args from Unicode to Ansi.
1735 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
1736 UINT32 msg, WPARAM32 wParam,
1737 LPARAM lParam )
1739 LRESULT result;
1741 if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
1742 result = WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
1743 WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
1744 return result;
1748 /**********************************************************************
1749 * WINPROC_CallProc16To32A
1751 * Call a 32-bit window procedure, translating the 16-bit args.
1753 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
1754 WPARAM16 wParam, LPARAM lParam,
1755 WNDPROC32 func )
1757 LRESULT result;
1758 UINT32 msg32;
1759 WPARAM32 wParam32;
1761 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1762 return 0;
1763 result = WINPROC_CallWndProc32Ptr( func, hwnd, msg32, wParam32, lParam );
1764 WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam );
1765 return result;
1769 /**********************************************************************
1770 * WINPROC_CallProc16To32W
1772 * Call a 32-bit window procedure, translating the 16-bit args.
1774 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
1775 WPARAM16 wParam, LPARAM lParam,
1776 WNDPROC32 func )
1778 LRESULT result;
1779 UINT32 msg32;
1780 WPARAM32 wParam32;
1782 if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1783 return 0;
1784 result = WINPROC_CallWndProc32Ptr( func, hwnd, msg32, wParam32, lParam );
1785 WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam );
1786 return result;
1790 /**********************************************************************
1791 * WINPROC_CallProc32ATo16
1793 * Call a 16-bit window procedure, translating the 32-bit args.
1795 static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
1796 UINT32 msg, WPARAM32 wParam,
1797 LPARAM lParam )
1799 UINT16 msg16;
1800 MSGPARAM16 mp16;
1801 WND *wndPtr = WIN_FindWndPtr( hwnd );
1802 WORD ds = CURRENT_DS;
1804 mp16.lParam = lParam;
1805 if (WINPROC_MapMsg32ATo16( msg, wParam,
1806 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
1807 return 0;
1808 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1809 mp16.lResult = WINPROC_CallWndProc16Ptr( func, hwnd, msg16,
1810 mp16.wParam, mp16.lParam );
1811 CURRENT_DS = ds;
1812 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, &mp16 );
1813 return mp16.lResult;
1817 /**********************************************************************
1818 * WINPROC_CallProc32WTo16
1820 * Call a 16-bit window procedure, translating the 32-bit args.
1822 static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
1823 UINT32 msg, WPARAM32 wParam,
1824 LPARAM lParam )
1826 UINT16 msg16;
1827 MSGPARAM16 mp16;
1828 WND *wndPtr = WIN_FindWndPtr( hwnd );
1829 WORD ds = CURRENT_DS;
1831 mp16.lParam = lParam;
1832 if (WINPROC_MapMsg32WTo16( msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1)
1833 return 0;
1834 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1835 mp16.lResult = WINPROC_CallWndProc16Ptr( func, hwnd, msg16,
1836 mp16.wParam, mp16.lParam );
1837 CURRENT_DS = ds;
1838 WINPROC_UnmapMsg32WTo16( msg, wParam, lParam, &mp16 );
1839 return mp16.lResult;
1843 /**********************************************************************
1844 * CallWindowProc16 (USER.122)
1846 LRESULT CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
1847 WPARAM16 wParam, LPARAM lParam )
1849 LRESULT result;
1850 WND *wndPtr;
1851 WINDOWPROC *proc = WINPROC_GetPtr( func );
1852 WORD ds = CURRENT_DS;
1854 if (!proc)
1856 wndPtr = WIN_FindWndPtr( hwnd );
1857 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1858 result = WINPROC_CallWndProc16Ptr( func, hwnd, msg, wParam, lParam );
1859 CURRENT_DS = ds;
1860 return result;
1862 #if testing
1863 wndPtr = WIN_FindWndPtr( hwnd );
1864 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1865 result = WINPROC_CallWndProc16Ptr( WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16),
1866 hwnd, msg, wParam, lParam );
1867 CURRENT_DS = ds;
1868 return result;
1869 #endif
1871 switch(proc->type)
1873 case WIN_PROC_16:
1874 if (!proc->thunk.t_from32.proc) return 0;
1875 wndPtr = WIN_FindWndPtr( hwnd );
1876 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1877 result = WINPROC_CallWndProc16Ptr( proc->thunk.t_from32.proc,
1878 hwnd, msg, wParam, lParam );
1879 CURRENT_DS = ds;
1880 return result;
1882 case WIN_PROC_32A:
1883 if (!proc->thunk.t_from16.proc) return 0;
1884 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
1885 proc->thunk.t_from16.proc );
1886 case WIN_PROC_32W:
1887 if (!proc->thunk.t_from16.proc) return 0;
1888 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
1889 proc->thunk.t_from16.proc );
1890 default:
1891 fprintf( stderr, "CallWindowProc16: invalid proc %p\n", proc );
1892 return 0;
1897 /**********************************************************************
1898 * CallWindowProc32A (USER32.17)
1900 LRESULT CallWindowProc32A( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1901 WPARAM32 wParam, LPARAM lParam )
1903 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1905 if (!proc) return WINPROC_CallWndProc32Ptr( func, hwnd, msg,
1906 wParam, lParam );
1908 #if testing
1909 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
1910 return WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
1911 #endif
1913 switch(proc->type)
1915 case WIN_PROC_16:
1916 if (!proc->thunk.t_from32.proc) return 0;
1917 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
1918 hwnd, msg, wParam, lParam );
1919 case WIN_PROC_32A:
1920 if (!proc->thunk.t_from16.proc) return 0;
1921 return WINPROC_CallWndProc32Ptr( proc->thunk.t_from16.proc,
1922 hwnd, msg, wParam, lParam );
1923 case WIN_PROC_32W:
1924 if (!proc->thunk.t_from16.proc) return 0;
1925 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
1926 hwnd, msg, wParam, lParam );
1927 default:
1928 fprintf( stderr, "CallWindowProc32A: invalid proc %p\n", proc );
1929 return 0;
1934 /**********************************************************************
1935 * CallWindowProc32W (USER32.18)
1937 LRESULT CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1938 WPARAM32 wParam, LPARAM lParam )
1940 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1942 if (!proc) return WINPROC_CallWndProc32Ptr( func, hwnd, msg,
1943 wParam, lParam );
1945 #if testing
1946 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
1947 return WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
1948 #endif
1950 switch(proc->type)
1952 case WIN_PROC_16:
1953 if (!proc->thunk.t_from32.proc) return 0;
1954 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
1955 hwnd, msg, wParam, lParam );
1956 case WIN_PROC_32A:
1957 if (!proc->thunk.t_from16.proc) return 0;
1958 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
1959 hwnd, msg, wParam, lParam );
1960 case WIN_PROC_32W:
1961 if (!proc->thunk.t_from16.proc) return 0;
1962 return WINPROC_CallWndProc32Ptr( proc->thunk.t_from16.proc,
1963 hwnd, msg, wParam, lParam );
1964 default:
1965 fprintf( stderr, "CallWindowProc32W: invalid proc %p\n", proc );
1966 return 0;