2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
11 #include "selectors.h"
19 /* Window procedure 16-to-32-bit thunk,
20 * see BuildSpec16Files() in tools/build.c */
24 BYTE popl_eax; /* popl %eax (return address) */
25 BYTE pushl_func; /* pushl $proc */
26 WNDPROC32 proc WINE_PACKED;
27 BYTE pushl_eax; /* pushl %eax */
28 WORD pushw_bp WINE_PACKED; /* pushw %bp */
29 BYTE pushl_thunk; /* pushl $thunkfrom16 */
30 void (*thunk32)() WINE_PACKED;
31 BYTE lcall; /* lcall cs:relay */
32 void (*relay)() WINE_PACKED; /* WINPROC_CallProc16To32A/W() */
34 } WINPROC_THUNK_FROM16;
36 /* Window procedure 32-to-16-bit thunk,
37 * see BuildSpec32Files() in tools/build.c */
41 BYTE popl_eax; /* popl %eax (return address) */
42 BYTE pushl_func; /* pushl $proc */
43 WNDPROC16 proc WINE_PACKED;
44 BYTE pushl_eax; /* pushl %eax */
45 BYTE jmp; /* jmp relay (relative jump)*/
46 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
47 } WINPROC_THUNK_FROM32;
49 /* Simple jmp to call 32-bit procedure directly */
52 BYTE jmp; /* jmp proc (relative jump) */
53 WNDPROC32 proc WINE_PACKED;
58 WINPROC_THUNK_FROM16 t_from16;
59 WINPROC_THUNK_FROM32 t_from32;
62 typedef struct tagWINDOWPROC
64 WINPROC_THUNK thunk; /* Thunk */
65 WINPROC_JUMP jmp; /* Jump */
66 struct tagWINDOWPROC *next; /* Next window proc */
67 UINT32 magic; /* Magic number */
68 WINDOWPROCTYPE type; /* Function type */
69 WINDOWPROCUSER user; /* Function user */
72 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
74 #define WINPROC_THUNKPROC(pproc) \
75 (((pproc)->type == WIN_PROC_16) ? \
76 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
77 (WNDPROC16)((pproc)->thunk.t_from16.proc))
79 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
80 UINT32 msg, WPARAM32 wParam,
82 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
83 UINT32 msg, WPARAM32 wParam,
85 static LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
86 WPARAM16 wParam, LPARAM lParam,
88 static LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
89 WPARAM16 wParam, LPARAM lParam,
92 static HANDLE32 WinProcHeap;
95 /**********************************************************************
98 BOOL32 WINPROC_Init(void)
100 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
103 WARN(relay, "Unable to create winproc heap\n" );
110 /**********************************************************************
111 * WINPROC_CallWndProc32
113 * Call a 32-bit WndProc.
115 static LRESULT WINPROC_CallWndProc32( WNDPROC32 proc, HWND32 hwnd, UINT32 msg,
116 WPARAM32 wParam, LPARAM lParam )
118 TRACE(relay, "(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
119 proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
120 return proc( hwnd, msg, wParam, lParam );
124 /**********************************************************************
127 * Return a pointer to the win proc.
129 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
134 /* Check for a linear pointer */
136 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
138 ptr = (BYTE *)handle;
139 /* First check if it is the jmp address */
140 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
141 (int)&((WINDOWPROC *)0)->thunk;
142 /* Now it must be the thunk address */
143 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
144 /* Now we have a pointer to the WINDOWPROC struct */
145 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
146 return (WINDOWPROC *)ptr;
149 /* Check for a segmented pointer */
151 if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
153 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
154 if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
155 /* It must be the thunk address */
156 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
157 /* Now we have a pointer to the WINDOWPROC struct */
158 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
159 return (WINDOWPROC *)ptr;
166 /**********************************************************************
167 * WINPROC_AllocWinProc
169 * Allocate a new window procedure.
171 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
172 WINDOWPROCUSER user )
174 WINDOWPROC *proc, *oldproc;
176 /* Allocate a window procedure */
178 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
180 /* Check if the function is already a win proc */
182 if ((oldproc = WINPROC_GetPtr( func )))
191 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
192 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
193 proc->thunk.t_from32.proc = func;
194 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
195 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
196 proc->thunk.t_from32.relay = /* relative jump */
197 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
198 (DWORD)(&proc->thunk.t_from32.relay + 1));
202 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
203 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
204 proc->thunk.t_from16.proc = (FARPROC32)func;
205 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
206 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
207 proc->thunk.t_from16.pushl_thunk = 0x68; /* pushl $thunkfrom16 */
208 proc->thunk.t_from16.thunk32 = (type == WIN_PROC_32A) ?
209 (void(*)())WINPROC_CallProc16To32A :
210 (void(*)())WINPROC_CallProc16To32W;
211 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:relay */
212 proc->thunk.t_from16.relay = Callbacks->CallFrom16WndProc;
213 GET_CS(proc->thunk.t_from16.cs);
214 proc->jmp.jmp = 0xe9;
215 /* Fixup relative jump */
216 proc->jmp.proc = (WNDPROC32)((DWORD)func -
217 (DWORD)(&proc->jmp.proc + 1));
220 /* Should not happen */
223 proc->magic = WINPROC_MAGIC;
228 TRACE(win, "(%08x,%d): returning %08x\n",
229 (UINT32)func, type, (UINT32)proc );
234 /**********************************************************************
237 * Get a window procedure pointer that can be passed to the Windows program.
239 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
241 if (!proc) return NULL;
242 if (type == WIN_PROC_16) /* We want a 16:16 address */
244 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
245 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
247 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
248 &((WINDOWPROC *)proc)->thunk );
250 else /* We want a 32-bit address */
252 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
253 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
254 else if (type != ((WINDOWPROC *)proc)->type)
255 /* Have to return the jmp address if types don't match */
256 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
258 /* Some Win16 programs want to get back the proc they set */
259 return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc;
264 /**********************************************************************
267 * Set the window procedure for a window or class. There are
268 * three tree classes of winproc callbacks:
270 * 1) class -> wp - not subclassed
271 * class -> wp -> wp -> wp -> wp - SetClassLong()
273 * 2) window -' / - not subclassed
274 * window -> wp -> wp ' - SetWindowLong()
276 * 3) timer -> wp - SetTimer()
278 * Initially, winproc of the window points to the current winproc
279 * thunk of its class. Subclassing prepends a new thunk to the
280 * window winproc chain at the head of the list. Thus, window thunk
281 * list includes class thunks and the latter are preserved when the
282 * window is destroyed.
285 BOOL32 WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
286 WINDOWPROCTYPE type, WINDOWPROCUSER user )
288 BOOL32 bRecycle = FALSE;
289 WINDOWPROC *proc, **ppPrev;
291 /* Check if function is already in the list */
293 ppPrev = (WINDOWPROC **)pFirst;
294 proc = WINPROC_GetPtr( func );
301 if ((*ppPrev)->user != user)
303 /* terminal thunk is being restored */
305 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
306 *(WINDOWPROC **)pFirst = *ppPrev;
315 if (((*ppPrev)->type == type) &&
316 (func == WINPROC_THUNKPROC(*ppPrev)))
323 /* WPF_CLASS thunk terminates window thunk list */
324 if ((*ppPrev)->user != user) break;
325 ppPrev = &(*ppPrev)->next;
330 /* Extract this thunk from the list */
332 *ppPrev = proc->next;
334 else /* Allocate a new one */
336 if (proc) /* Was already a win proc */
339 func = WINPROC_THUNKPROC(proc);
341 proc = WINPROC_AllocWinProc( func, type, user );
342 if (!proc) return FALSE;
345 /* Add the win proc at the head of the list */
347 TRACE(win, "(%08x,%08x,%d): res=%08x\n",
348 (UINT32)*pFirst, (UINT32)func, type, (UINT32)proc );
349 proc->next = *(WINDOWPROC **)pFirst;
350 *(WINDOWPROC **)pFirst = proc;
355 /**********************************************************************
358 * Free a list of win procs.
360 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
364 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
365 if (((WINDOWPROC *)proc)->user != user) break;
366 TRACE(win, "freeing %08x\n", (UINT32)proc);
367 HeapFree( WinProcHeap, 0, proc );
373 /**********************************************************************
374 * WINPROC_GetProcType
376 * Return the window procedure type.
378 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
381 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
382 return WIN_PROC_INVALID;
383 return ((WINDOWPROC *)proc)->type;
387 /**********************************************************************
388 * WINPROC_MapMsg32ATo32W
390 * Map a message from Ansi to Unicode.
391 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
392 * fixme WM_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR,
395 INT32 WINPROC_MapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
401 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
402 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
404 *ptr++ = *plparam; /* Store previous lParam */
405 *plparam = (LPARAM)ptr;
410 /* fixme: fixed sized buffer */
412 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
413 256 * sizeof(WCHAR) + sizeof(LPARAM) );
415 *ptr++ = *plparam; /* Store previous lParam */
416 *plparam = (LPARAM)ptr;
422 case CB_FINDSTRING32:
423 case CB_FINDSTRINGEXACT32:
424 case CB_INSERTSTRING32:
425 case CB_SELECTSTRING32:
427 case LB_INSERTSTRING32:
428 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
429 return (*plparam ? 1 : -1);
433 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
436 *cs = *(CREATESTRUCT32W *)*plparam;
437 if (HIWORD(cs->lpszName))
438 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
439 (LPCSTR)cs->lpszName );
440 if (HIWORD(cs->lpszClass))
441 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
442 (LPCSTR)cs->lpszClass );
443 *plparam = (LPARAM)cs;
448 MDICREATESTRUCT32W *cs =
449 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
451 *cs = *(MDICREATESTRUCT32W *)*plparam;
452 if (HIWORD(cs->szClass))
453 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
454 (LPCSTR)cs->szClass );
455 if (HIWORD(cs->szTitle))
456 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
457 (LPCSTR)cs->szTitle );
458 *plparam = (LPARAM)cs;
461 case WM_ASKCBFORMATNAME:
462 case WM_DEVMODECHANGE:
463 case WM_PAINTCLIPBOARD:
464 case WM_SIZECLIPBOARD:
465 case WM_WININICHANGE:
467 case EM_REPLACESEL32:
468 case EM_SETPASSWORDCHAR32:
471 case LB_FINDSTRING32:
472 case LB_SELECTSTRING32:
473 FIXME(msg, "message %s (0x%x) needs translation\n", SPY_GetMsgName(msg), msg );
475 default: /* No translation needed */
481 /**********************************************************************
482 * WINPROC_UnmapMsg32ATo32W
484 * Unmap a message that was mapped from Ansi to Unicode.
486 void WINPROC_UnmapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
492 LPARAM *ptr = (LPARAM *)lParam - 1;
493 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)(ptr + 1), wParam );
494 HeapFree( SystemHeap, 0, ptr );
500 LPARAM *ptr = (LPARAM *)lParam - 1;
501 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(ptr + 1) );
502 HeapFree( SystemHeap, 0, ptr );
507 case LB_INSERTSTRING32:
510 case CB_FINDSTRING32:
511 case CB_FINDSTRINGEXACT32:
512 case CB_INSERTSTRING32:
513 case CB_SELECTSTRING32:
515 HeapFree( SystemHeap, 0, (void *)lParam );
520 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
521 if (HIWORD(cs->lpszName))
522 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
523 if (HIWORD(cs->lpszClass))
524 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
525 HeapFree( SystemHeap, 0, cs );
530 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
531 if (HIWORD(cs->szTitle))
532 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
533 if (HIWORD(cs->szClass))
534 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
535 HeapFree( SystemHeap, 0, cs );
542 /**********************************************************************
543 * WINPROC_MapMsg32WTo32A
545 * Map a message from Unicode to Ansi.
546 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
548 INT32 WINPROC_MapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
554 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
555 wParam + sizeof(LPARAM) );
557 *ptr++ = *plparam; /* Store previous lParam */
558 *plparam = (LPARAM)ptr;
564 /* fixme: fixed sized buffer */
566 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
567 256 + sizeof(LPARAM) );
569 *ptr++ = *plparam; /* Store previous lParam */
570 *plparam = (LPARAM)ptr;
575 case LB_INSERTSTRING32:
578 case CB_FINDSTRING32:
579 case CB_FINDSTRINGEXACT32:
580 case CB_INSERTSTRING32:
581 case CB_SELECTSTRING32:
583 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
584 return (*plparam ? 1 : -1);
588 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
591 *cs = *(CREATESTRUCT32A *)*plparam;
592 if (HIWORD(cs->lpszName))
593 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
594 (LPCWSTR)cs->lpszName );
595 if (HIWORD(cs->lpszClass))
596 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
597 (LPCWSTR)cs->lpszClass);
598 *plparam = (LPARAM)cs;
603 MDICREATESTRUCT32A *cs =
604 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
606 *cs = *(MDICREATESTRUCT32A *)*plparam;
607 if (HIWORD(cs->szTitle))
608 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
609 (LPCWSTR)cs->szTitle );
610 if (HIWORD(cs->szClass))
611 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
612 (LPCWSTR)cs->szClass );
613 *plparam = (LPARAM)cs;
616 case WM_ASKCBFORMATNAME:
617 case WM_DEVMODECHANGE:
618 case WM_PAINTCLIPBOARD:
619 case WM_SIZECLIPBOARD:
620 case WM_WININICHANGE:
622 case EM_REPLACESEL32:
623 case EM_SETPASSWORDCHAR32:
626 case LB_FINDSTRING32:
627 case LB_SELECTSTRING32:
628 FIXME(msg, "message %04x needs translation\n",msg );
630 default: /* No translation needed */
636 /**********************************************************************
637 * WINPROC_UnmapMsg32WTo32A
639 * Unmap a message that was mapped from Unicode to Ansi.
641 void WINPROC_UnmapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
647 LPARAM *ptr = (LPARAM *)lParam - 1;
648 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)(ptr + 1), wParam );
649 HeapFree( SystemHeap, 0, ptr );
655 LPARAM *ptr = (LPARAM *)lParam - 1;
656 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(ptr + 1) );
657 HeapFree( SystemHeap, 0, ptr );
661 case LB_INSERTSTRING32:
664 case CB_FINDSTRING32:
665 case CB_FINDSTRINGEXACT32:
666 case CB_INSERTSTRING32:
667 case CB_SELECTSTRING32:
669 HeapFree( SystemHeap, 0, (void *)lParam );
674 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
675 if (HIWORD(cs->lpszName))
676 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
677 if (HIWORD(cs->lpszClass))
678 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
679 HeapFree( SystemHeap, 0, cs );
684 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
685 if (HIWORD(cs->szTitle))
686 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
687 if (HIWORD(cs->szClass))
688 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
689 HeapFree( SystemHeap, 0, cs );
696 /**********************************************************************
697 * WINPROC_MapMsg16To32A
699 * Map a message from 16- to 32-bit Ansi.
700 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
702 INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
703 WPARAM32 *pwparam32, LPARAM *plparam )
705 *pmsg32 = (UINT32)msg16;
706 *pwparam32 = (WPARAM32)wParam16;
713 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
714 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
718 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
719 *plparam = (LPARAM)(HWND32)HIWORD(*plparam);
722 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
723 *pwparam32 = (WPARAM32)(HDC32)wParam16;
724 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
728 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
729 COMPAREITEMSTRUCT32 *cis = (COMPAREITEMSTRUCT32 *)
730 HeapAlloc(SystemHeap, 0, sizeof(*cis));
732 cis->CtlType = cis16->CtlType;
733 cis->CtlID = cis16->CtlID;
734 cis->hwndItem = cis16->hwndItem;
735 cis->itemID1 = cis16->itemID1;
736 cis->itemData1 = cis16->itemData1;
737 cis->itemID2 = cis16->itemID2;
738 cis->itemData2 = cis16->itemData2;
739 cis->dwLocaleId = 0; /* FIXME */
740 *plparam = (LPARAM)cis;
745 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
746 DELETEITEMSTRUCT32 *dis = (DELETEITEMSTRUCT32 *)
747 HeapAlloc(SystemHeap, 0, sizeof(*dis));
749 dis->CtlType = dis16->CtlType;
750 dis->CtlID = dis16->CtlID;
751 dis->hwndItem = dis16->hwndItem;
752 dis->itemData = dis16->itemData;
753 *plparam = (LPARAM)dis;
758 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
759 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)
760 HeapAlloc(SystemHeap, 0,
761 sizeof(*mis) + sizeof(LPARAM));
763 mis->CtlType = mis16->CtlType;
764 mis->CtlID = mis16->CtlID;
765 mis->itemID = mis16->itemID;
766 mis->itemWidth = mis16->itemWidth;
767 mis->itemHeight = mis16->itemHeight;
768 mis->itemData = mis16->itemData;
769 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
770 *plparam = (LPARAM)mis;
775 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
776 DRAWITEMSTRUCT32 *dis = (DRAWITEMSTRUCT32*)HeapAlloc(SystemHeap, 0,
779 dis->CtlType = dis16->CtlType;
780 dis->CtlID = dis16->CtlID;
781 dis->itemID = dis16->itemID;
782 dis->itemAction = dis16->itemAction;
783 dis->itemState = dis16->itemState;
784 dis->hwndItem = dis16->hwndItem;
785 dis->hDC = dis16->hDC;
786 dis->itemData = dis16->itemData;
787 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
788 *plparam = (LPARAM)dis;
791 case WM_GETMINMAXINFO:
793 MINMAXINFO32 *mmi = (MINMAXINFO32 *)HeapAlloc( SystemHeap, 0,
794 sizeof(*mmi) + sizeof(LPARAM));
796 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
798 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
799 *plparam = (LPARAM)mmi;
803 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
807 MDICREATESTRUCT16 *cs16 =
808 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
809 MDICREATESTRUCT32A *cs =
810 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
811 sizeof(*cs) + sizeof(LPARAM) );
813 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
814 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
815 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
816 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
817 *plparam = (LPARAM)cs;
820 case WM_MDIGETACTIVE:
821 *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL32) );
825 *pmsg32=WM_MDIREFRESHMENU;
826 *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
827 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
831 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
832 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
837 *pwparam32 = (WPARAM32)(HWND32)HIWORD(*plparam);
838 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
840 else /* message sent to MDI client */
841 *pwparam32 = wParam16;
845 NCCALCSIZE_PARAMS16 *nc16;
846 NCCALCSIZE_PARAMS32 *nc;
848 nc = (NCCALCSIZE_PARAMS32 *)HeapAlloc( SystemHeap, 0,
849 sizeof(*nc) + sizeof(LPARAM) );
851 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
852 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
855 nc->lppos = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
856 sizeof(*nc->lppos) );
857 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
858 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
859 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
861 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
862 *plparam = (LPARAM)nc;
868 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
869 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
870 sizeof(*cs) + sizeof(LPARAM) );
872 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
873 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
874 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
875 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
876 *plparam = (LPARAM)cs;
879 case WM_PARENTNOTIFY:
880 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
882 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
883 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
887 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
889 case WM_WINDOWPOSCHANGING:
890 case WM_WINDOWPOSCHANGED:
892 WINDOWPOS32 *wp = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
893 sizeof(*wp) + sizeof(LPARAM) );
895 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
897 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
898 *plparam = (LPARAM)wp;
902 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
904 case WM_ASKCBFORMATNAME:
905 case WM_DEVMODECHANGE:
906 case WM_PAINTCLIPBOARD:
907 case WM_SIZECLIPBOARD:
908 case WM_WININICHANGE:
909 FIXME( msg, "message %04x needs translation\n",msg16 );
912 default: /* No translation needed */
918 /**********************************************************************
919 * WINPROC_UnmapMsg16To32A
921 * Unmap a message that was mapped from 16- to 32-bit Ansi.
923 LRESULT WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
931 HeapFree( SystemHeap, 0, (LPVOID)lParam );
935 MEASUREITEMSTRUCT16 *mis16;
936 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)lParam;
937 lParam = *(LPARAM *)(mis + 1);
938 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
939 mis16->itemWidth = (UINT16)mis->itemWidth;
940 mis16->itemHeight = (UINT16)mis->itemHeight;
941 HeapFree( SystemHeap, 0, mis );
944 case WM_GETMINMAXINFO:
946 MINMAXINFO32 *mmi = (MINMAXINFO32 *)lParam;
947 lParam = *(LPARAM *)(mmi + 1);
948 STRUCT32_MINMAXINFO32to16( mmi,
949 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
950 HeapFree( SystemHeap, 0, mmi );
955 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
956 lParam = *(LPARAM *)(cs + 1);
957 STRUCT32_MDICREATESTRUCT32Ato16( cs,
958 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
959 HeapFree( SystemHeap, 0, cs );
962 case WM_MDIGETACTIVE:
963 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL32 *)lParam) );
964 HeapFree( SystemHeap, 0, (BOOL32 *)lParam );
968 NCCALCSIZE_PARAMS16 *nc16;
969 NCCALCSIZE_PARAMS32 *nc = (NCCALCSIZE_PARAMS32 *)lParam;
970 lParam = *(LPARAM *)(nc + 1);
971 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
972 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
975 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
976 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
979 STRUCT32_WINDOWPOS32to16( nc->lppos,
980 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
981 HeapFree( SystemHeap, 0, nc->lppos );
984 HeapFree( SystemHeap, 0, nc );
990 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
991 lParam = *(LPARAM *)(cs + 1);
992 STRUCT32_CREATESTRUCT32Ato16( cs,
993 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
994 HeapFree( SystemHeap, 0, cs );
997 case WM_WINDOWPOSCHANGING:
998 case WM_WINDOWPOSCHANGED:
1000 WINDOWPOS32 *wp = (WINDOWPOS32 *)lParam;
1001 lParam = *(LPARAM *)(wp + 1);
1002 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
1003 HeapFree( SystemHeap, 0, wp );
1011 /**********************************************************************
1012 * WINPROC_MapMsg16To32W
1014 * Map a message from 16- to 32-bit Unicode.
1015 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1017 INT32 WINPROC_MapMsg16To32W( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
1018 WPARAM32 *pwparam32, LPARAM *plparam )
1024 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1025 return WINPROC_MapMsg32ATo32W( *pmsg32, *pwparam32, plparam );
1029 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1030 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
1031 sizeof(*cs) + sizeof(LPARAM) );
1033 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCT32A *)cs );
1034 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1035 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1036 if (HIWORD(cs->lpszName))
1037 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
1038 (LPCSTR)cs->lpszName );
1039 if (HIWORD(cs->lpszClass))
1040 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
1041 (LPCSTR)cs->lpszClass );
1042 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1043 *plparam = (LPARAM)cs;
1048 MDICREATESTRUCT16 *cs16 =
1049 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1050 MDICREATESTRUCT32W *cs =
1051 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
1052 sizeof(*cs) + sizeof(LPARAM) );
1054 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCT32A *)cs );
1055 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1056 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
1057 if (HIWORD(cs->szTitle))
1058 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
1059 (LPCSTR)cs->szTitle );
1060 if (HIWORD(cs->szClass))
1061 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
1062 (LPCSTR)cs->szClass );
1063 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1064 *plparam = (LPARAM)cs;
1067 default: /* No Unicode translation needed */
1068 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1069 pwparam32, plparam );
1074 /**********************************************************************
1075 * WINPROC_UnmapMsg16To32W
1077 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1079 LRESULT WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1086 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1091 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
1092 lParam = *(LPARAM *)(cs + 1);
1093 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
1094 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1095 if (HIWORD(cs->lpszName))
1096 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1097 if (HIWORD(cs->lpszClass))
1098 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1099 HeapFree( SystemHeap, 0, cs );
1104 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
1105 lParam = *(LPARAM *)(cs + 1);
1106 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
1107 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1108 if (HIWORD(cs->szTitle))
1109 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1110 if (HIWORD(cs->szClass))
1111 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1112 HeapFree( SystemHeap, 0, cs );
1116 return WINPROC_UnmapMsg16To32A( msg, wParam, lParam, result );
1122 /**********************************************************************
1123 * WINPROC_MapMsg32ATo16
1125 * Map a message from 32-bit Ansi to 16-bit.
1126 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1128 INT32 WINPROC_MapMsg32ATo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1129 UINT16 *pmsg16, WPARAM16 *pwparam16,
1132 *pmsg16 = (UINT16)msg32;
1133 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1141 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK32);
1147 case EM_SETRECTNP32:
1149 case EM_LINESCROLL32:
1150 case EM_SCROLLCARET32:
1151 case EM_GETMODIFY32:
1152 case EM_SETMODIFY32:
1153 case EM_GETLINECOUNT32:
1154 case EM_LINEINDEX32:
1155 case EM_SETHANDLE32:
1156 case EM_GETHANDLE32:
1158 case EM_LINELENGTH32:
1159 case EM_REPLACESEL32:
1161 case EM_LIMITTEXT32:
1165 case EM_LINEFROMCHAR32:
1166 case EM_SETTABSTOPS32:
1167 case EM_SETPASSWORDCHAR32:
1168 case EM_EMPTYUNDOBUFFER32:
1169 case EM_GETFIRSTVISIBLELINE32:
1170 case EM_SETREADONLY32:
1171 case EM_SETWORDBREAKPROC32:
1172 case EM_GETWORDBREAKPROC32:
1173 case EM_GETPASSWORDCHAR32:
1174 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL32);
1179 case LB_DELETESTRING32:
1180 case LB_GETANCHORINDEX32:
1181 case LB_GETCARETINDEX32:
1183 case LB_GETCURSEL32:
1184 case LB_GETHORIZONTALEXTENT32:
1185 case LB_GETITEMDATA32:
1186 case LB_GETITEMHEIGHT32:
1188 case LB_GETSELCOUNT32:
1189 case LB_GETTEXTLEN32:
1190 case LB_GETTOPINDEX32:
1191 case LB_RESETCONTENT32:
1192 case LB_SELITEMRANGE32:
1193 case LB_SELITEMRANGEEX32:
1194 case LB_SETANCHORINDEX32:
1195 case LB_SETCARETINDEX32:
1196 case LB_SETCOLUMNWIDTH32:
1197 case LB_SETCURSEL32:
1198 case LB_SETHORIZONTALEXTENT32:
1199 case LB_SETITEMDATA32:
1200 case LB_SETITEMHEIGHT32:
1202 case LB_SETTOPINDEX32:
1203 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1205 case CB_DELETESTRING32:
1207 case CB_GETLBTEXTLEN32:
1208 case CB_LIMITTEXT32:
1209 case CB_RESETCONTENT32:
1210 case CB_SETEDITSEL32:
1211 case CB_GETCURSEL32:
1212 case CB_SETCURSEL32:
1213 case CB_SHOWDROPDOWN32:
1214 case CB_SETITEMDATA32:
1215 case CB_SETITEMHEIGHT32:
1216 case CB_GETITEMHEIGHT32:
1217 case CB_SETEXTENDEDUI32:
1218 case CB_GETEXTENDEDUI32:
1219 case CB_GETDROPPEDSTATE32:
1220 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1222 case CB_GETEDITSEL32:
1223 *pmsg16 = CB_GETEDITSEL16;
1226 case LB_ADDSTRING32:
1227 case LB_FINDSTRING32:
1228 case LB_FINDSTRINGEXACT32:
1229 case LB_INSERTSTRING32:
1230 case LB_SELECTSTRING32:
1234 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1235 if (!str) return -1;
1236 *plparam = (LPARAM)SEGPTR_GET(str);
1238 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1241 case CB_ADDSTRING32:
1242 case CB_FINDSTRING32:
1243 case CB_FINDSTRINGEXACT32:
1244 case CB_INSERTSTRING32:
1245 case CB_SELECTSTRING32:
1248 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1249 if (!str) return -1;
1250 *plparam = (LPARAM)SEGPTR_GET(str);
1252 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1255 case LB_GETITEMRECT32:
1258 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1259 if (!rect) return -1;
1260 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1261 *plparam = (LPARAM)SEGPTR_GET(rect);
1263 *pmsg16 = LB_GETITEMRECT16;
1265 case LB_GETSELITEMS32:
1268 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1269 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1270 + sizeof(LPARAM)))) return -1;
1271 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1272 *plparam = (LPARAM)SEGPTR_GET(items);
1274 *pmsg16 = LB_GETSELITEMS16;
1276 case LB_SETTABSTOPS32:
1281 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1282 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1283 + sizeof(LPARAM)))) return -1;
1284 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT32)*plparam+i);
1285 *plparam = (LPARAM)SEGPTR_GET(stops);
1288 *pmsg16 = LB_SETTABSTOPS16;
1291 case CB_GETDROPPEDCONTROLRECT32:
1294 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1295 if (!rect) return -1;
1296 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1297 *plparam = (LPARAM)SEGPTR_GET(rect);
1299 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1303 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1304 *pmsg16 = LB_GETTEXT16;
1307 case CB_GETLBTEXT32:
1308 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1309 *pmsg16 = CB_GETLBTEXT16;
1314 *plparam = MAKELONG( (INT16)(INT32)wParam32, (INT16)*plparam );
1315 *pmsg16 = EM_SETSEL16;
1322 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1326 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1328 case WM_CTLCOLORMSGBOX:
1329 case WM_CTLCOLOREDIT:
1330 case WM_CTLCOLORLISTBOX:
1331 case WM_CTLCOLORBTN:
1332 case WM_CTLCOLORDLG:
1333 case WM_CTLCOLORSCROLLBAR:
1334 case WM_CTLCOLORSTATIC:
1335 *pmsg16 = WM_CTLCOLOR;
1336 *plparam = MAKELPARAM( (HWND16)*plparam,
1337 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1339 case WM_COMPAREITEM:
1341 COMPAREITEMSTRUCT32 *cis32 = (COMPAREITEMSTRUCT32 *)*plparam;
1342 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1343 if (!cis) return -1;
1344 cis->CtlType = (UINT16)cis32->CtlType;
1345 cis->CtlID = (UINT16)cis32->CtlID;
1346 cis->hwndItem = (HWND16)cis32->hwndItem;
1347 cis->itemID1 = (UINT16)cis32->itemID1;
1348 cis->itemData1 = cis32->itemData1;
1349 cis->itemID2 = (UINT16)cis32->itemID2;
1350 cis->itemData2 = cis32->itemData2;
1351 *plparam = (LPARAM)SEGPTR_GET(cis);
1356 DELETEITEMSTRUCT32 *dis32 = (DELETEITEMSTRUCT32 *)*plparam;
1357 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1358 if (!dis) return -1;
1359 dis->CtlType = (UINT16)dis32->CtlType;
1360 dis->CtlID = (UINT16)dis32->CtlID;
1361 dis->itemID = (UINT16)dis32->itemID;
1362 dis->hwndItem = (HWND16)dis32->hwndItem;
1363 dis->itemData = dis32->itemData;
1364 *plparam = (LPARAM)SEGPTR_GET(dis);
1369 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)*plparam;
1370 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1371 if (!dis) return -1;
1372 dis->CtlType = (UINT16)dis32->CtlType;
1373 dis->CtlID = (UINT16)dis32->CtlID;
1374 dis->itemID = (UINT16)dis32->itemID;
1375 dis->itemAction = (UINT16)dis32->itemAction;
1376 dis->itemState = (UINT16)dis32->itemState;
1377 dis->hwndItem = (HWND16)dis32->hwndItem;
1378 dis->hDC = (HDC16)dis32->hDC;
1379 dis->itemData = dis32->itemData;
1380 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1381 *plparam = (LPARAM)SEGPTR_GET(dis);
1384 case WM_MEASUREITEM:
1386 MEASUREITEMSTRUCT32 *mis32 = (MEASUREITEMSTRUCT32 *)*plparam;
1387 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1388 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1389 if (!mis) return -1;
1390 mis->CtlType = (UINT16)mis32->CtlType;
1391 mis->CtlID = (UINT16)mis32->CtlID;
1392 mis->itemID = (UINT16)mis32->itemID;
1393 mis->itemWidth = (UINT16)mis32->itemWidth;
1394 mis->itemHeight = (UINT16)mis32->itemHeight;
1395 mis->itemData = mis32->itemData;
1396 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1397 *plparam = (LPARAM)SEGPTR_GET(mis);
1400 case WM_GETMINMAXINFO:
1402 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1404 if (!mmi) return -1;
1405 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)*plparam, mmi );
1406 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1407 *plparam = (LPARAM)SEGPTR_GET(mmi);
1413 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1414 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1415 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1416 *plparam = (LPARAM)SEGPTR_GET(str);
1421 MDICREATESTRUCT16 *cs;
1422 MDICREATESTRUCT32A *cs32 = (MDICREATESTRUCT32A *)*plparam;
1425 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1426 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1427 name = SEGPTR_STRDUP( cs32->szTitle );
1428 cls = SEGPTR_STRDUP( cs32->szClass );
1429 cs->szTitle = SEGPTR_GET(name);
1430 cs->szClass = SEGPTR_GET(cls);
1431 *plparam = (LPARAM)SEGPTR_GET(cs);
1434 case WM_MDIGETACTIVE:
1437 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1438 (HMENU16)LOWORD(*plparam) );
1439 *pwparam16 = (*plparam == 0);
1443 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1445 case WM_MDIACTIVATE:
1446 if( WIDGETS_IsControl32(WIN_FindWndPtr(hwnd), BIC32_MDICLIENT) )
1448 *pwparam16 = (HWND32)wParam32;
1453 *pwparam16 = ((HWND32)*plparam == hwnd);
1454 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1455 (HWND16)LOWORD(wParam32) );
1460 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
1461 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1464 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1468 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1469 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1470 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1475 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1476 nc->lppos = SEGPTR_GET(wp);
1478 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1479 *plparam = (LPARAM)SEGPTR_GET(nc);
1486 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)*plparam;
1489 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1490 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1491 name = SEGPTR_STRDUP( cs32->lpszName );
1492 cls = SEGPTR_STRDUP( cs32->lpszClass );
1493 cs->lpszName = SEGPTR_GET(name);
1494 cs->lpszClass = SEGPTR_GET(cls);
1495 *plparam = (LPARAM)SEGPTR_GET(cs);
1498 case WM_PARENTNOTIFY:
1499 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1500 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1501 /* else nothing to do */
1504 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
1508 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1509 if (!str) return -1;
1510 *plparam = (LPARAM)SEGPTR_GET(str);
1513 case WM_WINDOWPOSCHANGING:
1514 case WM_WINDOWPOSCHANGED:
1516 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1519 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)*plparam, wp );
1520 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1521 *plparam = (LPARAM)SEGPTR_GET(wp);
1524 case WM_ASKCBFORMATNAME:
1525 case WM_DEVMODECHANGE:
1526 case WM_PAINTCLIPBOARD:
1527 case WM_SIZECLIPBOARD:
1528 case WM_WININICHANGE:
1529 WARN( msg, "message %04x needs translation\n", msg32 );
1532 default: /* No translation needed */
1538 /**********************************************************************
1539 * WINPROC_UnmapMsg32ATo16
1541 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1543 void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1549 case LB_ADDSTRING32:
1551 case LB_FINDSTRING32:
1552 case LB_FINDSTRINGEXACT32:
1553 case LB_INSERTSTRING32:
1554 case LB_SELECTSTRING32:
1555 case LB_SETTABSTOPS32:
1556 case CB_ADDSTRING32:
1557 case CB_FINDSTRING32:
1558 case CB_FINDSTRINGEXACT32:
1559 case CB_INSERTSTRING32:
1560 case CB_SELECTSTRING32:
1562 case WM_COMPAREITEM:
1566 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1569 case CB_GETDROPPEDCONTROLRECT32:
1570 case LB_GETITEMRECT32:
1572 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1573 p16->lParam = *(LPARAM *)(rect + 1);
1574 CONV_RECT16TO32( rect, (RECT32 *)(p16->lParam));
1575 SEGPTR_FREE( rect );
1578 case LB_GETSELITEMS32:
1581 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1582 p16->lParam = *((LPARAM *)items - 1);
1583 for (i = 0; i < p16->wParam; i++) *((LPINT32)(p16->lParam) + i) = items[i];
1584 SEGPTR_FREE( (LPARAM *)items - 1 );
1588 case CB_GETEDITSEL32:
1590 *((LPUINT32)(wParam)) = LOWORD(p16->lResult);
1592 *((LPUINT32)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1596 case CB_GETLBTEXT32:
1597 UnMapLS( (SEGPTR)(p16->lParam) );
1600 case WM_MEASUREITEM:
1602 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1603 MEASUREITEMSTRUCT32 *mis32 = *(MEASUREITEMSTRUCT32 **)(mis + 1);
1604 mis32->itemWidth = mis->itemWidth;
1605 mis32->itemHeight = mis->itemHeight;
1609 case WM_GETMINMAXINFO:
1611 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1612 p16->lParam = *(LPARAM *)(mmi + 1);
1613 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)(p16->lParam) );
1619 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1620 p16->lParam = *((LPARAM *)str - 1);
1621 lstrcpyn32A( (LPSTR)(p16->lParam), str, p16->wParam );
1622 SEGPTR_FREE( (LPARAM *)str - 1 );
1627 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1628 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1629 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1633 case WM_MDIGETACTIVE:
1634 if (lParam) *(BOOL32 *)lParam = (BOOL16)HIWORD(p16->lResult);
1635 p16->lResult = (HWND32)LOWORD(p16->lResult);
1639 NCCALCSIZE_PARAMS32 *nc32;
1640 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
1641 p16->lParam = *(LPARAM *)(nc + 1);
1642 nc32 = (NCCALCSIZE_PARAMS32 *)(p16->lParam);
1643 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1646 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1647 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1648 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1650 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1658 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1659 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1660 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1664 case WM_WINDOWPOSCHANGING:
1665 case WM_WINDOWPOSCHANGED:
1667 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
1668 p16->lParam = *(LPARAM *)(wp + 1);
1669 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)p16->lParam );
1674 UnMapLS(p16->lParam);
1680 /**********************************************************************
1681 * WINPROC_MapMsg32WTo16
1683 * Map a message from 32-bit Unicode to 16-bit.
1684 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1686 INT32 WINPROC_MapMsg32WTo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1687 UINT16 *pmsg16, WPARAM16 *pwparam16,
1692 case LB_ADDSTRING32:
1693 case LB_FINDSTRING32:
1694 case LB_FINDSTRINGEXACT32:
1695 case LB_INSERTSTRING32:
1696 case LB_SELECTSTRING32:
1700 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1701 if (!str) return -1;
1702 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1703 *plparam = (LPARAM)SEGPTR_GET(str);
1705 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1708 case CB_ADDSTRING32:
1709 case CB_FINDSTRING32:
1710 case CB_FINDSTRINGEXACT32:
1711 case CB_INSERTSTRING32:
1712 case CB_SELECTSTRING32:
1715 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1716 if (!str) return -1;
1717 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1718 *plparam = (LPARAM)SEGPTR_GET(str);
1720 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING32);
1727 CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
1730 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1731 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
1732 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
1733 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
1734 cs->lpszName = SEGPTR_GET(name);
1735 cs->lpszClass = SEGPTR_GET(cls);
1736 *pmsg16 = (UINT16)msg32;
1737 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1738 *plparam = (LPARAM)SEGPTR_GET(cs);
1743 MDICREATESTRUCT16 *cs;
1744 MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
1747 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1748 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
1749 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
1750 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
1751 cs->szTitle = SEGPTR_GET(name);
1752 cs->szClass = SEGPTR_GET(cls);
1753 *pmsg16 = (UINT16)msg32;
1754 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1755 *plparam = (LPARAM)SEGPTR_GET(cs);
1760 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1761 if (!str) return -1;
1762 *pmsg16 = (UINT16)msg32;
1763 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1764 *plparam = (LPARAM)SEGPTR_GET(str);
1767 default: /* No Unicode translation needed */
1768 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
1769 pwparam16, plparam );
1774 /**********************************************************************
1775 * WINPROC_UnmapMsg32WTo16
1777 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1779 void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1786 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1787 p16->lParam = *((LPARAM *)str - 1);
1788 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
1789 SEGPTR_FREE( (LPARAM *)str - 1 );
1793 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, p16 );
1799 /**********************************************************************
1800 * WINPROC_CallProc32ATo32W
1802 * Call a window procedure, translating args from Ansi to Unicode.
1804 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
1805 UINT32 msg, WPARAM32 wParam,
1810 if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
1811 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1812 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1817 /**********************************************************************
1818 * WINPROC_CallProc32WTo32A
1820 * Call a window procedure, translating args from Unicode to Ansi.
1822 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
1823 UINT32 msg, WPARAM32 wParam,
1828 if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
1829 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1830 WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
1835 /**********************************************************************
1836 * WINPROC_CallProc16To32A
1838 * Call a 32-bit window procedure, translating the 16-bit args.
1840 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
1841 WPARAM16 wParam, LPARAM lParam,
1848 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1850 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1851 return WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam, result );
1855 /**********************************************************************
1856 * WINPROC_CallProc16To32W
1858 * Call a 32-bit window procedure, translating the 16-bit args.
1860 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
1861 WPARAM16 wParam, LPARAM lParam,
1868 if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1870 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1871 return WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam, result );
1875 /**********************************************************************
1876 * WINPROC_CallProc32ATo16
1878 * Call a 16-bit window procedure, translating the 32-bit args.
1880 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
1881 UINT32 msg, WPARAM32 wParam,
1887 mp16.lParam = lParam;
1888 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
1889 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
1891 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1892 mp16.wParam, mp16.lParam );
1893 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, &mp16 );
1894 return mp16.lResult;
1898 /**********************************************************************
1899 * WINPROC_CallProc32WTo16
1901 * Call a 16-bit window procedure, translating the 32-bit args.
1903 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
1904 UINT32 msg, WPARAM32 wParam,
1910 mp16.lParam = lParam;
1911 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
1912 &mp16.lParam ) == -1)
1914 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1915 mp16.wParam, mp16.lParam );
1916 WINPROC_UnmapMsg32WTo16( msg, wParam, lParam, &mp16 );
1917 return mp16.lResult;
1921 /**********************************************************************
1922 * CallWindowProc16 (USER.122)
1924 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
1925 WPARAM16 wParam, LPARAM lParam )
1927 WINDOWPROC *proc = WINPROC_GetPtr( func );
1930 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1933 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
1934 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1940 if (!proc->thunk.t_from32.proc) return 0;
1941 return Callbacks->CallWndProc( proc->thunk.t_from32.proc,
1942 hwnd, msg, wParam, lParam );
1944 if (!proc->thunk.t_from16.proc) return 0;
1945 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
1946 proc->thunk.t_from16.proc );
1948 if (!proc->thunk.t_from16.proc) return 0;
1949 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
1950 proc->thunk.t_from16.proc );
1952 WARN( relay, "Invalid proc %p\n", proc );
1958 /**********************************************************************
1959 * CallWindowProc32A (USER32.18)
1961 * The CallWindowProc() function invokes the windows procedure _func_,
1962 * with _hwnd_ as the target window, the message specified by _msg_, and
1963 * the message parameters _wParam_ and _lParam_.
1965 * Some kinds of argument conversion may be done, I'm not sure what.
1967 * CallWindowProc() may be used for windows subclassing. Use
1968 * SetWindowLong() to set a new windows procedure for windows of the
1969 * subclass, and handle subclassed messages in the new windows
1970 * procedure. The new windows procedure may then use CallWindowProc()
1971 * with _func_ set to the parent class's windows procedure to dispatch
1972 * the message to the superclass.
1976 * The return value is message dependent.
1982 LRESULT WINAPI CallWindowProc32A(
1983 WNDPROC32 func, /* window procedure */
1984 HWND32 hwnd, /* target window */
1985 UINT32 msg, /* message */
1986 WPARAM32 wParam, /* message dependent parameter */
1987 LPARAM lParam /* message dependent parameter */
1989 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1991 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1994 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
1995 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2001 if (!proc->thunk.t_from32.proc) return 0;
2002 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2003 hwnd, msg, wParam, lParam );
2005 if (!proc->thunk.t_from16.proc) return 0;
2006 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
2007 hwnd, msg, wParam, lParam );
2009 if (!proc->thunk.t_from16.proc) return 0;
2010 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2011 hwnd, msg, wParam, lParam );
2013 WARN( relay, "Invalid proc %p\n", proc );
2019 /**********************************************************************
2020 * CallWindowProc32W (USER32.19)
2022 LRESULT WINAPI CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
2023 WPARAM32 wParam, LPARAM lParam )
2025 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2027 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2030 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2031 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2037 if (!proc->thunk.t_from32.proc) return 0;
2038 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2039 hwnd, msg, wParam, lParam );
2041 if (!proc->thunk.t_from16.proc) return 0;
2042 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2043 hwnd, msg, wParam, lParam );
2045 if (!proc->thunk.t_from16.proc) return 0;
2046 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
2047 hwnd, msg, wParam, lParam );
2049 WARN( relay, "Invalid proc %p\n", proc );