Release 970415
[wine/testsucceed.git] / windows / winproc.c
blob4fbde9229f53c1bf056cdccd3b8f34358ee9424f
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 "callback.h"
11 #include "heap.h"
12 #include "selectors.h"
13 #include "stackframe.h"
14 #include "struct32.h"
15 #include "win.h"
16 #include "winproc.h"
17 #include "stddebug.h"
18 #include "debug.h"
20 /* Window procedure 16-to-32-bit thunk,
21 * see BuildSpec16Files() in tools/build.c */
23 typedef struct
25 BYTE popl_eax; /* popl %eax (return address) */
26 BYTE pushl_func; /* pushl $proc */
27 WNDPROC32 proc WINE_PACKED;
28 BYTE pushl_eax; /* pushl %eax */
29 WORD pushw_bp WINE_PACKED; /* pushw %bp */
30 BYTE pushl_thunk; /* pushl $thunkfrom16 */
31 void (*thunk32)() WINE_PACKED;
32 BYTE lcall; /* lcall cs:relay */
33 void (*relay)() WINE_PACKED; /* WINPROC_CallProc16To32A/W() */
34 WORD cs WINE_PACKED;
35 } WINPROC_THUNK_FROM16;
37 /* Window procedure 32-to-16-bit thunk,
38 * see BuildSpec32Files() in tools/build.c */
40 typedef struct
42 BYTE popl_eax; /* popl %eax (return address) */
43 BYTE pushl_func; /* pushl $proc */
44 WNDPROC16 proc WINE_PACKED;
45 BYTE pushl_eax; /* pushl %eax */
46 BYTE pushl_ebp; /* pushl %ebp */
47 BYTE pushl_name; /* pushl $name */
48 LPCSTR name WINE_PACKED;
49 BYTE pushl_thunk; /* pushl $thunkfrom32 */
50 void (*thunk32)() WINE_PACKED;
51 BYTE jmp; /* jmp relay (relative jump)*/
52 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
53 } WINPROC_THUNK_FROM32;
55 /* Simple jmp to call 32-bit procedure directly */
56 typedef struct
58 BYTE jmp; /* jmp proc (relative jump) */
59 WNDPROC32 proc WINE_PACKED;
60 } WINPROC_JUMP;
62 typedef union
64 WINPROC_THUNK_FROM16 t_from16;
65 WINPROC_THUNK_FROM32 t_from32;
66 } WINPROC_THUNK;
68 typedef struct tagWINDOWPROC
70 WINPROC_THUNK thunk; /* Thunk */
71 WINPROC_JUMP jmp; /* Jump */
72 struct tagWINDOWPROC *next; /* Next window proc */
73 UINT32 magic; /* Magic number */
74 WINDOWPROCTYPE type; /* Function type */
75 WINDOWPROCUSER user; /* Function user */
76 } WINDOWPROC;
78 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
80 #define WINPROC_THUNKPROC(pproc) \
81 (((pproc)->type == WIN_PROC_16) ? \
82 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
83 (WNDPROC16)((pproc)->thunk.t_from16.proc))
85 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
86 WPARAM16 wParam, LPARAM lParam,
87 WNDPROC32 func );
88 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
89 WPARAM16 wParam, LPARAM lParam,
90 WNDPROC32 func );
91 static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
92 UINT32 msg, WPARAM32 wParam,
93 LPARAM lParam );
94 static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
95 UINT32 msg, WPARAM32 wParam,
96 LPARAM lParam );
98 #ifndef WINELIB
99 extern void CallFrom16_long_wwwll(void);
100 extern void CallFrom32_stdcall_5(void);
101 #else
102 static void CallFrom16_long_wwwll(void) {}
103 static void CallFrom32_stdcall_5(void) {}
104 #endif /* WINELIB */
106 static HANDLE32 WinProcHeap;
108 /**********************************************************************
109 * WINPROC_Init
111 BOOL32 WINPROC_Init(void)
113 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
114 if (!WinProcHeap)
116 fprintf( stderr, "Unable to create winproc heap\n" );
117 return FALSE;
119 return TRUE;
123 /**********************************************************************
124 * WINPROC_GetPtr
126 * Return a pointer to the win proc.
128 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
130 BYTE *ptr;
131 WINDOWPROC *proc;
133 /* Check for a linear pointer */
135 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
137 ptr = (BYTE *)handle;
138 /* First check if it is the jmp address */
139 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
140 (int)&((WINDOWPROC *)0)->thunk;
141 /* Now it must be the thunk address */
142 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
143 /* Now we have a pointer to the WINDOWPROC struct */
144 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
145 return (WINDOWPROC *)ptr;
148 /* Check for a segmented pointer */
150 if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
152 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
153 if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
154 /* It must be the thunk address */
155 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
156 /* Now we have a pointer to the WINDOWPROC struct */
157 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
158 return (WINDOWPROC *)ptr;
161 return NULL;
165 /**********************************************************************
166 * WINPROC_AllocWinProc
168 * Allocate a new window procedure.
170 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
171 WINDOWPROCUSER user )
173 WINDOWPROC *proc, *oldproc;
175 /* Allocate a window procedure */
177 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
179 /* Check if the function is already a win proc */
181 if ((oldproc = WINPROC_GetPtr( func )))
183 *proc = *oldproc;
185 else
187 switch(type)
189 case WIN_PROC_16:
190 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
191 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
192 proc->thunk.t_from32.proc = func;
193 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
194 proc->thunk.t_from32.pushl_ebp = 0x55; /* pushl %ebp */
195 proc->thunk.t_from32.pushl_name = 0x68; /* pushl $name */
196 proc->thunk.t_from32.name = "WINPROC_CallProc32ATo16";
197 proc->thunk.t_from32.pushl_thunk = 0x68; /* pushl $thunkfrom32 */
198 proc->thunk.t_from32.thunk32 = (void(*)())WINPROC_CallProc32ATo16;
199 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
200 proc->thunk.t_from32.relay = /* relative jump */
201 (void (*)())((DWORD)CallFrom32_stdcall_5 -
202 (DWORD)(&proc->thunk.t_from32.relay + 1));
203 break;
204 case WIN_PROC_32A:
205 case WIN_PROC_32W:
206 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
207 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
208 proc->thunk.t_from16.proc = (FARPROC32)func;
209 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
210 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
211 proc->thunk.t_from16.pushl_thunk = 0x68; /* pushl $thunkfrom16 */
212 proc->thunk.t_from16.thunk32 = (type == WIN_PROC_32A) ?
213 (void(*)())WINPROC_CallProc16To32A :
214 (void(*)())WINPROC_CallProc16To32W;
215 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:relay */
216 proc->thunk.t_from16.relay = CallFrom16_long_wwwll;
217 proc->thunk.t_from16.cs = WINE_CODE_SELECTOR;
218 proc->jmp.jmp = 0xe9;
219 /* Fixup relative jump */
220 proc->jmp.proc = (WNDPROC32)((DWORD)func -
221 (DWORD)(&proc->jmp.proc + 1));
222 break;
223 default:
224 /* Should not happen */
225 break;
227 proc->magic = WINPROC_MAGIC;
228 proc->type = type;
229 proc->user = user;
231 proc->next = NULL;
232 dprintf_win( stddeb, "WINPROC_AllocWinProc(%08x,%d): returning %08x\n",
233 (UINT32)func, type, (UINT32)proc );
234 return proc;
238 /**********************************************************************
239 * WINPROC_GetProc
241 * Get a window procedure pointer that can be passed to the Windows program.
243 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
245 if (!proc) return NULL;
246 if (type == WIN_PROC_16) /* We want a 16:16 address */
248 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
249 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
250 else
251 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
252 &((WINDOWPROC *)proc)->thunk );
254 else /* We want a 32-bit address */
256 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
257 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
258 else
259 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
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 dprintf_win( stddeb, "WINPROC_SetProc(%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 dprintf_win( stddeb, "WINPROC_FreeProc: 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.
393 INT32 WINPROC_MapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
395 switch(msg)
397 case WM_GETTEXT:
399 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
400 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
401 if (!ptr) return -1;
402 *ptr++ = *plparam; /* Store previous lParam */
403 *plparam = (LPARAM)ptr;
405 return 1;
406 case WM_SETTEXT:
407 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
408 return (*plparam ? 1 : -1);
409 case WM_NCCREATE:
410 case WM_CREATE:
412 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
413 sizeof(*cs) );
414 if (!cs) return -1;
415 *cs = *(CREATESTRUCT32W *)*plparam;
416 if (HIWORD(cs->lpszName))
417 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
418 (LPCSTR)cs->lpszName );
419 if (HIWORD(cs->lpszClass))
420 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
421 (LPCSTR)cs->lpszClass );
422 *plparam = (LPARAM)cs;
424 return 1;
425 case WM_MDICREATE:
427 MDICREATESTRUCT32W *cs =
428 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
429 if (!cs) return -1;
430 *cs = *(MDICREATESTRUCT32W *)*plparam;
431 if (HIWORD(cs->szClass))
432 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
433 (LPCSTR)cs->szClass );
434 if (HIWORD(cs->szTitle))
435 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
436 (LPCSTR)cs->szTitle );
437 *plparam = (LPARAM)cs;
439 return 1;
440 case WM_ASKCBFORMATNAME:
441 case WM_DEVMODECHANGE:
442 case WM_MDIACTIVATE:
443 case WM_PAINTCLIPBOARD:
444 case WM_SIZECLIPBOARD:
445 case WM_WININICHANGE:
446 fprintf( stderr, "MapMsg32ATo32W: message %04x needs translation\n",
447 msg );
448 return -1;
449 default: /* No translation needed */
450 return 0;
455 /**********************************************************************
456 * WINPROC_UnmapMsg32ATo32W
458 * Unmap a message that was mapped from Ansi to Unicode.
460 void WINPROC_UnmapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
462 switch(msg)
464 case WM_GETTEXT:
466 LPARAM *ptr = (LPARAM *)lParam - 1;
467 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)(ptr + 1), wParam );
468 HeapFree( SystemHeap, 0, ptr );
470 break;
471 case WM_SETTEXT:
472 HeapFree( SystemHeap, 0, (void *)lParam );
473 break;
474 case WM_NCCREATE:
475 case WM_CREATE:
477 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
478 if (HIWORD(cs->lpszName))
479 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
480 if (HIWORD(cs->lpszClass))
481 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
482 HeapFree( SystemHeap, 0, cs );
484 break;
485 case WM_MDICREATE:
487 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
488 if (HIWORD(cs->szTitle))
489 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
490 if (HIWORD(cs->szClass))
491 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
492 HeapFree( SystemHeap, 0, cs );
494 break;
499 /**********************************************************************
500 * WINPROC_MapMsg32WTo32A
502 * Map a message from Unicode to Ansi.
503 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
505 INT32 WINPROC_MapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
507 switch(msg)
509 case WM_GETTEXT:
511 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
512 wParam + sizeof(LPARAM) );
513 if (!ptr) return -1;
514 *ptr++ = *plparam; /* Store previous lParam */
515 *plparam = (LPARAM)ptr;
517 return 1;
518 case WM_SETTEXT:
519 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
520 return (*plparam ? 1 : -1);
521 case WM_NCCREATE:
522 case WM_CREATE:
524 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
525 sizeof(*cs) );
526 if (!cs) return -1;
527 *cs = *(CREATESTRUCT32A *)*plparam;
528 if (HIWORD(cs->lpszName))
529 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
530 (LPCWSTR)cs->lpszName );
531 if (HIWORD(cs->lpszClass))
532 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
533 (LPCWSTR)cs->lpszClass);
534 *plparam = (LPARAM)cs;
536 return 1;
537 case WM_MDICREATE:
539 MDICREATESTRUCT32A *cs =
540 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
541 if (!cs) return -1;
542 *cs = *(MDICREATESTRUCT32A *)*plparam;
543 if (HIWORD(cs->szTitle))
544 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
545 (LPCWSTR)cs->szTitle );
546 if (HIWORD(cs->szClass))
547 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
548 (LPCWSTR)cs->szClass );
549 *plparam = (LPARAM)cs;
551 return 1;
552 case WM_ASKCBFORMATNAME:
553 case WM_DEVMODECHANGE:
554 case WM_MDIACTIVATE:
555 case WM_PAINTCLIPBOARD:
556 case WM_SIZECLIPBOARD:
557 case WM_WININICHANGE:
558 fprintf( stderr, "MapMsg32WTo32A: message %04x needs translation\n",
559 msg );
560 return -1;
561 default: /* No translation needed */
562 return 0;
567 /**********************************************************************
568 * WINPROC_UnmapMsg32WTo32A
570 * Unmap a message that was mapped from Unicode to Ansi.
572 void WINPROC_UnmapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
574 switch(msg)
576 case WM_GETTEXT:
578 LPARAM *ptr = (LPARAM *)lParam - 1;
579 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)(ptr + 1), wParam );
580 HeapFree( SystemHeap, 0, ptr );
582 break;
583 case WM_SETTEXT:
584 HeapFree( SystemHeap, 0, (void *)lParam );
585 break;
586 case WM_NCCREATE:
587 case WM_CREATE:
589 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
590 if (HIWORD(cs->lpszName))
591 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
592 if (HIWORD(cs->lpszClass))
593 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
594 HeapFree( SystemHeap, 0, cs );
596 break;
597 case WM_MDICREATE:
599 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
600 if (HIWORD(cs->szTitle))
601 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
602 if (HIWORD(cs->szClass))
603 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
604 HeapFree( SystemHeap, 0, cs );
606 break;
611 /**********************************************************************
612 * WINPROC_MapMsg16To32A
614 * Map a message from 16- to 32-bit Ansi.
615 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
617 INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
618 WPARAM32 *pwparam32, LPARAM *plparam )
620 *pmsg32 = (UINT32)msg16;
621 *pwparam32 = (WPARAM32)wParam16;
622 switch(msg16)
624 case WM_ACTIVATE:
625 case WM_CHARTOITEM:
626 case WM_COMMAND:
627 case WM_VKEYTOITEM:
628 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
629 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
630 return 0;
631 case WM_HSCROLL:
632 case WM_VSCROLL:
633 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
634 *plparam = (LPARAM)(HWND32)HIWORD(*plparam);
635 return 0;
636 case WM_CTLCOLOR:
637 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
638 *pwparam32 = (WPARAM32)(HDC32)wParam16;
639 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
640 return 0;
641 case WM_COMPAREITEM:
643 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
644 COMPAREITEMSTRUCT32 *cis = (COMPAREITEMSTRUCT32 *)
645 HeapAlloc(SystemHeap, 0, sizeof(*cis));
646 if (!cis) return -1;
647 cis->CtlType = cis16->CtlType;
648 cis->CtlID = cis16->CtlID;
649 cis->hwndItem = cis16->hwndItem;
650 cis->itemID1 = cis16->itemID1;
651 cis->itemData1 = cis16->itemData1;
652 cis->itemID2 = cis16->itemID2;
653 cis->itemData2 = cis16->itemData2;
654 cis->dwLocaleId = 0; /* FIXME */
655 *plparam = (LPARAM)cis;
657 return 1;
658 case WM_DELETEITEM:
660 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
661 DELETEITEMSTRUCT32 *dis = (DELETEITEMSTRUCT32 *)
662 HeapAlloc(SystemHeap, 0, sizeof(*dis));
663 if (!dis) return -1;
664 dis->CtlType = dis16->CtlType;
665 dis->CtlID = dis16->CtlID;
666 dis->hwndItem = dis16->hwndItem;
667 dis->itemData = dis16->itemData;
668 *plparam = (LPARAM)dis;
670 return 1;
671 case WM_MEASUREITEM:
673 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
674 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)
675 HeapAlloc(SystemHeap, 0,
676 sizeof(*mis) + sizeof(LPARAM));
677 if (!mis) return -1;
678 mis->CtlType = mis16->CtlType;
679 mis->CtlID = mis16->CtlID;
680 mis->itemID = mis16->itemID;
681 mis->itemWidth = mis16->itemWidth;
682 mis->itemHeight = mis16->itemHeight;
683 mis->itemData = mis16->itemData;
684 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
685 *plparam = (LPARAM)mis;
687 return 1;
688 case WM_DRAWITEM:
690 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
691 DRAWITEMSTRUCT32 *dis = (DRAWITEMSTRUCT32*)HeapAlloc(SystemHeap, 0,
692 sizeof(*dis));
693 if (!dis) return -1;
694 dis->CtlType = dis16->CtlType;
695 dis->CtlID = dis16->CtlID;
696 dis->itemID = dis16->itemID;
697 dis->itemAction = dis16->itemAction;
698 dis->itemState = dis16->itemState;
699 dis->hwndItem = dis16->hwndItem;
700 dis->hDC = dis16->hDC;
701 dis->itemData = dis16->itemData;
702 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
703 *plparam = (LPARAM)dis;
705 return 1;
706 case WM_GETMINMAXINFO:
708 MINMAXINFO32 *mmi = (MINMAXINFO32 *)HeapAlloc( SystemHeap, 0,
709 sizeof(*mmi) + sizeof(LPARAM));
710 if (!mmi) return -1;
711 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
712 mmi );
713 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
714 *plparam = (LPARAM)mmi;
716 return 1;
717 case WM_GETTEXT:
718 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
719 return 0;
720 case WM_MDICREATE:
722 MDICREATESTRUCT16 *cs16 =
723 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
724 MDICREATESTRUCT32A *cs =
725 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
726 sizeof(*cs) + sizeof(LPARAM) );
727 if (!cs) return -1;
728 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
729 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
730 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
731 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
732 *plparam = (LPARAM)cs;
734 return 1;
735 case WM_MDISETMENU:
736 *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
737 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
738 return 0;
739 case WM_MENUCHAR:
740 case WM_MENUSELECT:
741 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
742 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
743 return 0;
744 case WM_NCCALCSIZE:
746 NCCALCSIZE_PARAMS16 *nc16;
747 NCCALCSIZE_PARAMS32 *nc;
749 nc = (NCCALCSIZE_PARAMS32 *)HeapAlloc( SystemHeap, 0,
750 sizeof(*nc) + sizeof(LPARAM) );
751 if (!nc) return -1;
752 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
753 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
754 if (wParam16)
756 nc->lppos = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
757 sizeof(*nc->lppos) );
758 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
759 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
760 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
762 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
763 *plparam = (LPARAM)nc;
765 return 1;
766 case WM_NCCREATE:
767 case WM_CREATE:
769 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
770 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
771 sizeof(*cs) + sizeof(LPARAM) );
772 if (!cs) return -1;
773 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
774 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
775 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
776 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
777 *plparam = (LPARAM)cs;
779 return 1;
780 case WM_PARENTNOTIFY:
781 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
783 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
784 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
786 return 0;
787 case WM_SETTEXT:
788 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
789 return 0;
790 case WM_WINDOWPOSCHANGING:
791 case WM_WINDOWPOSCHANGED:
793 WINDOWPOS32 *wp = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
794 sizeof(*wp) + sizeof(LPARAM) );
795 if (!wp) return -1;
796 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
797 wp );
798 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
799 *plparam = (LPARAM)wp;
801 return 1;
802 case WM_ASKCBFORMATNAME:
803 case WM_DEVMODECHANGE:
804 case WM_MDIACTIVATE:
805 case WM_PAINTCLIPBOARD:
806 case WM_SIZECLIPBOARD:
807 case WM_WININICHANGE:
808 fprintf( stderr, "MapMsg16To32A: message %04x needs translation\n",
809 msg16 );
810 return -1;
812 default: /* No translation needed */
813 return 0;
818 /**********************************************************************
819 * WINPROC_UnmapMsg16To32A
821 * Unmap a message that was mapped from 16- to 32-bit Ansi.
823 void WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
825 switch(msg)
827 case WM_COMPAREITEM:
828 case WM_DELETEITEM:
829 case WM_DRAWITEM:
830 HeapFree( SystemHeap, 0, (LPVOID)lParam );
831 break;
832 case WM_MEASUREITEM:
834 MEASUREITEMSTRUCT16 *mis16;
835 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)lParam;
836 lParam = *(LPARAM *)(mis + 1);
837 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
838 mis16->itemWidth = (UINT16)mis->itemWidth;
839 mis16->itemHeight = (UINT16)mis->itemHeight;
840 HeapFree( SystemHeap, 0, mis );
842 break;
843 case WM_GETMINMAXINFO:
845 MINMAXINFO32 *mmi = (MINMAXINFO32 *)lParam;
846 lParam = *(LPARAM *)(mmi + 1);
847 STRUCT32_MINMAXINFO32to16( mmi,
848 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
849 HeapFree( SystemHeap, 0, mmi );
851 break;
852 case WM_MDICREATE:
854 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
855 lParam = *(LPARAM *)(cs + 1);
856 STRUCT32_MDICREATESTRUCT32Ato16( cs,
857 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
858 HeapFree( SystemHeap, 0, cs );
860 break;
861 case WM_NCCALCSIZE:
863 NCCALCSIZE_PARAMS16 *nc16;
864 NCCALCSIZE_PARAMS32 *nc = (NCCALCSIZE_PARAMS32 *)lParam;
865 lParam = *(LPARAM *)(nc + 1);
866 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
867 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
868 if (wParam)
870 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
871 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
872 if (nc->lppos)
874 STRUCT32_WINDOWPOS32to16( nc->lppos,
875 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
876 HeapFree( SystemHeap, 0, nc->lppos );
879 HeapFree( SystemHeap, 0, nc );
881 break;
882 case WM_NCCREATE:
883 case WM_CREATE:
885 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
886 lParam = *(LPARAM *)(cs + 1);
887 STRUCT32_CREATESTRUCT32Ato16( cs,
888 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
889 HeapFree( SystemHeap, 0, cs );
891 break;
892 case WM_WINDOWPOSCHANGING:
893 case WM_WINDOWPOSCHANGED:
895 WINDOWPOS32 *wp = (WINDOWPOS32 *)lParam;
896 lParam = *(LPARAM *)(wp + 1);
897 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
898 HeapFree( SystemHeap, 0, wp );
900 break;
905 /**********************************************************************
906 * WINPROC_MapMsg16To32W
908 * Map a message from 16- to 32-bit Unicode.
909 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
911 INT32 WINPROC_MapMsg16To32W( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
912 WPARAM32 *pwparam32, LPARAM *plparam )
914 switch(msg16)
916 case WM_GETTEXT:
917 case WM_SETTEXT:
918 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
919 return WINPROC_MapMsg32ATo32W( *pmsg32, *pwparam32, plparam );
920 case WM_NCCREATE:
921 case WM_CREATE:
923 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
924 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
925 sizeof(*cs) + sizeof(LPARAM) );
926 if (!cs) return -1;
927 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCT32A *)cs );
928 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
929 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
930 if (HIWORD(cs->lpszName))
931 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
932 (LPCSTR)cs->lpszName );
933 if (HIWORD(cs->lpszClass))
934 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
935 (LPCSTR)cs->lpszClass );
936 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
937 *plparam = (LPARAM)cs;
939 return 1;
940 case WM_MDICREATE:
942 MDICREATESTRUCT16 *cs16 =
943 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
944 MDICREATESTRUCT32W *cs =
945 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
946 sizeof(*cs) + sizeof(LPARAM) );
947 if (!cs) return -1;
948 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCT32A *)cs );
949 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
950 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
951 if (HIWORD(cs->szTitle))
952 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
953 (LPCSTR)cs->szTitle );
954 if (HIWORD(cs->szClass))
955 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
956 (LPCSTR)cs->szClass );
957 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
958 *plparam = (LPARAM)cs;
960 return 1;
961 default: /* No Unicode translation needed */
962 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
963 pwparam32, plparam );
968 /**********************************************************************
969 * WINPROC_UnmapMsg16To32W
971 * Unmap a message that was mapped from 16- to 32-bit Unicode.
973 void WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
975 switch(msg)
977 case WM_GETTEXT:
978 case WM_SETTEXT:
979 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
980 break;
981 case WM_NCCREATE:
982 case WM_CREATE:
984 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
985 lParam = *(LPARAM *)(cs + 1);
986 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
987 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
988 if (HIWORD(cs->lpszName))
989 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
990 if (HIWORD(cs->lpszClass))
991 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
992 HeapFree( SystemHeap, 0, cs );
994 break;
995 case WM_MDICREATE:
997 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
998 lParam = *(LPARAM *)(cs + 1);
999 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
1000 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1001 if (HIWORD(cs->szTitle))
1002 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1003 if (HIWORD(cs->szClass))
1004 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1005 HeapFree( SystemHeap, 0, cs );
1007 break;
1008 default:
1009 WINPROC_UnmapMsg16To32A( msg, wParam, lParam );
1010 break;
1015 /**********************************************************************
1016 * WINPROC_MapMsg32ATo16
1018 * Map a message from 32-bit Ansi to 16-bit.
1019 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1021 INT32 WINPROC_MapMsg32ATo16( UINT32 msg32, WPARAM32 wParam32, UINT16 *pmsg16,
1022 WPARAM16 *pwparam16, LPARAM *plparam )
1024 *pmsg16 = (UINT16)msg32;
1025 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1026 switch(msg32)
1028 case BM_GETCHECK32:
1029 case BM_SETCHECK32:
1030 case BM_GETSTATE32:
1031 case BM_SETSTATE32:
1032 case BM_SETSTYLE32:
1033 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK32);
1034 return 0;
1036 case EM_GETSEL32:
1037 case EM_GETRECT32:
1038 case EM_SETRECT32:
1039 case EM_SETRECTNP32:
1040 case EM_SCROLL32:
1041 case EM_LINESCROLL32:
1042 case EM_SCROLLCARET32:
1043 case EM_GETMODIFY32:
1044 case EM_SETMODIFY32:
1045 case EM_GETLINECOUNT32:
1046 case EM_LINEINDEX32:
1047 case EM_SETHANDLE32:
1048 case EM_GETHANDLE32:
1049 case EM_GETTHUMB32:
1050 case EM_LINELENGTH32:
1051 case EM_REPLACESEL32:
1052 case EM_GETLINE32:
1053 case EM_LIMITTEXT32:
1054 case EM_CANUNDO32:
1055 case EM_UNDO32:
1056 case EM_FMTLINES32:
1057 case EM_LINEFROMCHAR32:
1058 case EM_SETTABSTOPS32:
1059 case EM_SETPASSWORDCHAR32:
1060 case EM_EMPTYUNDOBUFFER32:
1061 case EM_GETFIRSTVISIBLELINE32:
1062 case EM_SETREADONLY32:
1063 case EM_SETWORDBREAKPROC32:
1064 case EM_GETWORDBREAKPROC32:
1065 case EM_GETPASSWORDCHAR32:
1066 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL32);
1067 return 0;
1069 case LB_CARETOFF32:
1070 case LB_CARETON32:
1071 case LB_DELETESTRING32:
1072 case LB_GETANCHORINDEX32:
1073 case LB_GETCARETINDEX32:
1074 case LB_GETCOUNT32:
1075 case LB_GETCURSEL32:
1076 case LB_GETHORIZONTALEXTENT32:
1077 case LB_GETITEMDATA32:
1078 case LB_GETITEMHEIGHT32:
1079 case LB_GETSEL32:
1080 case LB_GETSELCOUNT32:
1081 case LB_GETTEXTLEN32:
1082 case LB_GETTOPINDEX32:
1083 case LB_RESETCONTENT32:
1084 case LB_SELITEMRANGE32:
1085 case LB_SELITEMRANGEEX32:
1086 case LB_SETANCHORINDEX32:
1087 case LB_SETCARETINDEX32:
1088 case LB_SETCOLUMNWIDTH32:
1089 case LB_SETCURSEL32:
1090 case LB_SETHORIZONTALEXTENT32:
1091 case LB_SETITEMDATA32:
1092 case LB_SETITEMHEIGHT32:
1093 case LB_SETSEL32:
1094 case LB_SETTOPINDEX32:
1095 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1096 return 0;
1097 case CB_DELETESTRING32:
1098 case CB_GETCOUNT32:
1099 case CB_GETLBTEXTLEN32:
1100 case CB_LIMITTEXT32:
1101 case CB_RESETCONTENT32:
1102 case CB_SETEDITSEL32:
1103 case CB_GETCURSEL32:
1104 case CB_SETCURSEL32:
1105 case CB_SHOWDROPDOWN32:
1106 case CB_SETITEMDATA32:
1107 case CB_SETITEMHEIGHT32:
1108 case CB_GETITEMHEIGHT32:
1109 case CB_SETEXTENDEDUI32:
1110 case CB_GETEXTENDEDUI32:
1111 case CB_GETDROPPEDSTATE32:
1112 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1113 return 0;
1114 case CB_GETEDITSEL32:
1115 *pmsg16 = CB_GETEDITSEL16;
1116 return 1;
1118 case LB_ADDSTRING32:
1119 case LB_FINDSTRING32:
1120 case LB_FINDSTRINGEXACT32:
1121 case LB_INSERTSTRING32:
1122 case LB_SELECTSTRING32:
1123 case LB_DIR32:
1124 case LB_ADDFILE32:
1126 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1127 if (!str) return -1;
1128 *plparam = (LPARAM)SEGPTR_GET(str);
1130 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1131 return 1;
1133 case CB_ADDSTRING32:
1134 case CB_FINDSTRING32:
1135 case CB_FINDSTRINGEXACT32:
1136 case CB_INSERTSTRING32:
1137 case CB_SELECTSTRING32:
1138 case CB_DIR32:
1140 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1141 if (!str) return -1;
1142 *plparam = (LPARAM)SEGPTR_GET(str);
1144 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1145 return 1;
1147 case LB_GETITEMRECT32:
1149 RECT16 *rect;
1150 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1151 if (!rect) return -1;
1152 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1153 *plparam = (LPARAM)SEGPTR_GET(rect);
1155 *pmsg16 = LB_GETITEMRECT16;
1156 return 1;
1157 case LB_GETSELITEMS32:
1159 LPINT16 items;
1160 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1161 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1162 + sizeof(LPARAM)))) return -1;
1163 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1164 *plparam = (LPARAM)SEGPTR_GET(items);
1166 *pmsg16 = LB_GETSELITEMS16;
1167 return 1;
1168 case LB_SETTABSTOPS32:
1169 if (wParam32)
1171 INT32 i;
1172 LPINT16 stops;
1173 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1174 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1175 + sizeof(LPARAM)))) return -1;
1176 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT32)*plparam+i);
1177 *plparam = (LPARAM)SEGPTR_GET(stops);
1178 return 1;
1180 *pmsg16 = LB_SETTABSTOPS16;
1181 return 0;
1183 case CB_GETDROPPEDCONTROLRECT32:
1185 RECT16 *rect;
1186 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1187 if (!rect) return -1;
1188 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1189 *plparam = (LPARAM)SEGPTR_GET(rect);
1191 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1192 return 1;
1194 case LB_GETTEXT32:
1195 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1196 *pmsg16 = LB_GETTEXT16;
1197 return 1;
1199 case CB_GETLBTEXT32:
1200 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1201 *pmsg16 = CB_GETLBTEXT16;
1202 return 1;
1204 case EM_SETSEL32:
1205 *pwparam16 = 0;
1206 *plparam = MAKELONG( (INT16)(INT32)wParam32, (INT16)*plparam );
1207 *pmsg16 = EM_SETSEL16;
1208 return 0;
1210 case WM_ACTIVATE:
1211 case WM_CHARTOITEM:
1212 case WM_COMMAND:
1213 case WM_VKEYTOITEM:
1214 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1215 return 0;
1216 case WM_HSCROLL:
1217 case WM_VSCROLL:
1218 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1219 return 0;
1220 case WM_CTLCOLORMSGBOX:
1221 case WM_CTLCOLOREDIT:
1222 case WM_CTLCOLORLISTBOX:
1223 case WM_CTLCOLORBTN:
1224 case WM_CTLCOLORDLG:
1225 case WM_CTLCOLORSCROLLBAR:
1226 case WM_CTLCOLORSTATIC:
1227 *pmsg16 = WM_CTLCOLOR;
1228 *plparam = MAKELPARAM( (HWND16)*plparam,
1229 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1230 return 0;
1231 case WM_COMPAREITEM:
1233 COMPAREITEMSTRUCT32 *cis32 = (COMPAREITEMSTRUCT32 *)*plparam;
1234 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1235 if (!cis) return -1;
1236 cis->CtlType = (UINT16)cis32->CtlType;
1237 cis->CtlID = (UINT16)cis32->CtlID;
1238 cis->hwndItem = (HWND16)cis32->hwndItem;
1239 cis->itemID1 = (UINT16)cis32->itemID1;
1240 cis->itemData1 = cis32->itemData1;
1241 cis->itemID2 = (UINT16)cis32->itemID2;
1242 cis->itemData2 = cis32->itemData2;
1243 *plparam = (LPARAM)SEGPTR_GET(cis);
1245 return 1;
1246 case WM_DELETEITEM:
1248 DELETEITEMSTRUCT32 *dis32 = (DELETEITEMSTRUCT32 *)*plparam;
1249 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1250 if (!dis) return -1;
1251 dis->CtlType = (UINT16)dis32->CtlType;
1252 dis->CtlID = (UINT16)dis32->CtlID;
1253 dis->itemID = (UINT16)dis32->itemID;
1254 dis->hwndItem = (HWND16)dis32->hwndItem;
1255 dis->itemData = dis32->itemData;
1256 *plparam = (LPARAM)SEGPTR_GET(dis);
1258 return 1;
1259 case WM_DRAWITEM:
1261 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)*plparam;
1262 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1263 if (!dis) return -1;
1264 dis->CtlType = (UINT16)dis32->CtlType;
1265 dis->CtlID = (UINT16)dis32->CtlID;
1266 dis->itemID = (UINT16)dis32->itemID;
1267 dis->itemAction = (UINT16)dis32->itemAction;
1268 dis->itemState = (UINT16)dis32->itemState;
1269 dis->hwndItem = (HWND16)dis32->hwndItem;
1270 dis->hDC = (HDC16)dis32->hDC;
1271 dis->itemData = dis32->itemData;
1272 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1273 *plparam = (LPARAM)SEGPTR_GET(dis);
1275 return 1;
1276 case WM_MEASUREITEM:
1278 MEASUREITEMSTRUCT32 *mis32 = (MEASUREITEMSTRUCT32 *)*plparam;
1279 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1280 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1281 if (!mis) return -1;
1282 mis->CtlType = (UINT16)mis32->CtlType;
1283 mis->CtlID = (UINT16)mis32->CtlID;
1284 mis->itemID = (UINT16)mis32->itemID;
1285 mis->itemWidth = (UINT16)mis32->itemWidth;
1286 mis->itemHeight = (UINT16)mis32->itemHeight;
1287 mis->itemData = mis32->itemData;
1288 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1289 *plparam = (LPARAM)SEGPTR_GET(mis);
1291 return 1;
1292 case WM_GETMINMAXINFO:
1294 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1295 sizeof(LPARAM) );
1296 if (!mmi) return -1;
1297 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)*plparam, mmi );
1298 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1299 *plparam = (LPARAM)SEGPTR_GET(mmi);
1301 return 1;
1302 case WM_GETTEXT:
1304 LPSTR str;
1305 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1306 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1307 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1308 *plparam = (LPARAM)SEGPTR_GET(str);
1310 return 1;
1311 case WM_MDICREATE:
1313 MDICREATESTRUCT16 *cs;
1314 MDICREATESTRUCT32A *cs32 = (MDICREATESTRUCT32A *)*plparam;
1315 LPSTR name, cls;
1317 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1318 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1319 name = SEGPTR_STRDUP( cs32->szTitle );
1320 cls = SEGPTR_STRDUP( cs32->szClass );
1321 cs->szTitle = SEGPTR_GET(name);
1322 cs->szClass = SEGPTR_GET(cls);
1323 *plparam = (LPARAM)SEGPTR_GET(cs);
1325 return 1;
1326 case WM_MDISETMENU:
1327 *pwparam16 = TRUE; /* FIXME? */
1328 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1329 (HMENU16)LOWORD(*plparam) );
1330 return 0;
1331 case WM_MENUCHAR:
1332 case WM_MENUSELECT:
1333 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1334 return 0;
1335 case WM_NCCALCSIZE:
1337 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
1338 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1339 if (!nc) return -1;
1341 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1342 if (wParam32)
1344 WINDOWPOS16 *wp;
1345 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1346 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1347 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1349 SEGPTR_FREE(nc);
1350 return -1;
1352 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1353 nc->lppos = SEGPTR_GET(wp);
1355 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1356 *plparam = (LPARAM)SEGPTR_GET(nc);
1358 return 1;
1359 case WM_NCCREATE:
1360 case WM_CREATE:
1362 CREATESTRUCT16 *cs;
1363 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)*plparam;
1364 LPSTR name, cls;
1366 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1367 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1368 name = SEGPTR_STRDUP( cs32->lpszName );
1369 cls = SEGPTR_STRDUP( cs32->lpszClass );
1370 cs->lpszName = SEGPTR_GET(name);
1371 cs->lpszClass = SEGPTR_GET(cls);
1372 *plparam = (LPARAM)SEGPTR_GET(cs);
1374 return 1;
1375 case WM_PARENTNOTIFY:
1376 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1377 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1378 /* else nothing to do */
1379 return 0;
1380 case WM_SETTEXT:
1382 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1383 if (!str) return -1;
1384 *plparam = (LPARAM)SEGPTR_GET(str);
1386 return 1;
1387 case WM_WINDOWPOSCHANGING:
1388 case WM_WINDOWPOSCHANGED:
1390 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1391 sizeof(LPARAM) );
1392 if (!wp) return -1;
1393 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)*plparam, wp );
1394 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1395 *plparam = (LPARAM)SEGPTR_GET(wp);
1397 return 1;
1398 case WM_ASKCBFORMATNAME:
1399 case WM_DEVMODECHANGE:
1400 case WM_MDIACTIVATE:
1401 case WM_PAINTCLIPBOARD:
1402 case WM_SIZECLIPBOARD:
1403 case WM_WININICHANGE:
1404 fprintf( stderr, "MapMsg32ATo16: message %04x needs translation\n",
1405 msg32 );
1406 return -1;
1408 default: /* No translation needed */
1409 return 0;
1414 /**********************************************************************
1415 * WINPROC_UnmapMsg32ATo16
1417 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1419 void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM32 wParam,
1420 LPARAM lParam, MSGPARAM16* p16 )
1422 switch(msg)
1424 case LB_ADDFILE32:
1425 case LB_ADDSTRING32:
1426 case LB_DIR32:
1427 case LB_FINDSTRING32:
1428 case LB_FINDSTRINGEXACT32:
1429 case LB_INSERTSTRING32:
1430 case LB_SELECTSTRING32:
1431 case LB_SETTABSTOPS32:
1432 case CB_ADDSTRING32:
1433 case CB_FINDSTRING32:
1434 case CB_FINDSTRINGEXACT32:
1435 case CB_INSERTSTRING32:
1436 case CB_SELECTSTRING32:
1437 case CB_DIR32:
1438 case WM_COMPAREITEM:
1439 case WM_DELETEITEM:
1440 case WM_DRAWITEM:
1441 case WM_SETTEXT:
1442 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1443 break;
1445 case CB_GETDROPPEDCONTROLRECT32:
1446 case LB_GETITEMRECT32:
1448 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1449 p16->lParam = *(LPARAM *)(rect + 1);
1450 CONV_RECT16TO32( rect, (RECT32 *)(p16->lParam));
1451 SEGPTR_FREE( rect );
1453 break;
1454 case LB_GETSELITEMS32:
1456 INT32 i;
1457 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1458 p16->lParam = *((LPARAM *)items - 1);
1459 for (i = 0; i < p16->wParam; i++) *((LPINT32)(p16->lParam) + i) = items[i];
1460 SEGPTR_FREE( (LPARAM *)items - 1 );
1462 break;
1464 case CB_GETEDITSEL32:
1465 if( wParam )
1466 *((LPUINT32)(wParam)) = LOWORD(p16->lResult);
1467 if( lParam )
1468 *((LPUINT32)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1469 break;
1471 case LB_GETTEXT32:
1472 case CB_GETLBTEXT32:
1473 UnMapLS( (SEGPTR)(p16->lParam) );
1474 break;
1476 case WM_MEASUREITEM:
1478 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1479 MEASUREITEMSTRUCT32 *mis32 = *(MEASUREITEMSTRUCT32 **)(mis + 1);
1480 mis32->itemWidth = mis->itemWidth;
1481 mis32->itemHeight = mis->itemHeight;
1482 SEGPTR_FREE(mis);
1484 break;
1485 case WM_GETMINMAXINFO:
1487 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1488 p16->lParam = *(LPARAM *)(mmi + 1);
1489 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)(p16->lParam) );
1490 SEGPTR_FREE(mmi);
1492 break;
1493 case WM_GETTEXT:
1495 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1496 p16->lParam = *((LPARAM *)str - 1);
1497 lstrcpyn32A( (LPSTR)(p16->lParam), str, p16->wParam );
1498 SEGPTR_FREE( (LPARAM *)str - 1 );
1500 break;
1501 case WM_MDICREATE:
1503 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1504 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1505 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1506 SEGPTR_FREE( cs );
1508 break;
1509 case WM_NCCALCSIZE:
1511 NCCALCSIZE_PARAMS32 *nc32;
1512 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
1513 p16->lParam = *(LPARAM *)(nc + 1);
1514 nc32 = (NCCALCSIZE_PARAMS32 *)(p16->lParam);
1515 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1516 if (p16->wParam)
1518 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1519 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1520 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1521 nc32->lppos );
1522 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1524 SEGPTR_FREE(nc);
1526 break;
1527 case WM_NCCREATE:
1528 case WM_CREATE:
1530 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1531 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1532 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1533 SEGPTR_FREE( cs );
1535 break;
1536 case WM_WINDOWPOSCHANGING:
1537 case WM_WINDOWPOSCHANGED:
1539 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
1540 p16->lParam = *(LPARAM *)(wp + 1);
1541 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)p16->lParam );
1542 SEGPTR_FREE(wp);
1544 break;
1549 /**********************************************************************
1550 * WINPROC_MapMsg32WTo16
1552 * Map a message from 32-bit Unicode to 16-bit.
1553 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1555 INT32 WINPROC_MapMsg32WTo16( UINT32 msg32, WPARAM32 wParam32, UINT16 *pmsg16,
1556 WPARAM16 *pwparam16, LPARAM *plparam )
1558 switch(msg32)
1560 case LB_ADDSTRING32:
1561 case LB_FINDSTRING32:
1562 case LB_FINDSTRINGEXACT32:
1563 case LB_INSERTSTRING32:
1564 case LB_SELECTSTRING32:
1565 case LB_DIR32:
1566 case LB_ADDFILE32:
1568 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1569 if (!str) return -1;
1570 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1571 *plparam = (LPARAM)SEGPTR_GET(str);
1573 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1574 return 1;
1576 case CB_ADDSTRING32:
1577 case CB_FINDSTRING32:
1578 case CB_FINDSTRINGEXACT32:
1579 case CB_INSERTSTRING32:
1580 case CB_SELECTSTRING32:
1581 case CB_DIR32:
1583 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1584 if (!str) return -1;
1585 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1586 *plparam = (LPARAM)SEGPTR_GET(str);
1588 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING32);
1589 return 1;
1591 case WM_NCCREATE:
1592 case WM_CREATE:
1594 CREATESTRUCT16 *cs;
1595 CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
1596 LPSTR name, cls;
1598 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1599 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
1600 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
1601 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
1602 cs->lpszName = SEGPTR_GET(name);
1603 cs->lpszClass = SEGPTR_GET(cls);
1604 *pmsg16 = (UINT16)msg32;
1605 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1606 *plparam = (LPARAM)SEGPTR_GET(cs);
1608 return 1;
1609 case WM_MDICREATE:
1611 MDICREATESTRUCT16 *cs;
1612 MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
1613 LPSTR name, cls;
1615 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1616 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
1617 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
1618 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
1619 cs->szTitle = SEGPTR_GET(name);
1620 cs->szClass = SEGPTR_GET(cls);
1621 *pmsg16 = (UINT16)msg32;
1622 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1623 *plparam = (LPARAM)SEGPTR_GET(cs);
1625 return 1;
1626 case WM_SETTEXT:
1628 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1629 if (!str) return -1;
1630 *pmsg16 = (UINT16)msg32;
1631 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1632 *plparam = (LPARAM)SEGPTR_GET(str);
1634 return 1;
1635 default: /* No Unicode translation needed */
1636 return WINPROC_MapMsg32ATo16( msg32, wParam32, pmsg16,
1637 pwparam16, plparam );
1642 /**********************************************************************
1643 * WINPROC_UnmapMsg32WTo16
1645 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1647 void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam,
1648 LPARAM lParam, MSGPARAM16* p16 )
1650 switch(msg)
1652 case WM_GETTEXT:
1654 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1655 p16->lParam = *((LPARAM *)str - 1);
1656 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
1657 SEGPTR_FREE( (LPARAM *)str - 1 );
1659 break;
1660 default:
1661 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, p16 );
1662 break;
1667 /**********************************************************************
1668 * WINPROC_CallProc32ATo32W
1670 * Call a window procedure, translating args from Ansi to Unicode.
1672 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
1673 UINT32 msg, WPARAM32 wParam,
1674 LPARAM lParam )
1676 LRESULT result;
1678 if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
1679 result = CallWndProc32( func, hwnd, msg, wParam, lParam );
1680 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1681 return result;
1685 /**********************************************************************
1686 * WINPROC_CallProc32WTo32A
1688 * Call a window procedure, translating args from Unicode to Ansi.
1690 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
1691 UINT32 msg, WPARAM32 wParam,
1692 LPARAM lParam )
1694 LRESULT result;
1696 if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
1697 result = CallWndProc32( func, hwnd, msg, wParam, lParam );
1698 WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
1699 return result;
1703 /**********************************************************************
1704 * WINPROC_CallProc16To32A
1706 * Call a 32-bit window procedure, translating the 16-bit args.
1708 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
1709 WPARAM16 wParam, LPARAM lParam,
1710 WNDPROC32 func )
1712 LRESULT result;
1713 UINT32 msg32;
1714 WPARAM32 wParam32;
1716 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1717 return 0;
1718 result = CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1719 WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam );
1720 return result;
1724 /**********************************************************************
1725 * WINPROC_CallProc16To32W
1727 * Call a 32-bit window procedure, translating the 16-bit args.
1729 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
1730 WPARAM16 wParam, LPARAM lParam,
1731 WNDPROC32 func )
1733 LRESULT result;
1734 UINT32 msg32;
1735 WPARAM32 wParam32;
1737 if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1738 return 0;
1739 result = CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1740 WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam );
1741 return result;
1745 /**********************************************************************
1746 * WINPROC_CallProc32ATo16
1748 * Call a 16-bit window procedure, translating the 32-bit args.
1750 static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
1751 UINT32 msg, WPARAM32 wParam,
1752 LPARAM lParam )
1754 UINT16 msg16;
1755 MSGPARAM16 mp16;
1756 WND *wndPtr = WIN_FindWndPtr( hwnd );
1757 WORD ds = CURRENT_DS;
1759 mp16.lParam = lParam;
1760 if (WINPROC_MapMsg32ATo16( msg, wParam,
1761 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
1762 return 0;
1763 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1764 mp16.lResult = CallWndProc16( func, hwnd, msg16, mp16.wParam, mp16.lParam );
1765 CURRENT_DS = ds;
1766 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, &mp16 );
1767 return mp16.lResult;
1771 /**********************************************************************
1772 * WINPROC_CallProc32WTo16
1774 * Call a 16-bit window procedure, translating the 32-bit args.
1776 static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
1777 UINT32 msg, WPARAM32 wParam,
1778 LPARAM lParam )
1780 UINT16 msg16;
1781 MSGPARAM16 mp16;
1782 WND *wndPtr = WIN_FindWndPtr( hwnd );
1783 WORD ds = CURRENT_DS;
1785 mp16.lParam = lParam;
1786 if (WINPROC_MapMsg32WTo16( msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1)
1787 return 0;
1788 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1789 mp16.lResult = CallWndProc16( func, hwnd, msg16, mp16.wParam, mp16.lParam );
1790 CURRENT_DS = ds;
1791 WINPROC_UnmapMsg32WTo16( msg, wParam, lParam, &mp16 );
1792 return mp16.lResult;
1796 /**********************************************************************
1797 * CallWindowProc16 (USER.122)
1799 LRESULT CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
1800 WPARAM16 wParam, LPARAM lParam )
1802 LRESULT result;
1803 WND *wndPtr;
1804 WINDOWPROC *proc = WINPROC_GetPtr( func );
1805 WORD ds = CURRENT_DS;
1807 if (!proc)
1809 wndPtr = WIN_FindWndPtr( hwnd );
1810 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1811 result = CallWndProc16( (FARPROC16)func, hwnd, msg, wParam, lParam );
1812 CURRENT_DS = ds;
1813 return result;
1815 #if testing
1816 wndPtr = WIN_FindWndPtr( hwnd );
1817 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1818 result = CallWndProc16( WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16),
1819 hwnd, msg, wParam, lParam );
1820 CURRENT_DS = ds;
1821 return result;
1822 #endif
1824 switch(proc->type)
1826 case WIN_PROC_16:
1827 if (!proc->thunk.t_from32.proc) return 0;
1828 wndPtr = WIN_FindWndPtr( hwnd );
1829 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1830 #ifndef WINELIB
1831 if ((msg == WM_CREATE) || (msg == WM_NCCREATE))
1833 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
1834 /* Build the CREATESTRUCT on the 16-bit stack. */
1835 /* This is really ugly, but some programs (notably the */
1836 /* "Undocumented Windows" examples) want it that way. */
1837 result = CallWndProcNCCREATE16( proc->thunk.t_from32.proc,
1838 cs->dwExStyle, cs->lpszClass, cs->lpszName, cs->style,
1839 cs->x, cs->y, cs->cx, cs->cy, cs->hwndParent, cs->hMenu,
1840 cs->hInstance, (LONG)cs->lpCreateParams, hwnd, msg, wParam,
1841 MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
1842 IF1632_Saved16_ss ) );
1843 CURRENT_DS = ds;
1844 return result;
1846 #endif
1847 result = CallWndProc16( proc->thunk.t_from32.proc,
1848 hwnd, msg, wParam, lParam );
1849 CURRENT_DS = ds;
1850 return result;
1852 case WIN_PROC_32A:
1853 if (!proc->thunk.t_from16.proc) return 0;
1854 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
1855 proc->thunk.t_from16.proc );
1856 case WIN_PROC_32W:
1857 if (!proc->thunk.t_from16.proc) return 0;
1858 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
1859 proc->thunk.t_from16.proc );
1860 default:
1861 fprintf( stderr, "CallWindowProc16: invalid proc %p\n", proc );
1862 return 0;
1867 /**********************************************************************
1868 * CallWindowProc32A (USER32.17)
1870 LRESULT CallWindowProc32A( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1871 WPARAM32 wParam, LPARAM lParam )
1873 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1875 if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam );
1877 #if testing
1878 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
1879 return CallWndProc32( func, hwnd, msg, wParam, lParam );
1880 #endif
1882 switch(proc->type)
1884 case WIN_PROC_16:
1885 if (!proc->thunk.t_from32.proc) return 0;
1886 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
1887 hwnd, msg, wParam, lParam );
1888 case WIN_PROC_32A:
1889 if (!proc->thunk.t_from16.proc) return 0;
1890 return CallWndProc32( proc->thunk.t_from16.proc,
1891 hwnd, msg, wParam, lParam );
1892 case WIN_PROC_32W:
1893 if (!proc->thunk.t_from16.proc) return 0;
1894 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
1895 hwnd, msg, wParam, lParam );
1896 default:
1897 fprintf( stderr, "CallWindowProc32A: invalid proc %p\n", proc );
1898 return 0;
1903 /**********************************************************************
1904 * CallWindowProc32W (USER32.18)
1906 LRESULT CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1907 WPARAM32 wParam, LPARAM lParam )
1909 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1911 if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam );
1913 #if testing
1914 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
1915 return CallWndProc32( func, hwnd, msg, wParam, lParam );
1916 #endif
1918 switch(proc->type)
1920 case WIN_PROC_16:
1921 if (!proc->thunk.t_from32.proc) return 0;
1922 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
1923 hwnd, msg, wParam, lParam );
1924 case WIN_PROC_32A:
1925 if (!proc->thunk.t_from16.proc) return 0;
1926 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
1927 hwnd, msg, wParam, lParam );
1928 case WIN_PROC_32W:
1929 if (!proc->thunk.t_from16.proc) return 0;
1930 return CallWndProc32( proc->thunk.t_from16.proc,
1931 hwnd, msg, wParam, lParam );
1932 default:
1933 fprintf( stderr, "CallWindowProc32W: invalid proc %p\n", proc );
1934 return 0;