Release 961222
[wine/multimedia.git] / windows / winproc.c
blob6cbe823714731e43f8d368240a28826bf2672f61
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 "ldt.h"
13 #include "registers.h"
14 #include "stackframe.h"
15 #include "struct32.h"
16 #include "win.h"
17 #include "winproc.h"
18 #include "stddebug.h"
19 #include "debug.h"
21 /* Window procedure 16-bit thunk; see BuildSpec16Files() in tools/build.c */
22 typedef struct
24 BYTE popl_eax; /* popl %eax (return address) */
25 BYTE pushl_func; /* pushl $proc */
26 WNDPROC32 proc WINE_PACKED;
27 BYTE pushl_eax; /* pushl %eax */
28 WORD pushw_bp WINE_PACKED; /* pushw %bp */
29 BYTE pushl_thunk; /* pushl $thunkfrom16 */
30 void (*thunk32)() WINE_PACKED;
31 BYTE lcall; /* lcall cs:relay */
32 void (*relay)() WINE_PACKED;
33 WORD cs WINE_PACKED;
34 } WINPROC_THUNK_FROM16;
36 /* Window procedure 32-bit thunk; see BuildSpec32Files() in tools/build.c */
37 typedef struct
39 BYTE popl_eax; /* popl %eax (return address) */
40 BYTE pushl_func; /* pushl $proc */
41 WNDPROC16 proc WINE_PACKED;
42 BYTE pushl_eax; /* pushl %eax */
43 BYTE pushl_ebp; /* pushl %ebp */
44 BYTE pushl_name; /* pushl $name */
45 LPCSTR name WINE_PACKED;
46 BYTE pushl_thunk; /* pushl $thunkfrom32 */
47 void (*thunk32)() WINE_PACKED;
48 BYTE jmp; /* jmp relay (relative jump)*/
49 void (*relay)() WINE_PACKED;
50 } WINPROC_THUNK_FROM32;
52 /* Simple jmp to call 32-bit procedure directly */
53 typedef struct
55 BYTE jmp; /* jmp proc (relative jump) */
56 WNDPROC32 proc WINE_PACKED;
57 } WINPROC_JUMP;
59 typedef union
61 WINPROC_THUNK_FROM16 t_from16;
62 WINPROC_THUNK_FROM32 t_from32;
63 } WINPROC_THUNK;
65 typedef struct tagWINDOWPROC
67 WINPROC_THUNK thunk; /* Thunk */
68 WINPROC_JUMP jmp; /* Jump */
69 struct tagWINDOWPROC *next; /* Next window proc */
70 UINT32 magic; /* Magic number */
71 WINDOWPROCTYPE type; /* Function type */
72 } WINDOWPROC;
74 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
76 #define WINPROC_THUNKPROC(pproc) \
77 (((pproc)->type == WIN_PROC_16) ? \
78 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
79 (WNDPROC16)((pproc)->thunk.t_from16.proc))
81 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
82 WPARAM16 wParam, LPARAM lParam,
83 WNDPROC32 func );
84 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
85 WPARAM16 wParam, LPARAM lParam,
86 WNDPROC32 func );
87 static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
88 UINT32 msg, WPARAM32 wParam,
89 LPARAM lParam );
90 static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
91 UINT32 msg, WPARAM32 wParam,
92 LPARAM lParam );
94 #ifndef WINELIB
95 extern void CallFrom16_long_wwwll(void);
96 extern void CallFrom32_stdcall_5(void);
97 #else
98 static void CallFrom16_long_wwwll(void) {}
99 static void CallFrom32_stdcall_5(void) {}
100 #endif /* WINELIB */
102 static HANDLE32 WinProcHeap;
104 /**********************************************************************
105 * WINPROC_Init
107 BOOL32 WINPROC_Init(void)
109 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
110 if (!WinProcHeap)
112 fprintf( stderr, "Unable to create winproc heap\n" );
113 return FALSE;
115 return TRUE;
119 /**********************************************************************
120 * WINPROC_GetPtr
122 * Return a pointer to the win proc.
124 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
126 BYTE *ptr;
127 WINDOWPROC *proc;
129 /* Check for a linear pointer */
131 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
133 ptr = (BYTE *)handle;
134 /* First check if it is the jmp address */
135 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
136 (int)&((WINDOWPROC *)0)->thunk;
137 /* Now it must be the thunk address */
138 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
139 /* Now we have a pointer to the WINDOWPROC struct */
140 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
141 return (WINDOWPROC *)ptr;
144 /* Check for a segmented pointer */
146 if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
148 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
149 if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
150 /* It must be the thunk address */
151 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
152 /* Now we have a pointer to the WINDOWPROC struct */
153 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
154 return (WINDOWPROC *)ptr;
157 return NULL;
161 /**********************************************************************
162 * WINPROC_AllocWinProc
164 * Allocate a new window procedure.
166 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type )
168 WINDOWPROC *proc, *oldproc;
170 /* Allocate a window procedure */
172 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
174 /* Check if the function is already a win proc */
176 if ((oldproc = WINPROC_GetPtr( func )))
178 *proc = *oldproc;
180 else
182 switch(type)
184 case WIN_PROC_16:
185 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
186 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
187 proc->thunk.t_from32.proc = func;
188 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
189 proc->thunk.t_from32.pushl_ebp = 0x55; /* pushl %ebp */
190 proc->thunk.t_from32.pushl_name = 0x68; /* pushl $name */
191 proc->thunk.t_from32.name = "WINPROC_CallProc32ATo16";
192 proc->thunk.t_from32.pushl_thunk = 0x68; /* pushl $thunkfrom32 */
193 proc->thunk.t_from32.thunk32 = (void(*)())WINPROC_CallProc32ATo16;
194 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
195 proc->thunk.t_from32.relay = /* relative jump */
196 (void (*)())((DWORD)CallFrom32_stdcall_5 -
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 = CallFrom16_long_wwwll;
212 proc->thunk.t_from16.cs = WINE_CODE_SELECTOR;
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;
225 proc->next = NULL;
226 dprintf_win( stddeb, "WINPROC_AllocWinProc(%08x,%d): returning %08x\n",
227 (UINT32)func, type, (UINT32)proc );
228 return proc;
232 /**********************************************************************
233 * WINPROC_GetProc
235 * Get a window procedure pointer that can be passed to the Windows program.
237 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
239 if (type == WIN_PROC_16) /* We want a 16:16 address */
241 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
242 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
243 else
244 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
245 &((WINDOWPROC *)proc)->thunk );
247 else /* We want a 32-bit address */
249 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
250 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
251 else
252 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
257 /**********************************************************************
258 * WINPROC_SetProc
260 * Set the window procedure for a window or class.
262 BOOL32 WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
263 WINDOWPROCTYPE type )
265 WINDOWPROC *proc, **ppPrev;
267 /* Check if function is already in the list */
269 ppPrev = (WINDOWPROC **)pFirst;
270 proc = WINPROC_GetPtr( func );
271 while (*ppPrev)
273 if (proc)
275 if (*ppPrev == proc) break;
277 else
279 if (((*ppPrev)->type == type) &&
280 (func == WINPROC_THUNKPROC(*ppPrev))) break;
282 ppPrev = &(*ppPrev)->next;
285 if (*ppPrev) /* Remove it from the list */
287 proc = *ppPrev;
288 *ppPrev = proc->next;
290 else /* Allocate a new one */
292 if (proc) /* Was already a win proc */
294 type = proc->type;
295 func = WINPROC_THUNKPROC(proc);
297 proc = WINPROC_AllocWinProc( func, type );
298 if (!proc) return FALSE;
301 /* Add the win proc at the head of the list */
303 dprintf_win( stddeb, "WINPROC_SetProc(%08x,%08x,%d): res=%08x\n",
304 (UINT32)*pFirst, (UINT32)func, type, (UINT32)proc );
305 proc->next = *(WINDOWPROC **)pFirst;
306 *(WINDOWPROC **)pFirst = proc;
307 return TRUE;
311 /**********************************************************************
312 * WINPROC_FreeProc
314 * Free a list of win procs.
316 void WINPROC_FreeProc( HWINDOWPROC proc )
318 while (proc)
320 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
321 dprintf_win( stddeb, "WINPROC_FreeProc: freeing %08x\n", (UINT32)proc);
322 HeapFree( WinProcHeap, 0, proc );
323 proc = next;
328 /**********************************************************************
329 * WINPROC_GetProcType
331 * Return the window procedure type.
333 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
335 if (!proc ||
336 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
337 return WIN_PROC_INVALID;
338 return ((WINDOWPROC *)proc)->type;
342 /**********************************************************************
343 * WINPROC_MapMsg32ATo32W
345 * Map a message from Ansi to Unicode.
346 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
348 INT32 WINPROC_MapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
350 switch(msg)
352 case WM_GETTEXT:
354 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
355 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
356 if (!ptr) return -1;
357 *ptr++ = *plparam; /* Store previous lParam */
358 *plparam = (LPARAM)ptr;
360 return 1;
361 case WM_SETTEXT:
362 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
363 return (*plparam ? 1 : -1);
364 case WM_NCCREATE:
365 case WM_CREATE:
367 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
368 sizeof(*cs) );
369 if (!cs) return -1;
370 *cs = *(CREATESTRUCT32W *)*plparam;
371 if (HIWORD(cs->lpszName))
372 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
373 (LPCSTR)cs->lpszName );
374 if (HIWORD(cs->lpszClass))
375 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
376 (LPCSTR)cs->lpszClass );
377 *plparam = (LPARAM)cs;
379 return 1;
380 case WM_MDICREATE:
382 MDICREATESTRUCT32W *cs =
383 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
384 if (!cs) return -1;
385 *cs = *(MDICREATESTRUCT32W *)*plparam;
386 if (HIWORD(cs->szClass))
387 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
388 (LPCSTR)cs->szClass );
389 if (HIWORD(cs->szTitle))
390 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
391 (LPCSTR)cs->szTitle );
392 *plparam = (LPARAM)cs;
394 return 1;
395 case WM_ASKCBFORMATNAME:
396 case WM_DEVMODECHANGE:
397 case WM_MDIACTIVATE:
398 case WM_PAINTCLIPBOARD:
399 case WM_SIZECLIPBOARD:
400 case WM_WININICHANGE:
401 fprintf( stderr, "MapMsg32ATo32W: message %04x needs translation\n",
402 msg );
403 return -1;
404 default: /* No translation needed */
405 return 0;
410 /**********************************************************************
411 * WINPROC_UnmapMsg32ATo32W
413 * Unmap a message that was mapped from Ansi to Unicode.
415 void WINPROC_UnmapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
417 switch(msg)
419 case WM_GETTEXT:
421 LPARAM *ptr = (LPARAM *)lParam - 1;
422 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)(ptr + 1), wParam );
423 HeapFree( SystemHeap, 0, ptr );
425 break;
426 case WM_SETTEXT:
427 HeapFree( SystemHeap, 0, (void *)lParam );
428 break;
429 case WM_NCCREATE:
430 case WM_CREATE:
432 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
433 if (HIWORD(cs->lpszName))
434 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
435 if (HIWORD(cs->lpszClass))
436 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
437 HeapFree( SystemHeap, 0, cs );
439 break;
440 case WM_MDICREATE:
442 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
443 if (HIWORD(cs->szTitle))
444 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
445 if (HIWORD(cs->szClass))
446 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
447 HeapFree( SystemHeap, 0, cs );
449 break;
454 /**********************************************************************
455 * WINPROC_MapMsg32WTo32A
457 * Map a message from Unicode to Ansi.
458 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
460 INT32 WINPROC_MapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
462 switch(msg)
464 case WM_GETTEXT:
466 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
467 wParam + sizeof(LPARAM) );
468 if (!ptr) return -1;
469 *ptr++ = *plparam; /* Store previous lParam */
470 *plparam = (LPARAM)ptr;
472 return 1;
473 case WM_SETTEXT:
474 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
475 return (*plparam ? 1 : -1);
476 case WM_NCCREATE:
477 case WM_CREATE:
479 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
480 sizeof(*cs) );
481 if (!cs) return -1;
482 *cs = *(CREATESTRUCT32A *)*plparam;
483 if (HIWORD(cs->lpszName))
484 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
485 (LPCWSTR)cs->lpszName );
486 if (HIWORD(cs->lpszClass))
487 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
488 (LPCWSTR)cs->lpszClass);
489 *plparam = (LPARAM)cs;
491 return 1;
492 case WM_MDICREATE:
494 MDICREATESTRUCT32A *cs =
495 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
496 if (!cs) return -1;
497 *cs = *(MDICREATESTRUCT32A *)*plparam;
498 if (HIWORD(cs->szTitle))
499 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
500 (LPCWSTR)cs->szTitle );
501 if (HIWORD(cs->szClass))
502 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
503 (LPCWSTR)cs->szClass );
504 *plparam = (LPARAM)cs;
506 return 1;
507 case WM_ASKCBFORMATNAME:
508 case WM_DEVMODECHANGE:
509 case WM_MDIACTIVATE:
510 case WM_PAINTCLIPBOARD:
511 case WM_SIZECLIPBOARD:
512 case WM_WININICHANGE:
513 fprintf( stderr, "MapMsg32WTo32A: message %04x needs translation\n",
514 msg );
515 return -1;
516 default: /* No translation needed */
517 return 0;
522 /**********************************************************************
523 * WINPROC_UnmapMsg32WTo32A
525 * Unmap a message that was mapped from Unicode to Ansi.
527 void WINPROC_UnmapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
529 switch(msg)
531 case WM_GETTEXT:
533 LPARAM *ptr = (LPARAM *)lParam - 1;
534 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)(ptr + 1), wParam );
535 HeapFree( SystemHeap, 0, ptr );
537 break;
538 case WM_SETTEXT:
539 HeapFree( SystemHeap, 0, (void *)lParam );
540 break;
541 case WM_NCCREATE:
542 case WM_CREATE:
544 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
545 if (HIWORD(cs->lpszName))
546 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
547 if (HIWORD(cs->lpszClass))
548 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
549 HeapFree( SystemHeap, 0, cs );
551 break;
552 case WM_MDICREATE:
554 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
555 if (HIWORD(cs->szTitle))
556 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
557 if (HIWORD(cs->szClass))
558 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
559 HeapFree( SystemHeap, 0, cs );
561 break;
566 /**********************************************************************
567 * WINPROC_MapMsg16To32A
569 * Map a message from 16- to 32-bit Ansi.
570 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
572 INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
573 WPARAM32 *pwparam32, LPARAM *plparam )
575 *pmsg32 = (UINT32)msg16;
576 *pwparam32 = (WPARAM32)wParam16;
577 switch(msg16)
579 case WM_ACTIVATE:
580 case WM_CHARTOITEM:
581 case WM_COMMAND:
582 case WM_VKEYTOITEM:
583 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
584 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
585 return 0;
586 case WM_HSCROLL:
587 case WM_VSCROLL:
588 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
589 *plparam = (LPARAM)(HWND32)HIWORD(*plparam);
590 return 0;
591 case WM_CTLCOLOR:
592 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
593 *pwparam32 = (WPARAM32)(HDC32)wParam16;
594 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
595 return 0;
596 case WM_COMPAREITEM:
598 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
599 COMPAREITEMSTRUCT32 *cis = (COMPAREITEMSTRUCT32 *)
600 HeapAlloc(SystemHeap, 0, sizeof(*cis));
601 if (!cis) return -1;
602 cis->CtlType = cis16->CtlType;
603 cis->CtlID = cis16->CtlID;
604 cis->hwndItem = cis16->hwndItem;
605 cis->itemID1 = cis16->itemID1;
606 cis->itemData1 = cis16->itemData1;
607 cis->itemID2 = cis16->itemID2;
608 cis->itemData2 = cis16->itemData2;
609 cis->dwLocaleId = 0; /* FIXME */
610 *plparam = (LPARAM)cis;
612 return 1;
613 case WM_DELETEITEM:
615 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
616 DELETEITEMSTRUCT32 *dis = (DELETEITEMSTRUCT32 *)
617 HeapAlloc(SystemHeap, 0, sizeof(*dis));
618 if (!dis) return -1;
619 dis->CtlType = dis16->CtlType;
620 dis->CtlID = dis16->CtlID;
621 dis->hwndItem = dis16->hwndItem;
622 dis->itemData = dis16->itemData;
623 *plparam = (LPARAM)dis;
625 return 1;
626 case WM_MEASUREITEM:
628 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
629 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)
630 HeapAlloc(SystemHeap, 0,
631 sizeof(*mis) + sizeof(LPARAM));
632 if (!mis) return -1;
633 mis->CtlType = mis16->CtlType;
634 mis->CtlID = mis16->CtlID;
635 mis->itemID = mis16->itemID;
636 mis->itemWidth = mis16->itemWidth;
637 mis->itemHeight = mis16->itemHeight;
638 mis->itemData = mis16->itemData;
639 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
640 *plparam = (LPARAM)mis;
642 return 1;
643 case WM_DRAWITEM:
645 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
646 DRAWITEMSTRUCT32 *dis = (DRAWITEMSTRUCT32*)HeapAlloc(SystemHeap, 0,
647 sizeof(*dis));
648 if (!dis) return -1;
649 dis->CtlType = dis16->CtlType;
650 dis->CtlID = dis16->CtlID;
651 dis->itemID = dis16->itemID;
652 dis->itemAction = dis16->itemAction;
653 dis->itemState = dis16->itemState;
654 dis->hwndItem = dis16->hwndItem;
655 dis->hDC = dis16->hDC;
656 dis->itemData = dis16->itemData;
657 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
658 *plparam = (LPARAM)dis;
660 return 1;
661 case WM_GETMINMAXINFO:
663 MINMAXINFO32 *mmi = (MINMAXINFO32 *)HeapAlloc( SystemHeap, 0,
664 sizeof(*mmi) + sizeof(LPARAM));
665 if (!mmi) return -1;
666 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
667 mmi );
668 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
669 *plparam = (LPARAM)mmi;
671 return 1;
672 case WM_GETTEXT:
673 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
674 return 0;
675 case WM_MDICREATE:
677 MDICREATESTRUCT16 *cs16 =
678 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
679 MDICREATESTRUCT32A *cs =
680 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
681 sizeof(*cs) + sizeof(LPARAM) );
682 if (!cs) return -1;
683 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
684 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
685 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
686 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
687 *plparam = (LPARAM)cs;
689 return 1;
690 case WM_MDISETMENU:
691 *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
692 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
693 return 0;
694 case WM_MENUCHAR:
695 case WM_MENUSELECT:
696 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
697 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
698 return 0;
699 case WM_NCCALCSIZE:
701 NCCALCSIZE_PARAMS16 *nc16;
702 NCCALCSIZE_PARAMS32 *nc;
704 nc = (NCCALCSIZE_PARAMS32 *)HeapAlloc( SystemHeap, 0,
705 sizeof(*nc) + sizeof(LPARAM) );
706 if (!nc) return -1;
707 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
708 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
709 if (wParam16)
711 nc->lppos = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
712 sizeof(*nc->lppos) );
713 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
714 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
715 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
717 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
718 *plparam = (LPARAM)nc;
720 return 1;
721 case WM_NCCREATE:
722 case WM_CREATE:
724 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
725 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
726 sizeof(*cs) + sizeof(LPARAM) );
727 if (!cs) return -1;
728 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
729 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
730 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
731 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
732 *plparam = (LPARAM)cs;
734 return 1;
735 case WM_PARENTNOTIFY:
736 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
738 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
739 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
741 return 0;
742 case WM_SETTEXT:
743 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
744 return 0;
745 case WM_WINDOWPOSCHANGING:
746 case WM_WINDOWPOSCHANGED:
748 WINDOWPOS32 *wp = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
749 sizeof(*wp) + sizeof(LPARAM) );
750 if (!wp) return -1;
751 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
752 wp );
753 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
754 *plparam = (LPARAM)wp;
756 return 1;
757 case WM_ASKCBFORMATNAME:
758 case WM_DEVMODECHANGE:
759 case WM_MDIACTIVATE:
760 case WM_PAINTCLIPBOARD:
761 case WM_SIZECLIPBOARD:
762 case WM_WININICHANGE:
763 fprintf( stderr, "MapMsg16To32A: message %04x needs translation\n",
764 msg16 );
765 return -1;
767 default: /* No translation needed */
768 return 0;
773 /**********************************************************************
774 * WINPROC_UnmapMsg16To32A
776 * Unmap a message that was mapped from 16- to 32-bit Ansi.
778 void WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
780 switch(msg)
782 case WM_COMPAREITEM:
783 case WM_DELETEITEM:
784 case WM_DRAWITEM:
785 HeapFree( SystemHeap, 0, (LPVOID)lParam );
786 break;
787 case WM_MEASUREITEM:
789 MEASUREITEMSTRUCT16 *mis16;
790 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)lParam;
791 lParam = *(LPARAM *)(mis + 1);
792 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
793 mis16->itemWidth = (UINT16)mis->itemWidth;
794 mis16->itemHeight = (UINT16)mis->itemHeight;
795 HeapFree( SystemHeap, 0, mis );
797 break;
798 case WM_GETMINMAXINFO:
800 MINMAXINFO32 *mmi = (MINMAXINFO32 *)lParam;
801 lParam = *(LPARAM *)(mmi + 1);
802 STRUCT32_MINMAXINFO32to16( mmi,
803 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
804 HeapFree( SystemHeap, 0, mmi );
806 break;
807 case WM_MDICREATE:
809 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
810 lParam = *(LPARAM *)(cs + 1);
811 STRUCT32_MDICREATESTRUCT32Ato16( cs,
812 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
813 HeapFree( SystemHeap, 0, cs );
815 break;
816 case WM_NCCALCSIZE:
818 NCCALCSIZE_PARAMS16 *nc16;
819 NCCALCSIZE_PARAMS32 *nc = (NCCALCSIZE_PARAMS32 *)lParam;
820 lParam = *(LPARAM *)(nc + 1);
821 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
822 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
823 if (wParam)
825 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
826 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
827 if (nc->lppos)
829 STRUCT32_WINDOWPOS32to16( nc->lppos,
830 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
831 HeapFree( SystemHeap, 0, nc->lppos );
834 HeapFree( SystemHeap, 0, nc );
836 break;
837 case WM_NCCREATE:
838 case WM_CREATE:
840 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
841 lParam = *(LPARAM *)(cs + 1);
842 STRUCT32_CREATESTRUCT32Ato16( cs,
843 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
844 HeapFree( SystemHeap, 0, cs );
846 break;
847 case WM_WINDOWPOSCHANGING:
848 case WM_WINDOWPOSCHANGED:
850 WINDOWPOS32 *wp = (WINDOWPOS32 *)lParam;
851 lParam = *(LPARAM *)(wp + 1);
852 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
853 HeapFree( SystemHeap, 0, wp );
855 break;
860 /**********************************************************************
861 * WINPROC_MapMsg16To32W
863 * Map a message from 16- to 32-bit Unicode.
864 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
866 INT32 WINPROC_MapMsg16To32W( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
867 WPARAM32 *pwparam32, LPARAM *plparam )
869 switch(msg16)
871 case WM_GETTEXT:
872 case WM_SETTEXT:
873 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
874 return WINPROC_MapMsg32ATo32W( *pmsg32, *pwparam32, plparam );
875 case WM_NCCREATE:
876 case WM_CREATE:
878 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
879 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
880 sizeof(*cs) + sizeof(LPARAM) );
881 if (!cs) return -1;
882 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCT32A *)cs );
883 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
884 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
885 if (HIWORD(cs->lpszName))
886 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
887 (LPCSTR)cs->lpszName );
888 if (HIWORD(cs->lpszClass))
889 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
890 (LPCSTR)cs->lpszClass );
891 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
892 *plparam = (LPARAM)cs;
894 return 1;
895 case WM_MDICREATE:
897 MDICREATESTRUCT16 *cs16 =
898 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
899 MDICREATESTRUCT32W *cs =
900 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
901 sizeof(*cs) + sizeof(LPARAM) );
902 if (!cs) return -1;
903 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCT32A *)cs );
904 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
905 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
906 if (HIWORD(cs->szTitle))
907 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
908 (LPCSTR)cs->szTitle );
909 if (HIWORD(cs->szClass))
910 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
911 (LPCSTR)cs->szClass );
912 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
913 *plparam = (LPARAM)cs;
915 return 1;
916 default: /* No Unicode translation needed */
917 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
918 pwparam32, plparam );
923 /**********************************************************************
924 * WINPROC_UnmapMsg16To32W
926 * Unmap a message that was mapped from 16- to 32-bit Unicode.
928 void WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
930 switch(msg)
932 case WM_GETTEXT:
933 case WM_SETTEXT:
934 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
935 break;
936 case WM_NCCREATE:
937 case WM_CREATE:
939 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
940 lParam = *(LPARAM *)(cs + 1);
941 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
942 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
943 if (HIWORD(cs->lpszName))
944 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
945 if (HIWORD(cs->lpszClass))
946 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
947 HeapFree( SystemHeap, 0, cs );
949 break;
950 case WM_MDICREATE:
952 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
953 lParam = *(LPARAM *)(cs + 1);
954 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
955 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
956 if (HIWORD(cs->szTitle))
957 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
958 if (HIWORD(cs->szClass))
959 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
960 HeapFree( SystemHeap, 0, cs );
962 break;
963 default:
964 WINPROC_UnmapMsg16To32A( msg, wParam, lParam );
965 break;
970 /**********************************************************************
971 * WINPROC_MapMsg32ATo16
973 * Map a message from 32-bit Ansi to 16-bit.
974 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
976 INT32 WINPROC_MapMsg32ATo16( UINT32 msg32, WPARAM32 wParam32, UINT16 *pmsg16,
977 WPARAM16 *pwparam16, LPARAM *plparam )
979 *pmsg16 = (UINT16)msg32;
980 *pwparam16 = (WPARAM16)LOWORD(wParam32);
981 switch(msg32)
983 case BM_GETCHECK32:
984 case BM_SETCHECK32:
985 case BM_GETSTATE32:
986 case BM_SETSTATE32:
987 case BM_SETSTYLE32:
988 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK32);
989 return 0;
990 case LB_CARETOFF32:
991 case LB_CARETON32:
992 case LB_DELETESTRING32:
993 case LB_GETANCHORINDEX32:
994 case LB_GETCARETINDEX32:
995 case LB_GETCOUNT32:
996 case LB_GETCURSEL32:
997 case LB_GETHORIZONTALEXTENT32:
998 case LB_GETITEMDATA32:
999 case LB_GETITEMHEIGHT32:
1000 case LB_GETSEL32:
1001 case LB_GETSELCOUNT32:
1002 case LB_GETTEXTLEN32:
1003 case LB_GETTOPINDEX32:
1004 case LB_RESETCONTENT32:
1005 case LB_SELITEMRANGE32:
1006 case LB_SELITEMRANGEEX32:
1007 case LB_SETANCHORINDEX32:
1008 case LB_SETCARETINDEX32:
1009 case LB_SETCOLUMNWIDTH32:
1010 case LB_SETCURSEL32:
1011 case LB_SETHORIZONTALEXTENT32:
1012 case LB_SETITEMDATA32:
1013 case LB_SETITEMHEIGHT32:
1014 case LB_SETSEL32:
1015 case LB_SETTOPINDEX32:
1016 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1017 return 0;
1018 case LB_ADDSTRING32:
1019 case LB_FINDSTRING32:
1020 case LB_FINDSTRINGEXACT32:
1021 case LB_INSERTSTRING32:
1022 case LB_SELECTSTRING32:
1023 case LB_DIR32:
1024 case LB_ADDFILE32:
1025 /* case LB_GETTEXT32: FIXME */
1027 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1028 if (!str) return -1;
1029 *plparam = (LPARAM)SEGPTR_GET(str);
1031 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1032 return 1;
1033 case LB_GETITEMRECT32:
1035 RECT16 *rect;
1036 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1037 if (!rect) return -1;
1038 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1039 *plparam = (LPARAM)SEGPTR_GET(rect);
1041 return 1;
1042 case LB_GETSELITEMS32:
1044 LPINT16 items;
1045 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1046 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1047 + sizeof(LPARAM)))) return -1;
1048 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1049 *plparam = (LPARAM)SEGPTR_GET(items);
1051 return 1;
1052 case LB_SETTABSTOPS32:
1053 if (wParam32)
1055 INT32 i;
1056 LPINT16 stops;
1057 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1058 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1059 + sizeof(LPARAM)))) return -1;
1060 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT32)*plparam+i);
1061 *plparam = (LPARAM)SEGPTR_GET(stops);
1062 return 1;
1064 *pmsg16 = LB_SETTABSTOPS16;
1065 return 0;
1066 case WM_ACTIVATE:
1067 case WM_CHARTOITEM:
1068 case WM_COMMAND:
1069 case WM_VKEYTOITEM:
1070 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1071 return 0;
1072 case WM_HSCROLL:
1073 case WM_VSCROLL:
1074 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1075 return 0;
1076 case WM_CTLCOLORMSGBOX:
1077 case WM_CTLCOLOREDIT:
1078 case WM_CTLCOLORLISTBOX:
1079 case WM_CTLCOLORBTN:
1080 case WM_CTLCOLORDLG:
1081 case WM_CTLCOLORSCROLLBAR:
1082 case WM_CTLCOLORSTATIC:
1083 *pmsg16 = WM_CTLCOLOR;
1084 *plparam = MAKELPARAM( (HWND16)*plparam,
1085 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1086 return 0;
1087 case WM_COMPAREITEM:
1089 COMPAREITEMSTRUCT32 *cis32 = (COMPAREITEMSTRUCT32 *)*plparam;
1090 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1091 if (!cis) return -1;
1092 cis->CtlType = (UINT16)cis32->CtlType;
1093 cis->CtlID = (UINT16)cis32->CtlID;
1094 cis->hwndItem = (HWND16)cis32->hwndItem;
1095 cis->itemID1 = (UINT16)cis32->itemID1;
1096 cis->itemData1 = cis32->itemData1;
1097 cis->itemID2 = (UINT16)cis32->itemID2;
1098 cis->itemData2 = cis32->itemData2;
1099 *plparam = (LPARAM)SEGPTR_GET(cis);
1101 return 1;
1102 case WM_DELETEITEM:
1104 DELETEITEMSTRUCT32 *dis32 = (DELETEITEMSTRUCT32 *)*plparam;
1105 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1106 if (!dis) return -1;
1107 dis->CtlType = (UINT16)dis32->CtlType;
1108 dis->CtlID = (UINT16)dis32->CtlID;
1109 dis->itemID = (UINT16)dis32->itemID;
1110 dis->hwndItem = (HWND16)dis32->hwndItem;
1111 dis->itemData = dis32->itemData;
1112 *plparam = (LPARAM)SEGPTR_GET(dis);
1114 return 1;
1115 case WM_DRAWITEM:
1117 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)*plparam;
1118 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1119 if (!dis) return -1;
1120 dis->CtlType = (UINT16)dis32->CtlType;
1121 dis->CtlID = (UINT16)dis32->CtlID;
1122 dis->itemID = (UINT16)dis32->itemID;
1123 dis->itemAction = (UINT16)dis32->itemAction;
1124 dis->itemState = (UINT16)dis32->itemState;
1125 dis->hwndItem = (HWND16)dis32->hwndItem;
1126 dis->hDC = (HDC16)dis32->hDC;
1127 dis->itemData = dis32->itemData;
1128 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1129 *plparam = (LPARAM)SEGPTR_GET(dis);
1131 return 1;
1132 case WM_MEASUREITEM:
1134 MEASUREITEMSTRUCT32 *mis32 = (MEASUREITEMSTRUCT32 *)*plparam;
1135 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1136 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1137 if (!mis) return -1;
1138 mis->CtlType = (UINT16)mis32->CtlType;
1139 mis->CtlID = (UINT16)mis32->CtlID;
1140 mis->itemID = (UINT16)mis32->itemID;
1141 mis->itemWidth = (UINT16)mis32->itemWidth;
1142 mis->itemHeight = (UINT16)mis32->itemHeight;
1143 mis->itemData = mis32->itemData;
1144 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1145 *plparam = (LPARAM)SEGPTR_GET(mis);
1147 return 1;
1148 case WM_GETMINMAXINFO:
1150 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1151 sizeof(LPARAM) );
1152 if (!mmi) return -1;
1153 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)*plparam, mmi );
1154 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1155 *plparam = (LPARAM)SEGPTR_GET(mmi);
1157 return 1;
1158 case WM_GETTEXT:
1160 LPSTR str;
1161 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1162 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1163 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1164 *plparam = (LPARAM)SEGPTR_GET(str);
1166 return 1;
1167 case WM_MDICREATE:
1169 MDICREATESTRUCT16 *cs;
1170 MDICREATESTRUCT32A *cs32 = (MDICREATESTRUCT32A *)*plparam;
1171 LPSTR name, cls;
1173 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1174 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1175 name = SEGPTR_STRDUP( cs32->szTitle );
1176 cls = SEGPTR_STRDUP( cs32->szClass );
1177 cs->szTitle = SEGPTR_GET(name);
1178 cs->szClass = SEGPTR_GET(cls);
1179 *plparam = (LPARAM)SEGPTR_GET(cs);
1181 return 1;
1182 case WM_MDISETMENU:
1183 *pwparam16 = TRUE; /* FIXME? */
1184 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1185 (HMENU16)LOWORD(*plparam) );
1186 return 0;
1187 case WM_MENUCHAR:
1188 case WM_MENUSELECT:
1189 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1190 return 0;
1191 case WM_NCCALCSIZE:
1193 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
1194 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1195 if (!nc) return -1;
1197 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1198 if (wParam32)
1200 WINDOWPOS16 *wp;
1201 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1202 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1203 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1205 SEGPTR_FREE(nc);
1206 return -1;
1208 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1209 nc->lppos = SEGPTR_GET(wp);
1211 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1212 *plparam = (LPARAM)SEGPTR_GET(nc);
1214 return 1;
1215 case WM_NCCREATE:
1216 case WM_CREATE:
1218 CREATESTRUCT16 *cs;
1219 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)*plparam;
1220 LPSTR name, cls;
1222 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1223 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1224 name = SEGPTR_STRDUP( cs32->lpszName );
1225 cls = SEGPTR_STRDUP( cs32->lpszClass );
1226 cs->lpszName = SEGPTR_GET(name);
1227 cs->lpszClass = SEGPTR_GET(cls);
1228 *plparam = (LPARAM)SEGPTR_GET(cs);
1230 return 1;
1231 case WM_PARENTNOTIFY:
1232 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1233 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1234 /* else nothing to do */
1235 return 0;
1236 case WM_SETTEXT:
1238 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1239 if (!str) return -1;
1240 *plparam = (LPARAM)SEGPTR_GET(str);
1242 return 1;
1243 case WM_WINDOWPOSCHANGING:
1244 case WM_WINDOWPOSCHANGED:
1246 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1247 sizeof(LPARAM) );
1248 if (!wp) return -1;
1249 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)*plparam, wp );
1250 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1251 *plparam = (LPARAM)SEGPTR_GET(wp);
1253 return 1;
1254 case WM_ASKCBFORMATNAME:
1255 case WM_DEVMODECHANGE:
1256 case WM_MDIACTIVATE:
1257 case WM_PAINTCLIPBOARD:
1258 case WM_SIZECLIPBOARD:
1259 case WM_WININICHANGE:
1260 fprintf( stderr, "MapMsg32ATo16: message %04x needs translation\n",
1261 msg32 );
1262 return -1;
1264 default: /* No translation needed */
1265 return 0;
1270 /**********************************************************************
1271 * WINPROC_UnmapMsg32ATo16
1273 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1275 void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM16 wParam, LPARAM lParam )
1277 switch(msg)
1279 case LB_ADDFILE32:
1280 case LB_ADDSTRING32:
1281 case LB_DIR32:
1282 case LB_FINDSTRING32:
1283 case LB_FINDSTRINGEXACT32:
1284 case LB_INSERTSTRING32:
1285 case LB_SELECTSTRING32:
1286 case LB_SETTABSTOPS32:
1287 case WM_COMPAREITEM:
1288 case WM_DELETEITEM:
1289 case WM_DRAWITEM:
1290 case WM_SETTEXT:
1291 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
1292 break;
1293 case LB_GETITEMRECT32:
1295 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(lParam);
1296 lParam = *(LPARAM *)(rect + 1);
1297 CONV_RECT16TO32( rect, (RECT32 *)lParam );
1298 SEGPTR_FREE( rect );
1300 break;
1301 case LB_GETSELITEMS32:
1303 INT32 i;
1304 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1305 lParam = *((LPARAM *)items - 1);
1306 for (i = 0; i < wParam; i++) *((LPINT32)lParam + i) = items[i];
1307 SEGPTR_FREE( (LPARAM *)items - 1 );
1309 break;
1310 case WM_MEASUREITEM:
1312 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
1313 MEASUREITEMSTRUCT32 *mis32 = *(MEASUREITEMSTRUCT32 **)(mis + 1);
1314 mis32->itemWidth = mis->itemWidth;
1315 mis32->itemHeight = mis->itemHeight;
1316 SEGPTR_FREE(mis);
1318 break;
1319 case WM_GETMINMAXINFO:
1321 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam);
1322 lParam = *(LPARAM *)(mmi + 1);
1323 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)lParam );
1324 SEGPTR_FREE(mmi);
1326 break;
1327 case WM_GETTEXT:
1329 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(lParam);
1330 lParam = *((LPARAM *)str - 1);
1331 lstrcpyn32A( (LPSTR)lParam, str, wParam );
1332 SEGPTR_FREE( (LPARAM *)str - 1 );
1334 break;
1335 case WM_MDICREATE:
1337 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(lParam);
1338 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1339 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1340 SEGPTR_FREE( cs );
1342 break;
1343 case WM_NCCALCSIZE:
1345 NCCALCSIZE_PARAMS32 *nc32;
1346 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
1347 lParam = *(LPARAM *)(nc + 1);
1348 nc32 = (NCCALCSIZE_PARAMS32 *)lParam;
1349 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1350 if (wParam)
1352 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1353 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1354 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1355 nc32->lppos );
1356 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1358 SEGPTR_FREE(nc);
1360 break;
1361 case WM_NCCREATE:
1362 case WM_CREATE:
1364 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
1365 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1366 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1367 SEGPTR_FREE( cs );
1369 break;
1370 case WM_WINDOWPOSCHANGING:
1371 case WM_WINDOWPOSCHANGED:
1373 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam);
1374 lParam = *(LPARAM *)(wp + 1);
1375 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)lParam );
1376 SEGPTR_FREE(wp);
1378 break;
1383 /**********************************************************************
1384 * WINPROC_MapMsg32WTo16
1386 * Map a message from 32-bit Unicode to 16-bit.
1387 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1389 INT32 WINPROC_MapMsg32WTo16( UINT32 msg32, WPARAM32 wParam32, UINT16 *pmsg16,
1390 WPARAM16 *pwparam16, LPARAM *plparam )
1392 switch(msg32)
1394 case LB_ADDSTRING32:
1395 case LB_FINDSTRING32:
1396 case LB_FINDSTRINGEXACT32:
1397 case LB_INSERTSTRING32:
1398 case LB_SELECTSTRING32:
1399 case LB_DIR32:
1400 case LB_ADDFILE32:
1402 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1403 if (!str) return -1;
1404 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1405 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1406 *plparam = (LPARAM)SEGPTR_GET(str);
1408 return 1;
1409 case WM_NCCREATE:
1410 case WM_CREATE:
1412 CREATESTRUCT16 *cs;
1413 CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
1414 LPSTR name, cls;
1416 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1417 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
1418 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
1419 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
1420 cs->lpszName = SEGPTR_GET(name);
1421 cs->lpszClass = SEGPTR_GET(cls);
1422 *pmsg16 = (UINT16)msg32;
1423 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1424 *plparam = (LPARAM)SEGPTR_GET(cs);
1426 return 1;
1427 case WM_MDICREATE:
1429 MDICREATESTRUCT16 *cs;
1430 MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
1431 LPSTR name, cls;
1433 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1434 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
1435 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
1436 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
1437 cs->szTitle = SEGPTR_GET(name);
1438 cs->szClass = SEGPTR_GET(cls);
1439 *pmsg16 = (UINT16)msg32;
1440 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1441 *plparam = (LPARAM)SEGPTR_GET(cs);
1443 return 1;
1444 case WM_SETTEXT:
1446 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1447 if (!str) return -1;
1448 *pmsg16 = (UINT16)msg32;
1449 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1450 *plparam = (LPARAM)SEGPTR_GET(str);
1452 return 1;
1453 default: /* No Unicode translation needed */
1454 return WINPROC_MapMsg32ATo16( msg32, wParam32, pmsg16,
1455 pwparam16, plparam );
1460 /**********************************************************************
1461 * WINPROC_UnmapMsg32WTo16
1463 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1465 void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM16 wParam, LPARAM lParam )
1467 switch(msg)
1469 case WM_GETTEXT:
1471 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(lParam);
1472 lParam = *((LPARAM *)str - 1);
1473 lstrcpyAtoW( (LPWSTR)lParam, str );
1474 SEGPTR_FREE( (LPARAM *)str - 1 );
1476 break;
1477 default:
1478 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam );
1479 break;
1484 /**********************************************************************
1485 * WINPROC_CallProc32ATo32W
1487 * Call a window procedure, translating args from Ansi to Unicode.
1489 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
1490 UINT32 msg, WPARAM32 wParam,
1491 LPARAM lParam )
1493 LRESULT result;
1495 if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
1496 result = CallWndProc32( func, hwnd, msg, wParam, lParam );
1497 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1498 return result;
1502 /**********************************************************************
1503 * WINPROC_CallProc32WTo32A
1505 * Call a window procedure, translating args from Unicode to Ansi.
1507 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
1508 UINT32 msg, WPARAM32 wParam,
1509 LPARAM lParam )
1511 LRESULT result;
1513 if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
1514 result = CallWndProc32( func, hwnd, msg, wParam, lParam );
1515 WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
1516 return result;
1520 /**********************************************************************
1521 * WINPROC_CallProc16To32A
1523 * Call a 32-bit window procedure, translating the 16-bit args.
1525 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
1526 WPARAM16 wParam, LPARAM lParam,
1527 WNDPROC32 func )
1529 LRESULT result;
1530 UINT32 msg32;
1531 WPARAM32 wParam32;
1533 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1534 return 0;
1535 result = CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1536 WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam );
1537 return result;
1541 /**********************************************************************
1542 * WINPROC_CallProc16To32W
1544 * Call a 32-bit window procedure, translating the 16-bit args.
1546 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
1547 WPARAM16 wParam, LPARAM lParam,
1548 WNDPROC32 func )
1550 LRESULT result;
1551 UINT32 msg32;
1552 WPARAM32 wParam32;
1554 if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1555 return 0;
1556 result = CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1557 WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam );
1558 return result;
1562 /**********************************************************************
1563 * WINPROC_CallProc32ATo16
1565 * Call a 16-bit window procedure, translating the 32-bit args.
1567 static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
1568 UINT32 msg, WPARAM32 wParam,
1569 LPARAM lParam )
1571 LRESULT result;
1572 UINT16 msg16;
1573 WPARAM16 wParam16;
1574 WND *wndPtr = WIN_FindWndPtr( hwnd );
1575 WORD ds = CURRENT_DS;
1577 if (WINPROC_MapMsg32ATo16( msg, wParam, &msg16, &wParam16, &lParam ) == -1)
1578 return 0;
1579 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1580 result = CallWndProc16( func, hwnd, msg16, wParam16, lParam );
1581 CURRENT_DS = ds;
1582 WINPROC_UnmapMsg32ATo16( msg, wParam16, lParam );
1583 return result;
1587 /**********************************************************************
1588 * WINPROC_CallProc32WTo16
1590 * Call a 16-bit window procedure, translating the 32-bit args.
1592 static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
1593 UINT32 msg, WPARAM32 wParam,
1594 LPARAM lParam )
1596 LRESULT result;
1597 UINT16 msg16;
1598 WPARAM16 wParam16;
1599 WND *wndPtr = WIN_FindWndPtr( hwnd );
1600 WORD ds = CURRENT_DS;
1602 if (WINPROC_MapMsg32WTo16( msg, wParam, &msg16, &wParam16, &lParam ) == -1)
1603 return 0;
1604 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1605 result = CallWndProc16( func, hwnd, msg16, wParam16, lParam );
1606 CURRENT_DS = ds;
1607 WINPROC_UnmapMsg32WTo16( msg, wParam16, lParam );
1608 return result;
1612 /**********************************************************************
1613 * CallWindowProc16 (USER.122)
1615 LRESULT CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
1616 WPARAM16 wParam, LPARAM lParam )
1618 LRESULT result;
1619 WND *wndPtr;
1620 WINDOWPROC *proc = WINPROC_GetPtr( func );
1621 WORD ds = CURRENT_DS;
1623 if (!proc)
1625 wndPtr = WIN_FindWndPtr( hwnd );
1626 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1627 result = CallWndProc16( (FARPROC16)func, hwnd, msg, wParam, lParam );
1628 CURRENT_DS = ds;
1629 return result;
1631 #if testing
1632 wndPtr = WIN_FindWndPtr( hwnd );
1633 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1634 result = CallWndProc16( WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16),
1635 hwnd, msg, wParam, lParam );
1636 CURRENT_DS = ds;
1637 return result;
1638 #endif
1640 switch(proc->type)
1642 case WIN_PROC_16:
1643 if (!proc->thunk.t_from32.proc) return 0;
1644 wndPtr = WIN_FindWndPtr( hwnd );
1645 if (wndPtr) CURRENT_DS = wndPtr->hInstance;
1646 #ifndef WINELIB
1647 if ((msg == WM_CREATE) || (msg == WM_NCCREATE))
1649 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
1650 /* Build the CREATESTRUCT on the 16-bit stack. */
1651 /* This is really ugly, but some programs (notably the */
1652 /* "Undocumented Windows" examples) want it that way. */
1653 result = CallWndProcNCCREATE16( proc->thunk.t_from32.proc,
1654 cs->dwExStyle, cs->lpszClass, cs->lpszName, cs->style,
1655 cs->x, cs->y, cs->cx, cs->cy, cs->hwndParent, cs->hMenu,
1656 cs->hInstance, (LONG)cs->lpCreateParams, hwnd, msg, wParam,
1657 MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
1658 IF1632_Saved16_ss ) );
1659 CURRENT_DS = ds;
1660 return result;
1662 #endif
1663 result = CallWndProc16( proc->thunk.t_from32.proc,
1664 hwnd, msg, wParam, lParam );
1665 CURRENT_DS = ds;
1666 return result;
1668 case WIN_PROC_32A:
1669 if (!proc->thunk.t_from16.proc) return 0;
1670 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
1671 proc->thunk.t_from16.proc );
1672 case WIN_PROC_32W:
1673 if (!proc->thunk.t_from16.proc) return 0;
1674 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
1675 proc->thunk.t_from16.proc );
1676 default:
1677 fprintf( stderr, "CallWindowProc16: invalid proc %p\n", proc );
1678 return 0;
1683 /**********************************************************************
1684 * CallWindowProc32A (USER32.17)
1686 LRESULT CallWindowProc32A( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1687 WPARAM32 wParam, LPARAM lParam )
1689 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1691 if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam );
1693 #if testing
1694 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
1695 return CallWndProc32( func, hwnd, msg, wParam, lParam );
1696 #endif
1698 switch(proc->type)
1700 case WIN_PROC_16:
1701 if (!proc->thunk.t_from32.proc) return 0;
1702 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
1703 hwnd, msg, wParam, lParam );
1704 case WIN_PROC_32A:
1705 if (!proc->thunk.t_from16.proc) return 0;
1706 return CallWndProc32( proc->thunk.t_from16.proc,
1707 hwnd, msg, wParam, lParam );
1708 case WIN_PROC_32W:
1709 if (!proc->thunk.t_from16.proc) return 0;
1710 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
1711 hwnd, msg, wParam, lParam );
1712 default:
1713 fprintf( stderr, "CallWindowProc32A: invalid proc %p\n", proc );
1714 return 0;
1719 /**********************************************************************
1720 * CallWindowProc32W (USER32.18)
1722 LRESULT CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1723 WPARAM32 wParam, LPARAM lParam )
1725 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1727 if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam );
1729 #if testing
1730 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
1731 return CallWndProc32( func, hwnd, msg, wParam, lParam );
1732 #endif
1734 switch(proc->type)
1736 case WIN_PROC_16:
1737 if (!proc->thunk.t_from32.proc) return 0;
1738 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
1739 hwnd, msg, wParam, lParam );
1740 case WIN_PROC_32A:
1741 if (!proc->thunk.t_from16.proc) return 0;
1742 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
1743 hwnd, msg, wParam, lParam );
1744 case WIN_PROC_32W:
1745 if (!proc->thunk.t_from16.proc) return 0;
1746 return CallWndProc32( proc->thunk.t_from16.proc,
1747 hwnd, msg, wParam, lParam );
1748 default:
1749 fprintf( stderr, "CallWindowProc32W: invalid proc %p\n", proc );
1750 return 0;