Release 980329
[wine.git] / windows / winproc.c
blob3b627deebc51170c8668da87847410609c225b3f
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 "struct32.h"
14 #include "win.h"
15 #include "winproc.h"
16 #include "debug.h"
18 /* Window procedure 16-to-32-bit thunk,
19 * see BuildSpec16Files() in tools/build.c */
21 typedef struct
23 BYTE popl_eax; /* popl %eax (return address) */
24 BYTE pushl_func; /* pushl $proc */
25 WNDPROC32 proc WINE_PACKED;
26 BYTE pushl_eax; /* pushl %eax */
27 WORD pushw_bp WINE_PACKED; /* pushw %bp */
28 BYTE pushl_thunk; /* pushl $thunkfrom16 */
29 void (*thunk32)() WINE_PACKED;
30 BYTE lcall; /* lcall cs:relay */
31 void (*relay)() WINE_PACKED; /* WINPROC_CallProc16To32A/W() */
32 WORD cs WINE_PACKED;
33 } WINPROC_THUNK_FROM16;
35 /* Window procedure 32-to-16-bit thunk,
36 * see BuildSpec32Files() in tools/build.c */
38 typedef struct
40 BYTE popl_eax; /* popl %eax (return address) */
41 BYTE pushl_func; /* pushl $proc */
42 WNDPROC16 proc WINE_PACKED;
43 BYTE pushl_eax; /* pushl %eax */
44 BYTE jmp; /* jmp relay (relative jump)*/
45 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
46 } WINPROC_THUNK_FROM32;
48 /* Simple jmp to call 32-bit procedure directly */
49 typedef struct
51 BYTE jmp; /* jmp proc (relative jump) */
52 WNDPROC32 proc WINE_PACKED;
53 } WINPROC_JUMP;
55 typedef union
57 WINPROC_THUNK_FROM16 t_from16;
58 WINPROC_THUNK_FROM32 t_from32;
59 } WINPROC_THUNK;
61 typedef struct tagWINDOWPROC
63 WINPROC_THUNK thunk; /* Thunk */
64 WINPROC_JUMP jmp; /* Jump */
65 struct tagWINDOWPROC *next; /* Next window proc */
66 UINT32 magic; /* Magic number */
67 WINDOWPROCTYPE type; /* Function type */
68 WINDOWPROCUSER user; /* Function user */
69 } WINDOWPROC;
71 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
73 #define WINPROC_THUNKPROC(pproc) \
74 (((pproc)->type == WIN_PROC_16) ? \
75 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
76 (WNDPROC16)((pproc)->thunk.t_from16.proc))
78 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
79 UINT32 msg, WPARAM32 wParam,
80 LPARAM lParam );
81 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
82 UINT32 msg, WPARAM32 wParam,
83 LPARAM lParam );
84 static LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
85 WPARAM16 wParam, LPARAM lParam,
86 WNDPROC32 func );
87 static LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
88 WPARAM16 wParam, LPARAM lParam,
89 WNDPROC32 func );
91 static HANDLE32 WinProcHeap;
94 /**********************************************************************
95 * WINPROC_Init
97 BOOL32 WINPROC_Init(void)
99 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
100 if (!WinProcHeap)
102 fprintf( stderr, "Unable to create winproc heap\n" );
103 return FALSE;
105 return TRUE;
109 /**********************************************************************
110 * WINPROC_CallWndProc32
112 * Call a 32-bit WndProc.
114 static LRESULT WINPROC_CallWndProc32( WNDPROC32 proc, HWND32 hwnd, UINT32 msg,
115 WPARAM32 wParam, LPARAM lParam )
117 TRACE(relay, "(wndproc=%p,hwnd=%08x,msg=%08x,wp=%08x,lp=%08lx)\n",
118 proc, hwnd, msg, wParam, lParam );
119 return proc( hwnd, msg, wParam, lParam );
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.jmp = 0xe9; /* jmp relay*/
195 proc->thunk.t_from32.relay = /* relative jump */
196 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
197 (DWORD)(&proc->thunk.t_from32.relay + 1));
198 break;
199 case WIN_PROC_32A:
200 case WIN_PROC_32W:
201 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
202 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
203 proc->thunk.t_from16.proc = (FARPROC32)func;
204 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
205 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
206 proc->thunk.t_from16.pushl_thunk = 0x68; /* pushl $thunkfrom16 */
207 proc->thunk.t_from16.thunk32 = (type == WIN_PROC_32A) ?
208 (void(*)())WINPROC_CallProc16To32A :
209 (void(*)())WINPROC_CallProc16To32W;
210 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:relay */
211 proc->thunk.t_from16.relay = Callbacks->CallFrom16WndProc;
212 GET_CS(proc->thunk.t_from16.cs);
213 proc->jmp.jmp = 0xe9;
214 /* Fixup relative jump */
215 proc->jmp.proc = (WNDPROC32)((DWORD)func -
216 (DWORD)(&proc->jmp.proc + 1));
217 break;
218 default:
219 /* Should not happen */
220 break;
222 proc->magic = WINPROC_MAGIC;
223 proc->type = type;
224 proc->user = user;
226 proc->next = NULL;
227 TRACE(win, "(%08x,%d): returning %08x\n",
228 (UINT32)func, type, (UINT32)proc );
229 return proc;
233 /**********************************************************************
234 * WINPROC_GetProc
236 * Get a window procedure pointer that can be passed to the Windows program.
238 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
240 if (!proc) return NULL;
241 if (type == WIN_PROC_16) /* We want a 16:16 address */
243 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
244 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
245 else
246 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
247 &((WINDOWPROC *)proc)->thunk );
249 else /* We want a 32-bit address */
251 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
252 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
253 else
254 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
259 /**********************************************************************
260 * WINPROC_SetProc
262 * Set the window procedure for a window or class. There are
263 * three tree classes of winproc callbacks:
265 * 1) class -> wp - not subclassed
266 * class -> wp -> wp -> wp -> wp - SetClassLong()
267 * / /
268 * 2) window -' / - not subclassed
269 * window -> wp -> wp ' - SetWindowLong()
271 * 3) timer -> wp - SetTimer()
273 * Initially, winproc of the window points to the current winproc
274 * thunk of its class. Subclassing prepends a new thunk to the
275 * window winproc chain at the head of the list. Thus, window thunk
276 * list includes class thunks and the latter are preserved when the
277 * window is destroyed.
280 BOOL32 WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
281 WINDOWPROCTYPE type, WINDOWPROCUSER user )
283 BOOL32 bRecycle = FALSE;
284 WINDOWPROC *proc, **ppPrev;
286 /* Check if function is already in the list */
288 ppPrev = (WINDOWPROC **)pFirst;
289 proc = WINPROC_GetPtr( func );
290 while (*ppPrev)
292 if (proc)
294 if (*ppPrev == proc)
296 if ((*ppPrev)->user != user)
298 /* terminal thunk is being restored */
300 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
301 *(WINDOWPROC **)pFirst = *ppPrev;
302 return TRUE;
304 bRecycle = TRUE;
305 break;
308 else
310 if (((*ppPrev)->type == type) &&
311 (func == WINPROC_THUNKPROC(*ppPrev)))
313 bRecycle = TRUE;
314 break;
318 /* WPF_CLASS thunk terminates window thunk list */
319 if ((*ppPrev)->user != user) break;
320 ppPrev = &(*ppPrev)->next;
323 if (bRecycle)
325 /* Extract this thunk from the list */
326 proc = *ppPrev;
327 *ppPrev = proc->next;
329 else /* Allocate a new one */
331 if (proc) /* Was already a win proc */
333 type = proc->type;
334 func = WINPROC_THUNKPROC(proc);
336 proc = WINPROC_AllocWinProc( func, type, user );
337 if (!proc) return FALSE;
340 /* Add the win proc at the head of the list */
342 TRACE(win, "(%08x,%08x,%d): res=%08x\n",
343 (UINT32)*pFirst, (UINT32)func, type, (UINT32)proc );
344 proc->next = *(WINDOWPROC **)pFirst;
345 *(WINDOWPROC **)pFirst = proc;
346 return TRUE;
350 /**********************************************************************
351 * WINPROC_FreeProc
353 * Free a list of win procs.
355 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
357 while (proc)
359 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
360 if (((WINDOWPROC *)proc)->user != user) break;
361 TRACE(win, "freeing %08x\n", (UINT32)proc);
362 HeapFree( WinProcHeap, 0, proc );
363 proc = next;
368 /**********************************************************************
369 * WINPROC_GetProcType
371 * Return the window procedure type.
373 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
375 if (!proc ||
376 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
377 return WIN_PROC_INVALID;
378 return ((WINDOWPROC *)proc)->type;
382 /**********************************************************************
383 * WINPROC_MapMsg32ATo32W
385 * Map a message from Ansi to Unicode.
386 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
388 INT32 WINPROC_MapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
390 switch(msg)
392 case WM_GETTEXT:
394 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
395 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
396 if (!ptr) return -1;
397 *ptr++ = *plparam; /* Store previous lParam */
398 *plparam = (LPARAM)ptr;
400 return 1;
401 case WM_SETTEXT:
402 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
403 return (*plparam ? 1 : -1);
404 case WM_NCCREATE:
405 case WM_CREATE:
407 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
408 sizeof(*cs) );
409 if (!cs) return -1;
410 *cs = *(CREATESTRUCT32W *)*plparam;
411 if (HIWORD(cs->lpszName))
412 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
413 (LPCSTR)cs->lpszName );
414 if (HIWORD(cs->lpszClass))
415 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
416 (LPCSTR)cs->lpszClass );
417 *plparam = (LPARAM)cs;
419 return 1;
420 case WM_MDICREATE:
422 MDICREATESTRUCT32W *cs =
423 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
424 if (!cs) return -1;
425 *cs = *(MDICREATESTRUCT32W *)*plparam;
426 if (HIWORD(cs->szClass))
427 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
428 (LPCSTR)cs->szClass );
429 if (HIWORD(cs->szTitle))
430 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
431 (LPCSTR)cs->szTitle );
432 *plparam = (LPARAM)cs;
434 return 1;
435 case WM_ASKCBFORMATNAME:
436 case WM_DEVMODECHANGE:
437 case WM_PAINTCLIPBOARD:
438 case WM_SIZECLIPBOARD:
439 case WM_WININICHANGE:
440 fprintf( stderr, "MapMsg32ATo32W: message %04x needs translation\n",
441 msg );
442 return -1;
443 default: /* No translation needed */
444 return 0;
449 /**********************************************************************
450 * WINPROC_UnmapMsg32ATo32W
452 * Unmap a message that was mapped from Ansi to Unicode.
454 void WINPROC_UnmapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
456 switch(msg)
458 case WM_GETTEXT:
460 LPARAM *ptr = (LPARAM *)lParam - 1;
461 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)(ptr + 1), wParam );
462 HeapFree( SystemHeap, 0, ptr );
464 break;
465 case WM_SETTEXT:
466 HeapFree( SystemHeap, 0, (void *)lParam );
467 break;
468 case WM_NCCREATE:
469 case WM_CREATE:
471 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
472 if (HIWORD(cs->lpszName))
473 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
474 if (HIWORD(cs->lpszClass))
475 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
476 HeapFree( SystemHeap, 0, cs );
478 break;
479 case WM_MDICREATE:
481 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
482 if (HIWORD(cs->szTitle))
483 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
484 if (HIWORD(cs->szClass))
485 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
486 HeapFree( SystemHeap, 0, cs );
488 break;
493 /**********************************************************************
494 * WINPROC_MapMsg32WTo32A
496 * Map a message from Unicode to Ansi.
497 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
499 INT32 WINPROC_MapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
501 switch(msg)
503 case WM_GETTEXT:
505 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
506 wParam + sizeof(LPARAM) );
507 if (!ptr) return -1;
508 *ptr++ = *plparam; /* Store previous lParam */
509 *plparam = (LPARAM)ptr;
511 return 1;
512 case WM_SETTEXT:
513 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
514 return (*plparam ? 1 : -1);
515 case WM_NCCREATE:
516 case WM_CREATE:
518 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
519 sizeof(*cs) );
520 if (!cs) return -1;
521 *cs = *(CREATESTRUCT32A *)*plparam;
522 if (HIWORD(cs->lpszName))
523 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
524 (LPCWSTR)cs->lpszName );
525 if (HIWORD(cs->lpszClass))
526 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
527 (LPCWSTR)cs->lpszClass);
528 *plparam = (LPARAM)cs;
530 return 1;
531 case WM_MDICREATE:
533 MDICREATESTRUCT32A *cs =
534 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
535 if (!cs) return -1;
536 *cs = *(MDICREATESTRUCT32A *)*plparam;
537 if (HIWORD(cs->szTitle))
538 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
539 (LPCWSTR)cs->szTitle );
540 if (HIWORD(cs->szClass))
541 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
542 (LPCWSTR)cs->szClass );
543 *plparam = (LPARAM)cs;
545 return 1;
546 case WM_ASKCBFORMATNAME:
547 case WM_DEVMODECHANGE:
548 case WM_PAINTCLIPBOARD:
549 case WM_SIZECLIPBOARD:
550 case WM_WININICHANGE:
551 fprintf( stderr, "MapMsg32WTo32A: message %04x needs translation\n",
552 msg );
553 return -1;
554 default: /* No translation needed */
555 return 0;
560 /**********************************************************************
561 * WINPROC_UnmapMsg32WTo32A
563 * Unmap a message that was mapped from Unicode to Ansi.
565 void WINPROC_UnmapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
567 switch(msg)
569 case WM_GETTEXT:
571 LPARAM *ptr = (LPARAM *)lParam - 1;
572 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)(ptr + 1), wParam );
573 HeapFree( SystemHeap, 0, ptr );
575 break;
576 case WM_SETTEXT:
577 HeapFree( SystemHeap, 0, (void *)lParam );
578 break;
579 case WM_NCCREATE:
580 case WM_CREATE:
582 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
583 if (HIWORD(cs->lpszName))
584 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
585 if (HIWORD(cs->lpszClass))
586 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
587 HeapFree( SystemHeap, 0, cs );
589 break;
590 case WM_MDICREATE:
592 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
593 if (HIWORD(cs->szTitle))
594 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
595 if (HIWORD(cs->szClass))
596 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
597 HeapFree( SystemHeap, 0, cs );
599 break;
604 /**********************************************************************
605 * WINPROC_MapMsg16To32A
607 * Map a message from 16- to 32-bit Ansi.
608 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
610 INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
611 WPARAM32 *pwparam32, LPARAM *plparam )
613 *pmsg32 = (UINT32)msg16;
614 *pwparam32 = (WPARAM32)wParam16;
615 switch(msg16)
617 case WM_ACTIVATE:
618 case WM_CHARTOITEM:
619 case WM_COMMAND:
620 case WM_VKEYTOITEM:
621 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
622 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
623 return 0;
624 case WM_HSCROLL:
625 case WM_VSCROLL:
626 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
627 *plparam = (LPARAM)(HWND32)HIWORD(*plparam);
628 return 0;
629 case WM_CTLCOLOR:
630 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
631 *pwparam32 = (WPARAM32)(HDC32)wParam16;
632 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
633 return 0;
634 case WM_COMPAREITEM:
636 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
637 COMPAREITEMSTRUCT32 *cis = (COMPAREITEMSTRUCT32 *)
638 HeapAlloc(SystemHeap, 0, sizeof(*cis));
639 if (!cis) return -1;
640 cis->CtlType = cis16->CtlType;
641 cis->CtlID = cis16->CtlID;
642 cis->hwndItem = cis16->hwndItem;
643 cis->itemID1 = cis16->itemID1;
644 cis->itemData1 = cis16->itemData1;
645 cis->itemID2 = cis16->itemID2;
646 cis->itemData2 = cis16->itemData2;
647 cis->dwLocaleId = 0; /* FIXME */
648 *plparam = (LPARAM)cis;
650 return 1;
651 case WM_DELETEITEM:
653 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
654 DELETEITEMSTRUCT32 *dis = (DELETEITEMSTRUCT32 *)
655 HeapAlloc(SystemHeap, 0, sizeof(*dis));
656 if (!dis) return -1;
657 dis->CtlType = dis16->CtlType;
658 dis->CtlID = dis16->CtlID;
659 dis->hwndItem = dis16->hwndItem;
660 dis->itemData = dis16->itemData;
661 *plparam = (LPARAM)dis;
663 return 1;
664 case WM_MEASUREITEM:
666 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
667 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)
668 HeapAlloc(SystemHeap, 0,
669 sizeof(*mis) + sizeof(LPARAM));
670 if (!mis) return -1;
671 mis->CtlType = mis16->CtlType;
672 mis->CtlID = mis16->CtlID;
673 mis->itemID = mis16->itemID;
674 mis->itemWidth = mis16->itemWidth;
675 mis->itemHeight = mis16->itemHeight;
676 mis->itemData = mis16->itemData;
677 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
678 *plparam = (LPARAM)mis;
680 return 1;
681 case WM_DRAWITEM:
683 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
684 DRAWITEMSTRUCT32 *dis = (DRAWITEMSTRUCT32*)HeapAlloc(SystemHeap, 0,
685 sizeof(*dis));
686 if (!dis) return -1;
687 dis->CtlType = dis16->CtlType;
688 dis->CtlID = dis16->CtlID;
689 dis->itemID = dis16->itemID;
690 dis->itemAction = dis16->itemAction;
691 dis->itemState = dis16->itemState;
692 dis->hwndItem = dis16->hwndItem;
693 dis->hDC = dis16->hDC;
694 dis->itemData = dis16->itemData;
695 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
696 *plparam = (LPARAM)dis;
698 return 1;
699 case WM_GETMINMAXINFO:
701 MINMAXINFO32 *mmi = (MINMAXINFO32 *)HeapAlloc( SystemHeap, 0,
702 sizeof(*mmi) + sizeof(LPARAM));
703 if (!mmi) return -1;
704 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
705 mmi );
706 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
707 *plparam = (LPARAM)mmi;
709 return 1;
710 case WM_GETTEXT:
711 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
712 return 0;
713 case WM_MDICREATE:
715 MDICREATESTRUCT16 *cs16 =
716 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
717 MDICREATESTRUCT32A *cs =
718 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
719 sizeof(*cs) + sizeof(LPARAM) );
720 if (!cs) return -1;
721 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
722 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
723 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
724 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
725 *plparam = (LPARAM)cs;
727 return 1;
728 case WM_MDIGETACTIVE:
729 *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL32) );
730 return 1;
731 case WM_MDISETMENU:
732 *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
733 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
734 return 0;
735 case WM_MENUCHAR:
736 case WM_MENUSELECT:
737 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
738 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
739 return 0;
740 case WM_MDIACTIVATE:
741 if( *plparam )
743 *pwparam32 = (WPARAM32)(HWND32)HIWORD(*plparam);
744 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
746 else /* message sent to MDI client */
747 *pwparam32 = wParam16;
748 return 0;
749 case WM_NCCALCSIZE:
751 NCCALCSIZE_PARAMS16 *nc16;
752 NCCALCSIZE_PARAMS32 *nc;
754 nc = (NCCALCSIZE_PARAMS32 *)HeapAlloc( SystemHeap, 0,
755 sizeof(*nc) + sizeof(LPARAM) );
756 if (!nc) return -1;
757 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
758 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
759 if (wParam16)
761 nc->lppos = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
762 sizeof(*nc->lppos) );
763 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
764 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
765 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
767 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
768 *plparam = (LPARAM)nc;
770 return 1;
771 case WM_NCCREATE:
772 case WM_CREATE:
774 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
775 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
776 sizeof(*cs) + sizeof(LPARAM) );
777 if (!cs) return -1;
778 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
779 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
780 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
781 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
782 *plparam = (LPARAM)cs;
784 return 1;
785 case WM_PARENTNOTIFY:
786 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
788 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
789 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
791 return 0;
792 case WM_SETTEXT:
793 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
794 return 0;
795 case WM_WINDOWPOSCHANGING:
796 case WM_WINDOWPOSCHANGED:
798 WINDOWPOS32 *wp = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
799 sizeof(*wp) + sizeof(LPARAM) );
800 if (!wp) return -1;
801 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
802 wp );
803 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
804 *plparam = (LPARAM)wp;
806 return 1;
807 case WM_ASKCBFORMATNAME:
808 case WM_DEVMODECHANGE:
809 case WM_PAINTCLIPBOARD:
810 case WM_SIZECLIPBOARD:
811 case WM_WININICHANGE:
812 fprintf( stderr, "MapMsg16To32A: message %04x needs translation\n",
813 msg16 );
814 return -1;
816 default: /* No translation needed */
817 return 0;
822 /**********************************************************************
823 * WINPROC_UnmapMsg16To32A
825 * Unmap a message that was mapped from 16- to 32-bit Ansi.
827 LRESULT WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
828 LRESULT result )
830 switch(msg)
832 case WM_COMPAREITEM:
833 case WM_DELETEITEM:
834 case WM_DRAWITEM:
835 HeapFree( SystemHeap, 0, (LPVOID)lParam );
836 break;
837 case WM_MEASUREITEM:
839 MEASUREITEMSTRUCT16 *mis16;
840 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)lParam;
841 lParam = *(LPARAM *)(mis + 1);
842 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
843 mis16->itemWidth = (UINT16)mis->itemWidth;
844 mis16->itemHeight = (UINT16)mis->itemHeight;
845 HeapFree( SystemHeap, 0, mis );
847 break;
848 case WM_GETMINMAXINFO:
850 MINMAXINFO32 *mmi = (MINMAXINFO32 *)lParam;
851 lParam = *(LPARAM *)(mmi + 1);
852 STRUCT32_MINMAXINFO32to16( mmi,
853 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
854 HeapFree( SystemHeap, 0, mmi );
856 break;
857 case WM_MDICREATE:
859 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
860 lParam = *(LPARAM *)(cs + 1);
861 STRUCT32_MDICREATESTRUCT32Ato16( cs,
862 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
863 HeapFree( SystemHeap, 0, cs );
865 break;
866 case WM_MDIGETACTIVE:
867 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL32 *)lParam) );
868 HeapFree( SystemHeap, 0, (BOOL32 *)lParam );
869 break;
870 case WM_NCCALCSIZE:
872 NCCALCSIZE_PARAMS16 *nc16;
873 NCCALCSIZE_PARAMS32 *nc = (NCCALCSIZE_PARAMS32 *)lParam;
874 lParam = *(LPARAM *)(nc + 1);
875 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
876 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
877 if (wParam)
879 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
880 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
881 if (nc->lppos)
883 STRUCT32_WINDOWPOS32to16( nc->lppos,
884 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
885 HeapFree( SystemHeap, 0, nc->lppos );
888 HeapFree( SystemHeap, 0, nc );
890 break;
891 case WM_NCCREATE:
892 case WM_CREATE:
894 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
895 lParam = *(LPARAM *)(cs + 1);
896 STRUCT32_CREATESTRUCT32Ato16( cs,
897 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
898 HeapFree( SystemHeap, 0, cs );
900 break;
901 case WM_WINDOWPOSCHANGING:
902 case WM_WINDOWPOSCHANGED:
904 WINDOWPOS32 *wp = (WINDOWPOS32 *)lParam;
905 lParam = *(LPARAM *)(wp + 1);
906 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
907 HeapFree( SystemHeap, 0, wp );
909 break;
911 return result;
915 /**********************************************************************
916 * WINPROC_MapMsg16To32W
918 * Map a message from 16- to 32-bit Unicode.
919 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
921 INT32 WINPROC_MapMsg16To32W( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
922 WPARAM32 *pwparam32, LPARAM *plparam )
924 switch(msg16)
926 case WM_GETTEXT:
927 case WM_SETTEXT:
928 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
929 return WINPROC_MapMsg32ATo32W( *pmsg32, *pwparam32, plparam );
930 case WM_NCCREATE:
931 case WM_CREATE:
933 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
934 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
935 sizeof(*cs) + sizeof(LPARAM) );
936 if (!cs) return -1;
937 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCT32A *)cs );
938 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
939 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
940 if (HIWORD(cs->lpszName))
941 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
942 (LPCSTR)cs->lpszName );
943 if (HIWORD(cs->lpszClass))
944 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
945 (LPCSTR)cs->lpszClass );
946 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
947 *plparam = (LPARAM)cs;
949 return 1;
950 case WM_MDICREATE:
952 MDICREATESTRUCT16 *cs16 =
953 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
954 MDICREATESTRUCT32W *cs =
955 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
956 sizeof(*cs) + sizeof(LPARAM) );
957 if (!cs) return -1;
958 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCT32A *)cs );
959 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
960 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
961 if (HIWORD(cs->szTitle))
962 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
963 (LPCSTR)cs->szTitle );
964 if (HIWORD(cs->szClass))
965 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
966 (LPCSTR)cs->szClass );
967 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
968 *plparam = (LPARAM)cs;
970 return 1;
971 default: /* No Unicode translation needed */
972 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
973 pwparam32, plparam );
978 /**********************************************************************
979 * WINPROC_UnmapMsg16To32W
981 * Unmap a message that was mapped from 16- to 32-bit Unicode.
983 LRESULT WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
984 LRESULT result )
986 switch(msg)
988 case WM_GETTEXT:
989 case WM_SETTEXT:
990 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
991 break;
992 case WM_NCCREATE:
993 case WM_CREATE:
995 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
996 lParam = *(LPARAM *)(cs + 1);
997 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
998 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
999 if (HIWORD(cs->lpszName))
1000 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1001 if (HIWORD(cs->lpszClass))
1002 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1003 HeapFree( SystemHeap, 0, cs );
1005 break;
1006 case WM_MDICREATE:
1008 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
1009 lParam = *(LPARAM *)(cs + 1);
1010 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
1011 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1012 if (HIWORD(cs->szTitle))
1013 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1014 if (HIWORD(cs->szClass))
1015 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1016 HeapFree( SystemHeap, 0, cs );
1018 break;
1019 default:
1020 return WINPROC_UnmapMsg16To32A( msg, wParam, lParam, result );
1022 return result;
1026 /**********************************************************************
1027 * WINPROC_MapMsg32ATo16
1029 * Map a message from 32-bit Ansi to 16-bit.
1030 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1032 INT32 WINPROC_MapMsg32ATo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1033 UINT16 *pmsg16, WPARAM16 *pwparam16,
1034 LPARAM *plparam )
1036 *pmsg16 = (UINT16)msg32;
1037 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1038 switch(msg32)
1040 case BM_GETCHECK32:
1041 case BM_SETCHECK32:
1042 case BM_GETSTATE32:
1043 case BM_SETSTATE32:
1044 case BM_SETSTYLE32:
1045 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK32);
1046 return 0;
1048 case EM_GETSEL32:
1049 case EM_GETRECT32:
1050 case EM_SETRECT32:
1051 case EM_SETRECTNP32:
1052 case EM_SCROLL32:
1053 case EM_LINESCROLL32:
1054 case EM_SCROLLCARET32:
1055 case EM_GETMODIFY32:
1056 case EM_SETMODIFY32:
1057 case EM_GETLINECOUNT32:
1058 case EM_LINEINDEX32:
1059 case EM_SETHANDLE32:
1060 case EM_GETHANDLE32:
1061 case EM_GETTHUMB32:
1062 case EM_LINELENGTH32:
1063 case EM_REPLACESEL32:
1064 case EM_GETLINE32:
1065 case EM_LIMITTEXT32:
1066 case EM_CANUNDO32:
1067 case EM_UNDO32:
1068 case EM_FMTLINES32:
1069 case EM_LINEFROMCHAR32:
1070 case EM_SETTABSTOPS32:
1071 case EM_SETPASSWORDCHAR32:
1072 case EM_EMPTYUNDOBUFFER32:
1073 case EM_GETFIRSTVISIBLELINE32:
1074 case EM_SETREADONLY32:
1075 case EM_SETWORDBREAKPROC32:
1076 case EM_GETWORDBREAKPROC32:
1077 case EM_GETPASSWORDCHAR32:
1078 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL32);
1079 return 0;
1081 case LB_CARETOFF32:
1082 case LB_CARETON32:
1083 case LB_DELETESTRING32:
1084 case LB_GETANCHORINDEX32:
1085 case LB_GETCARETINDEX32:
1086 case LB_GETCOUNT32:
1087 case LB_GETCURSEL32:
1088 case LB_GETHORIZONTALEXTENT32:
1089 case LB_GETITEMDATA32:
1090 case LB_GETITEMHEIGHT32:
1091 case LB_GETSEL32:
1092 case LB_GETSELCOUNT32:
1093 case LB_GETTEXTLEN32:
1094 case LB_GETTOPINDEX32:
1095 case LB_RESETCONTENT32:
1096 case LB_SELITEMRANGE32:
1097 case LB_SELITEMRANGEEX32:
1098 case LB_SETANCHORINDEX32:
1099 case LB_SETCARETINDEX32:
1100 case LB_SETCOLUMNWIDTH32:
1101 case LB_SETCURSEL32:
1102 case LB_SETHORIZONTALEXTENT32:
1103 case LB_SETITEMDATA32:
1104 case LB_SETITEMHEIGHT32:
1105 case LB_SETSEL32:
1106 case LB_SETTOPINDEX32:
1107 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1108 return 0;
1109 case CB_DELETESTRING32:
1110 case CB_GETCOUNT32:
1111 case CB_GETLBTEXTLEN32:
1112 case CB_LIMITTEXT32:
1113 case CB_RESETCONTENT32:
1114 case CB_SETEDITSEL32:
1115 case CB_GETCURSEL32:
1116 case CB_SETCURSEL32:
1117 case CB_SHOWDROPDOWN32:
1118 case CB_SETITEMDATA32:
1119 case CB_SETITEMHEIGHT32:
1120 case CB_GETITEMHEIGHT32:
1121 case CB_SETEXTENDEDUI32:
1122 case CB_GETEXTENDEDUI32:
1123 case CB_GETDROPPEDSTATE32:
1124 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1125 return 0;
1126 case CB_GETEDITSEL32:
1127 *pmsg16 = CB_GETEDITSEL16;
1128 return 1;
1130 case LB_ADDSTRING32:
1131 case LB_FINDSTRING32:
1132 case LB_FINDSTRINGEXACT32:
1133 case LB_INSERTSTRING32:
1134 case LB_SELECTSTRING32:
1135 case LB_DIR32:
1136 case LB_ADDFILE32:
1138 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1139 if (!str) return -1;
1140 *plparam = (LPARAM)SEGPTR_GET(str);
1142 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1143 return 1;
1145 case CB_ADDSTRING32:
1146 case CB_FINDSTRING32:
1147 case CB_FINDSTRINGEXACT32:
1148 case CB_INSERTSTRING32:
1149 case CB_SELECTSTRING32:
1150 case CB_DIR32:
1152 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1153 if (!str) return -1;
1154 *plparam = (LPARAM)SEGPTR_GET(str);
1156 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1157 return 1;
1159 case LB_GETITEMRECT32:
1161 RECT16 *rect;
1162 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1163 if (!rect) return -1;
1164 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1165 *plparam = (LPARAM)SEGPTR_GET(rect);
1167 *pmsg16 = LB_GETITEMRECT16;
1168 return 1;
1169 case LB_GETSELITEMS32:
1171 LPINT16 items;
1172 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1173 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1174 + sizeof(LPARAM)))) return -1;
1175 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1176 *plparam = (LPARAM)SEGPTR_GET(items);
1178 *pmsg16 = LB_GETSELITEMS16;
1179 return 1;
1180 case LB_SETTABSTOPS32:
1181 if (wParam32)
1183 INT32 i;
1184 LPINT16 stops;
1185 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1186 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1187 + sizeof(LPARAM)))) return -1;
1188 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT32)*plparam+i);
1189 *plparam = (LPARAM)SEGPTR_GET(stops);
1190 return 1;
1192 *pmsg16 = LB_SETTABSTOPS16;
1193 return 0;
1195 case CB_GETDROPPEDCONTROLRECT32:
1197 RECT16 *rect;
1198 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1199 if (!rect) return -1;
1200 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1201 *plparam = (LPARAM)SEGPTR_GET(rect);
1203 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1204 return 1;
1206 case LB_GETTEXT32:
1207 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1208 *pmsg16 = LB_GETTEXT16;
1209 return 1;
1211 case CB_GETLBTEXT32:
1212 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1213 *pmsg16 = CB_GETLBTEXT16;
1214 return 1;
1216 case EM_SETSEL32:
1217 *pwparam16 = 0;
1218 *plparam = MAKELONG( (INT16)(INT32)wParam32, (INT16)*plparam );
1219 *pmsg16 = EM_SETSEL16;
1220 return 0;
1222 case WM_ACTIVATE:
1223 case WM_CHARTOITEM:
1224 case WM_COMMAND:
1225 case WM_VKEYTOITEM:
1226 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1227 return 0;
1228 case WM_HSCROLL:
1229 case WM_VSCROLL:
1230 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1231 return 0;
1232 case WM_CTLCOLORMSGBOX:
1233 case WM_CTLCOLOREDIT:
1234 case WM_CTLCOLORLISTBOX:
1235 case WM_CTLCOLORBTN:
1236 case WM_CTLCOLORDLG:
1237 case WM_CTLCOLORSCROLLBAR:
1238 case WM_CTLCOLORSTATIC:
1239 *pmsg16 = WM_CTLCOLOR;
1240 *plparam = MAKELPARAM( (HWND16)*plparam,
1241 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1242 return 0;
1243 case WM_COMPAREITEM:
1245 COMPAREITEMSTRUCT32 *cis32 = (COMPAREITEMSTRUCT32 *)*plparam;
1246 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1247 if (!cis) return -1;
1248 cis->CtlType = (UINT16)cis32->CtlType;
1249 cis->CtlID = (UINT16)cis32->CtlID;
1250 cis->hwndItem = (HWND16)cis32->hwndItem;
1251 cis->itemID1 = (UINT16)cis32->itemID1;
1252 cis->itemData1 = cis32->itemData1;
1253 cis->itemID2 = (UINT16)cis32->itemID2;
1254 cis->itemData2 = cis32->itemData2;
1255 *plparam = (LPARAM)SEGPTR_GET(cis);
1257 return 1;
1258 case WM_DELETEITEM:
1260 DELETEITEMSTRUCT32 *dis32 = (DELETEITEMSTRUCT32 *)*plparam;
1261 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1262 if (!dis) return -1;
1263 dis->CtlType = (UINT16)dis32->CtlType;
1264 dis->CtlID = (UINT16)dis32->CtlID;
1265 dis->itemID = (UINT16)dis32->itemID;
1266 dis->hwndItem = (HWND16)dis32->hwndItem;
1267 dis->itemData = dis32->itemData;
1268 *plparam = (LPARAM)SEGPTR_GET(dis);
1270 return 1;
1271 case WM_DRAWITEM:
1273 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)*plparam;
1274 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1275 if (!dis) return -1;
1276 dis->CtlType = (UINT16)dis32->CtlType;
1277 dis->CtlID = (UINT16)dis32->CtlID;
1278 dis->itemID = (UINT16)dis32->itemID;
1279 dis->itemAction = (UINT16)dis32->itemAction;
1280 dis->itemState = (UINT16)dis32->itemState;
1281 dis->hwndItem = (HWND16)dis32->hwndItem;
1282 dis->hDC = (HDC16)dis32->hDC;
1283 dis->itemData = dis32->itemData;
1284 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1285 *plparam = (LPARAM)SEGPTR_GET(dis);
1287 return 1;
1288 case WM_MEASUREITEM:
1290 MEASUREITEMSTRUCT32 *mis32 = (MEASUREITEMSTRUCT32 *)*plparam;
1291 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1292 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1293 if (!mis) return -1;
1294 mis->CtlType = (UINT16)mis32->CtlType;
1295 mis->CtlID = (UINT16)mis32->CtlID;
1296 mis->itemID = (UINT16)mis32->itemID;
1297 mis->itemWidth = (UINT16)mis32->itemWidth;
1298 mis->itemHeight = (UINT16)mis32->itemHeight;
1299 mis->itemData = mis32->itemData;
1300 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1301 *plparam = (LPARAM)SEGPTR_GET(mis);
1303 return 1;
1304 case WM_GETMINMAXINFO:
1306 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1307 sizeof(LPARAM) );
1308 if (!mmi) return -1;
1309 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)*plparam, mmi );
1310 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1311 *plparam = (LPARAM)SEGPTR_GET(mmi);
1313 return 1;
1314 case WM_GETTEXT:
1316 LPSTR str;
1317 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1318 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1319 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1320 *plparam = (LPARAM)SEGPTR_GET(str);
1322 return 1;
1323 case WM_MDICREATE:
1325 MDICREATESTRUCT16 *cs;
1326 MDICREATESTRUCT32A *cs32 = (MDICREATESTRUCT32A *)*plparam;
1327 LPSTR name, cls;
1329 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1330 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1331 name = SEGPTR_STRDUP( cs32->szTitle );
1332 cls = SEGPTR_STRDUP( cs32->szClass );
1333 cs->szTitle = SEGPTR_GET(name);
1334 cs->szClass = SEGPTR_GET(cls);
1335 *plparam = (LPARAM)SEGPTR_GET(cs);
1337 return 1;
1338 case WM_MDIGETACTIVE:
1339 return 1;
1340 case WM_MDISETMENU:
1341 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1342 (HMENU16)LOWORD(*plparam) );
1343 *pwparam16 = (*plparam == 0);
1344 return 0;
1345 case WM_MENUCHAR:
1346 case WM_MENUSELECT:
1347 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1348 return 0;
1349 case WM_MDIACTIVATE:
1350 if( WIDGETS_IsControl32(WIN_FindWndPtr(hwnd), BIC32_MDICLIENT) )
1352 *pwparam16 = (HWND32)wParam32;
1353 *plparam = 0;
1355 else
1357 *pwparam16 = ((HWND32)*plparam == hwnd);
1358 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1359 (HWND16)LOWORD(wParam32) );
1361 return 0;
1362 case WM_NCCALCSIZE:
1364 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
1365 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1366 if (!nc) return -1;
1368 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1369 if (wParam32)
1371 WINDOWPOS16 *wp;
1372 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1373 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1374 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1376 SEGPTR_FREE(nc);
1377 return -1;
1379 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1380 nc->lppos = SEGPTR_GET(wp);
1382 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1383 *plparam = (LPARAM)SEGPTR_GET(nc);
1385 return 1;
1386 case WM_NCCREATE:
1387 case WM_CREATE:
1389 CREATESTRUCT16 *cs;
1390 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)*plparam;
1391 LPSTR name, cls;
1393 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1394 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1395 name = SEGPTR_STRDUP( cs32->lpszName );
1396 cls = SEGPTR_STRDUP( cs32->lpszClass );
1397 cs->lpszName = SEGPTR_GET(name);
1398 cs->lpszClass = SEGPTR_GET(cls);
1399 *plparam = (LPARAM)SEGPTR_GET(cs);
1401 return 1;
1402 case WM_PARENTNOTIFY:
1403 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1404 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1405 /* else nothing to do */
1406 return 0;
1407 case WM_SETTEXT:
1409 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1410 if (!str) return -1;
1411 *plparam = (LPARAM)SEGPTR_GET(str);
1413 return 1;
1414 case WM_WINDOWPOSCHANGING:
1415 case WM_WINDOWPOSCHANGED:
1417 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1418 sizeof(LPARAM) );
1419 if (!wp) return -1;
1420 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)*plparam, wp );
1421 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1422 *plparam = (LPARAM)SEGPTR_GET(wp);
1424 return 1;
1425 case WM_ASKCBFORMATNAME:
1426 case WM_DEVMODECHANGE:
1427 case WM_PAINTCLIPBOARD:
1428 case WM_SIZECLIPBOARD:
1429 case WM_WININICHANGE:
1430 fprintf( stderr, "MapMsg32ATo16: message %04x needs translation\n",
1431 msg32 );
1432 return -1;
1434 default: /* No translation needed */
1435 return 0;
1440 /**********************************************************************
1441 * WINPROC_UnmapMsg32ATo16
1443 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1445 void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1446 MSGPARAM16* p16 )
1448 switch(msg)
1450 case LB_ADDFILE32:
1451 case LB_ADDSTRING32:
1452 case LB_DIR32:
1453 case LB_FINDSTRING32:
1454 case LB_FINDSTRINGEXACT32:
1455 case LB_INSERTSTRING32:
1456 case LB_SELECTSTRING32:
1457 case LB_SETTABSTOPS32:
1458 case CB_ADDSTRING32:
1459 case CB_FINDSTRING32:
1460 case CB_FINDSTRINGEXACT32:
1461 case CB_INSERTSTRING32:
1462 case CB_SELECTSTRING32:
1463 case CB_DIR32:
1464 case WM_COMPAREITEM:
1465 case WM_DELETEITEM:
1466 case WM_DRAWITEM:
1467 case WM_SETTEXT:
1468 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1469 break;
1471 case CB_GETDROPPEDCONTROLRECT32:
1472 case LB_GETITEMRECT32:
1474 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1475 p16->lParam = *(LPARAM *)(rect + 1);
1476 CONV_RECT16TO32( rect, (RECT32 *)(p16->lParam));
1477 SEGPTR_FREE( rect );
1479 break;
1480 case LB_GETSELITEMS32:
1482 INT32 i;
1483 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1484 p16->lParam = *((LPARAM *)items - 1);
1485 for (i = 0; i < p16->wParam; i++) *((LPINT32)(p16->lParam) + i) = items[i];
1486 SEGPTR_FREE( (LPARAM *)items - 1 );
1488 break;
1490 case CB_GETEDITSEL32:
1491 if( wParam )
1492 *((LPUINT32)(wParam)) = LOWORD(p16->lResult);
1493 if( lParam )
1494 *((LPUINT32)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1495 break;
1497 case LB_GETTEXT32:
1498 case CB_GETLBTEXT32:
1499 UnMapLS( (SEGPTR)(p16->lParam) );
1500 break;
1502 case WM_MEASUREITEM:
1504 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1505 MEASUREITEMSTRUCT32 *mis32 = *(MEASUREITEMSTRUCT32 **)(mis + 1);
1506 mis32->itemWidth = mis->itemWidth;
1507 mis32->itemHeight = mis->itemHeight;
1508 SEGPTR_FREE(mis);
1510 break;
1511 case WM_GETMINMAXINFO:
1513 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1514 p16->lParam = *(LPARAM *)(mmi + 1);
1515 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)(p16->lParam) );
1516 SEGPTR_FREE(mmi);
1518 break;
1519 case WM_GETTEXT:
1521 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1522 p16->lParam = *((LPARAM *)str - 1);
1523 lstrcpyn32A( (LPSTR)(p16->lParam), str, p16->wParam );
1524 SEGPTR_FREE( (LPARAM *)str - 1 );
1526 break;
1527 case WM_MDICREATE:
1529 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1530 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1531 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1532 SEGPTR_FREE( cs );
1534 break;
1535 case WM_MDIGETACTIVE:
1536 if (lParam) *(BOOL32 *)lParam = (BOOL16)HIWORD(p16->lResult);
1537 p16->lResult = (HWND32)LOWORD(p16->lResult);
1538 break;
1539 case WM_NCCALCSIZE:
1541 NCCALCSIZE_PARAMS32 *nc32;
1542 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
1543 p16->lParam = *(LPARAM *)(nc + 1);
1544 nc32 = (NCCALCSIZE_PARAMS32 *)(p16->lParam);
1545 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1546 if (p16->wParam)
1548 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1549 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1550 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1551 nc32->lppos );
1552 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1554 SEGPTR_FREE(nc);
1556 break;
1557 case WM_NCCREATE:
1558 case WM_CREATE:
1560 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1561 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1562 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1563 SEGPTR_FREE( cs );
1565 break;
1566 case WM_WINDOWPOSCHANGING:
1567 case WM_WINDOWPOSCHANGED:
1569 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
1570 p16->lParam = *(LPARAM *)(wp + 1);
1571 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)p16->lParam );
1572 SEGPTR_FREE(wp);
1574 break;
1579 /**********************************************************************
1580 * WINPROC_MapMsg32WTo16
1582 * Map a message from 32-bit Unicode to 16-bit.
1583 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1585 INT32 WINPROC_MapMsg32WTo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1586 UINT16 *pmsg16, WPARAM16 *pwparam16,
1587 LPARAM *plparam )
1589 switch(msg32)
1591 case LB_ADDSTRING32:
1592 case LB_FINDSTRING32:
1593 case LB_FINDSTRINGEXACT32:
1594 case LB_INSERTSTRING32:
1595 case LB_SELECTSTRING32:
1596 case LB_DIR32:
1597 case LB_ADDFILE32:
1599 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1600 if (!str) return -1;
1601 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1602 *plparam = (LPARAM)SEGPTR_GET(str);
1604 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1605 return 1;
1607 case CB_ADDSTRING32:
1608 case CB_FINDSTRING32:
1609 case CB_FINDSTRINGEXACT32:
1610 case CB_INSERTSTRING32:
1611 case CB_SELECTSTRING32:
1612 case CB_DIR32:
1614 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1615 if (!str) return -1;
1616 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1617 *plparam = (LPARAM)SEGPTR_GET(str);
1619 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING32);
1620 return 1;
1622 case WM_NCCREATE:
1623 case WM_CREATE:
1625 CREATESTRUCT16 *cs;
1626 CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
1627 LPSTR name, cls;
1629 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1630 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
1631 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
1632 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
1633 cs->lpszName = SEGPTR_GET(name);
1634 cs->lpszClass = SEGPTR_GET(cls);
1635 *pmsg16 = (UINT16)msg32;
1636 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1637 *plparam = (LPARAM)SEGPTR_GET(cs);
1639 return 1;
1640 case WM_MDICREATE:
1642 MDICREATESTRUCT16 *cs;
1643 MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
1644 LPSTR name, cls;
1646 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1647 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
1648 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
1649 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
1650 cs->szTitle = SEGPTR_GET(name);
1651 cs->szClass = SEGPTR_GET(cls);
1652 *pmsg16 = (UINT16)msg32;
1653 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1654 *plparam = (LPARAM)SEGPTR_GET(cs);
1656 return 1;
1657 case WM_SETTEXT:
1659 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1660 if (!str) return -1;
1661 *pmsg16 = (UINT16)msg32;
1662 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1663 *plparam = (LPARAM)SEGPTR_GET(str);
1665 return 1;
1666 default: /* No Unicode translation needed */
1667 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
1668 pwparam16, plparam );
1673 /**********************************************************************
1674 * WINPROC_UnmapMsg32WTo16
1676 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1678 void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1679 MSGPARAM16* p16 )
1681 switch(msg)
1683 case WM_GETTEXT:
1685 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1686 p16->lParam = *((LPARAM *)str - 1);
1687 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
1688 SEGPTR_FREE( (LPARAM *)str - 1 );
1690 break;
1691 default:
1692 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, p16 );
1693 break;
1698 /**********************************************************************
1699 * WINPROC_CallProc32ATo32W
1701 * Call a window procedure, translating args from Ansi to Unicode.
1703 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
1704 UINT32 msg, WPARAM32 wParam,
1705 LPARAM lParam )
1707 LRESULT result;
1709 if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
1710 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1711 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1712 return result;
1716 /**********************************************************************
1717 * WINPROC_CallProc32WTo32A
1719 * Call a window procedure, translating args from Unicode to Ansi.
1721 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
1722 UINT32 msg, WPARAM32 wParam,
1723 LPARAM lParam )
1725 LRESULT result;
1727 if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
1728 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1729 WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
1730 return result;
1734 /**********************************************************************
1735 * WINPROC_CallProc16To32A
1737 * Call a 32-bit window procedure, translating the 16-bit args.
1739 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
1740 WPARAM16 wParam, LPARAM lParam,
1741 WNDPROC32 func )
1743 LRESULT result;
1744 UINT32 msg32;
1745 WPARAM32 wParam32;
1747 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1748 return 0;
1749 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1750 return WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam, result );
1754 /**********************************************************************
1755 * WINPROC_CallProc16To32W
1757 * Call a 32-bit window procedure, translating the 16-bit args.
1759 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
1760 WPARAM16 wParam, LPARAM lParam,
1761 WNDPROC32 func )
1763 LRESULT result;
1764 UINT32 msg32;
1765 WPARAM32 wParam32;
1767 if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1768 return 0;
1769 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1770 return WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam, result );
1774 /**********************************************************************
1775 * WINPROC_CallProc32ATo16
1777 * Call a 16-bit window procedure, translating the 32-bit args.
1779 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
1780 UINT32 msg, WPARAM32 wParam,
1781 LPARAM lParam )
1783 UINT16 msg16;
1784 MSGPARAM16 mp16;
1786 mp16.lParam = lParam;
1787 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
1788 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
1789 return 0;
1790 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1791 mp16.wParam, mp16.lParam );
1792 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, &mp16 );
1793 return mp16.lResult;
1797 /**********************************************************************
1798 * WINPROC_CallProc32WTo16
1800 * Call a 16-bit window procedure, translating the 32-bit args.
1802 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
1803 UINT32 msg, WPARAM32 wParam,
1804 LPARAM lParam )
1806 UINT16 msg16;
1807 MSGPARAM16 mp16;
1809 mp16.lParam = lParam;
1810 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
1811 &mp16.lParam ) == -1)
1812 return 0;
1813 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1814 mp16.wParam, mp16.lParam );
1815 WINPROC_UnmapMsg32WTo16( msg, wParam, lParam, &mp16 );
1816 return mp16.lResult;
1820 /**********************************************************************
1821 * CallWindowProc16 (USER.122)
1823 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
1824 WPARAM16 wParam, LPARAM lParam )
1826 WINDOWPROC *proc = WINPROC_GetPtr( func );
1828 if (!proc)
1829 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1831 #if testing
1832 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
1833 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1834 #endif
1836 switch(proc->type)
1838 case WIN_PROC_16:
1839 if (!proc->thunk.t_from32.proc) return 0;
1840 return Callbacks->CallWndProc( proc->thunk.t_from32.proc,
1841 hwnd, msg, wParam, lParam );
1842 case WIN_PROC_32A:
1843 if (!proc->thunk.t_from16.proc) return 0;
1844 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
1845 proc->thunk.t_from16.proc );
1846 case WIN_PROC_32W:
1847 if (!proc->thunk.t_from16.proc) return 0;
1848 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
1849 proc->thunk.t_from16.proc );
1850 default:
1851 fprintf( stderr, "CallWindowProc16: invalid proc %p\n", proc );
1852 return 0;
1857 /**********************************************************************
1858 * CallWindowProc32A (USER32.17)
1860 LRESULT WINAPI CallWindowProc32A( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1861 WPARAM32 wParam, LPARAM lParam )
1863 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1865 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1867 #if testing
1868 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
1869 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1870 #endif
1872 switch(proc->type)
1874 case WIN_PROC_16:
1875 if (!proc->thunk.t_from32.proc) return 0;
1876 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
1877 hwnd, msg, wParam, lParam );
1878 case WIN_PROC_32A:
1879 if (!proc->thunk.t_from16.proc) return 0;
1880 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
1881 hwnd, msg, wParam, lParam );
1882 case WIN_PROC_32W:
1883 if (!proc->thunk.t_from16.proc) return 0;
1884 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
1885 hwnd, msg, wParam, lParam );
1886 default:
1887 fprintf( stderr, "CallWindowProc32A: invalid proc %p\n", proc );
1888 return 0;
1893 /**********************************************************************
1894 * CallWindowProc32W (USER32.18)
1896 LRESULT WINAPI CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1897 WPARAM32 wParam, LPARAM lParam )
1899 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1901 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1903 #if testing
1904 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
1905 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1906 #endif
1908 switch(proc->type)
1910 case WIN_PROC_16:
1911 if (!proc->thunk.t_from32.proc) return 0;
1912 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
1913 hwnd, msg, wParam, lParam );
1914 case WIN_PROC_32A:
1915 if (!proc->thunk.t_from16.proc) return 0;
1916 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
1917 hwnd, msg, wParam, lParam );
1918 case WIN_PROC_32W:
1919 if (!proc->thunk.t_from16.proc) return 0;
1920 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
1921 hwnd, msg, wParam, lParam );
1922 default:
1923 fprintf( stderr, "CallWindowProc32W: invalid proc %p\n", proc );
1924 return 0;