2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
13 #include "registers.h"
14 #include "stackframe.h"
22 /* Window procedure 16-bit thunk; see BuildSpec16Files() in tools/build.c */
25 BYTE popl_eax
; /* popl %eax (return address) */
26 BYTE pushl_func
; /* pushl $proc */
27 WNDPROC32 proc WINE_PACKED
;
28 BYTE pushl_eax
; /* pushl %eax */
29 WORD pushw_bp WINE_PACKED
; /* pushw %bp */
30 BYTE pushl_thunk
; /* pushl $thunkfrom16 */
31 void (*thunk32
)() WINE_PACKED
;
32 BYTE lcall
; /* lcall cs:relay */
33 void (*relay
)() WINE_PACKED
;
35 } WINPROC_THUNK_FROM16
;
37 /* Window procedure 32-bit thunk; see BuildSpec32Files() in tools/build.c */
40 BYTE popl_eax
; /* popl %eax (return address) */
41 BYTE pushl_func
; /* pushl $proc */
42 WNDPROC16 proc WINE_PACKED
;
43 BYTE pushl_eax
; /* pushl %eax */
44 BYTE pushl_ebp
; /* pushl %ebp */
45 BYTE pushl_name
; /* pushl $name */
46 LPCSTR name WINE_PACKED
;
47 BYTE pushl_thunk
; /* pushl $thunkfrom32 */
48 void (*thunk32
)() WINE_PACKED
;
49 BYTE jmp
; /* jmp relay (relative jump)*/
50 void (*relay
)() WINE_PACKED
;
51 } WINPROC_THUNK_FROM32
;
53 /* Simple jmp to call 32-bit procedure directly */
56 BYTE jmp
; /* jmp proc (relative jump) */
57 WNDPROC32 proc WINE_PACKED
;
62 WINPROC_THUNK_FROM16 t_from16
;
63 WINPROC_THUNK_FROM32 t_from32
;
66 typedef struct tagWINDOWPROC
68 WINPROC_THUNK thunk
; /* Thunk */
69 WINPROC_JUMP jmp
; /* Jump */
70 struct tagWINDOWPROC
*next
; /* Next window proc */
71 UINT32 magic
; /* Magic number */
72 WINDOWPROCTYPE type
; /* Function type */
75 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
77 #define WINPROC_THUNKPROC(pproc) \
78 (((pproc)->type == WIN_PROC_16) ? \
79 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
80 (WNDPROC16)((pproc)->thunk.t_from16.proc))
82 LRESULT
WINPROC_CallProc16To32A( HWND16 hwnd
, UINT16 msg
,
83 WPARAM16 wParam
, LPARAM lParam
,
85 LRESULT
WINPROC_CallProc16To32W( HWND16 hwnd
, UINT16 msg
,
86 WPARAM16 wParam
, LPARAM lParam
,
88 static LRESULT
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND32 hwnd
,
89 UINT32 msg
, WPARAM32 wParam
,
91 static LRESULT
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND32 hwnd
,
92 UINT32 msg
, WPARAM32 wParam
,
96 extern void CallFrom16_long_wwwll(void);
97 extern void CallFrom32_stdcall_5(void);
99 static void CallFrom16_long_wwwll(void) {}
100 static void CallFrom32_stdcall_5(void) {}
103 /* Reference 16->32A thunk */
104 static const WINPROC_THUNK_FROM16 WINPROC_ThunkRef16To32A
=
106 0x58, /* popl %eax */
107 0x68, 0x00000000, /* pushl $proc32 */
108 0x50, /* pushl %eax */
109 0x5566, /* pushw %bp */
110 0x68, (void (*)())WINPROC_CallProc16To32A
, /* pushl $thunk32 */
111 0x9a, CallFrom16_long_wwwll
, /* lcall cs:relay */
115 /* Reference 16->32W thunk */
116 static const WINPROC_THUNK_FROM16 WINPROC_ThunkRef16To32W
=
118 0x58, /* popl %eax */
119 0x68, 0x00000000, /* pushl $proc32 */
120 0x50, /* pushl %eax */
121 0x5566, /* pushw %bp */
122 0x68, (void (*)())WINPROC_CallProc16To32W
, /* pushl $thunk32 */
123 0x9a, CallFrom16_long_wwwll
, /* lcall cs:relay */
127 /* Reference 32->16 thunk */
128 static const WINPROC_THUNK_FROM32 WINPROC_ThunkRef32To16
=
130 0x58, /* popl %eax */
131 0x68, 0x00000000, /* pushl $proc16 */
132 0x50, /* pushl %eax */
133 0x55, /* pushl %ebp */
134 0x68, "WINPROC_CallProc32ATo16", /* pushl $name */
135 0x68, (void (*)())WINPROC_CallProc32ATo16
, /* pushl $thunk32 */
136 0xe9, CallFrom32_stdcall_5
/* jmp relay */
139 /* Reference 32->32 jump */
140 static const WINPROC_JUMP WINPROC_JumpRef
=
142 0xe9, 0x00000000 /* jmp proc (relative) */
145 static HANDLE32 WinProcHeap
;
147 /**********************************************************************
150 BOOL32
WINPROC_Init(void)
152 WinProcHeap
= HeapCreate( HEAP_WINE_SEGPTR
| HEAP_WINE_CODESEG
, 0, 0 );
155 fprintf( stderr
, "Unable to create winproc heap\n" );
162 /**********************************************************************
165 * Return a pointer to the win proc.
167 static WINDOWPROC
*WINPROC_GetPtr( WNDPROC16 handle
)
172 /* Check for a linear pointer */
174 if (HEAP_IsInsideHeap( WinProcHeap
, 0, (LPVOID
)handle
))
176 ptr
= (BYTE
*)handle
;
177 /* First check if it is the jmp address */
178 if (*ptr
== WINPROC_JumpRef
.jmp
)
179 ptr
-= (int)&((WINDOWPROC
*)0)->jmp
-
180 (int)&((WINDOWPROC
*)0)->thunk
;
181 /* Now it must be the thunk address */
182 if (*ptr
== WINPROC_ThunkRef16To32A
.popl_eax
)
183 ptr
-= (int)&((WINDOWPROC
*)0)->thunk
;
184 /* Now we have a pointer to the WINDOWPROC struct */
185 if (((WINDOWPROC
*)ptr
)->magic
== WINPROC_MAGIC
)
186 return (WINDOWPROC
*)ptr
;
189 /* Check for a segmented pointer */
191 if (!IsBadReadPtr( (SEGPTR
)handle
, sizeof(WINDOWPROC
)-sizeof(proc
->thunk
)))
193 ptr
= (BYTE
*)PTR_SEG_TO_LIN(handle
);
194 /* It must be the thunk address */
195 if (*ptr
== WINPROC_ThunkRef32To16
.popl_eax
)
196 ptr
-= (int)&((WINDOWPROC
*)0)->thunk
;
197 /* Now we have a pointer to the WINDOWPROC struct */
198 if (((WINDOWPROC
*)ptr
)->magic
== WINPROC_MAGIC
)
199 return (WINDOWPROC
*)ptr
;
206 /**********************************************************************
207 * WINPROC_AllocWinProc
209 * Allocate a new window procedure.
211 static WINDOWPROC
*WINPROC_AllocWinProc( WNDPROC16 func
, WINDOWPROCTYPE type
)
213 WINDOWPROC
*proc
, *oldproc
;
215 /* Allocate a window procedure */
217 if (!(proc
= HeapAlloc( WinProcHeap
, 0, sizeof(WINDOWPROC
) ))) return 0;
219 /* Check if the function is already a win proc */
221 if ((oldproc
= WINPROC_GetPtr( func
)))
230 proc
->thunk
.t_from32
= WINPROC_ThunkRef32To16
;
231 proc
->thunk
.t_from32
.proc
= func
;
232 /* We need to fix the relative jump target */
233 proc
->thunk
.t_from32
.relay
= (void (*)())((DWORD
)proc
->thunk
.t_from32
.relay
-
234 (DWORD
)(&proc
->thunk
.t_from32
.relay
+ 1));
237 proc
->thunk
.t_from16
= WINPROC_ThunkRef16To32A
;
238 proc
->thunk
.t_from16
.proc
= (FARPROC32
)func
;
239 proc
->jmp
= WINPROC_JumpRef
;
240 /* Fixup relative jump */
241 proc
->jmp
.proc
= (WNDPROC32
)((DWORD
)func
-
242 (DWORD
)(&proc
->jmp
.proc
+ 1));
245 proc
->thunk
.t_from16
= WINPROC_ThunkRef16To32W
;
246 proc
->thunk
.t_from16
.proc
= (WNDPROC32
)func
;
247 proc
->jmp
= WINPROC_JumpRef
;
248 /* Fixup relative jump */
249 proc
->jmp
.proc
= (WNDPROC32
)((DWORD
)func
-
250 (DWORD
)(&proc
->jmp
.proc
+ 1));
253 /* Should not happen */
256 proc
->magic
= WINPROC_MAGIC
;
260 dprintf_win( stddeb
, "WINPROC_AllocWinProc(%08x,%d): returning %08x\n",
261 (UINT32
)func
, type
, (UINT32
)proc
);
266 /**********************************************************************
269 * Get a window procedure pointer that can be passed to the Windows program.
271 WNDPROC16
WINPROC_GetProc( HWINDOWPROC proc
, WINDOWPROCTYPE type
)
273 if (type
== WIN_PROC_16
) /* We want a 16:16 address */
275 if (((WINDOWPROC
*)proc
)->type
== WIN_PROC_16
)
276 return ((WINDOWPROC
*)proc
)->thunk
.t_from32
.proc
;
278 return (WNDPROC16
)HEAP_GetSegptr( WinProcHeap
, 0,
279 &((WINDOWPROC
*)proc
)->thunk
);
281 else /* We want a 32-bit address */
283 if (((WINDOWPROC
*)proc
)->type
== WIN_PROC_16
)
284 return (WNDPROC16
)&((WINDOWPROC
*)proc
)->thunk
;
286 return (WNDPROC16
)&((WINDOWPROC
*)proc
)->jmp
;
291 /**********************************************************************
294 * Set the window procedure for a window or class.
296 BOOL32
WINPROC_SetProc( HWINDOWPROC
*pFirst
, WNDPROC16 func
,
297 WINDOWPROCTYPE type
)
299 WINDOWPROC
*proc
, **ppPrev
;
301 /* Check if function is already in the list */
303 ppPrev
= (WINDOWPROC
**)pFirst
;
304 proc
= WINPROC_GetPtr( func
);
309 if (*ppPrev
== proc
) break;
313 if (((*ppPrev
)->type
== type
) &&
314 (func
== WINPROC_THUNKPROC(*ppPrev
))) break;
316 ppPrev
= &(*ppPrev
)->next
;
319 if (*ppPrev
) /* Remove it from the list */
322 *ppPrev
= proc
->next
;
324 else /* Allocate a new one */
326 if (proc
) /* Was already a win proc */
329 func
= WINPROC_THUNKPROC(proc
);
331 proc
= WINPROC_AllocWinProc( func
, type
);
332 if (!proc
) return FALSE
;
335 /* Add the win proc at the head of the list */
337 dprintf_win( stddeb
, "WINPROC_SetProc(%08x,%08x,%d): res=%08x\n",
338 (UINT32
)*pFirst
, (UINT32
)func
, type
, (UINT32
)proc
);
339 proc
->next
= *(WINDOWPROC
**)pFirst
;
340 *(WINDOWPROC
**)pFirst
= proc
;
345 /**********************************************************************
348 * Free a list of win procs.
350 void WINPROC_FreeProc( HWINDOWPROC proc
)
354 WINDOWPROC
*next
= ((WINDOWPROC
*)proc
)->next
;
355 dprintf_win( stddeb
, "WINPROC_FreeProc: freeing %08x\n", (UINT32
)proc
);
356 HeapFree( WinProcHeap
, 0, proc
);
362 /**********************************************************************
363 * WINPROC_GetProcType
365 * Return the window procedure type.
367 WINDOWPROCTYPE
WINPROC_GetProcType( HWINDOWPROC proc
)
370 (((WINDOWPROC
*)proc
)->magic
!= WINPROC_MAGIC
))
371 return WIN_PROC_INVALID
;
372 return ((WINDOWPROC
*)proc
)->type
;
376 /**********************************************************************
377 * WINPROC_MapMsg32ATo32W
379 * Map a message from Ansi to Unicode.
380 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
382 INT32
WINPROC_MapMsg32ATo32W( UINT32 msg
, WPARAM32 wParam
, LPARAM
*plparam
)
388 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( SystemHeap
, 0,
389 wParam
* sizeof(WCHAR
) + sizeof(LPARAM
) );
391 *ptr
++ = *plparam
; /* Store previous lParam */
392 *plparam
= (LPARAM
)ptr
;
396 *plparam
= (LPARAM
)STRING32_DupAnsiToUni( (LPCSTR
)*plparam
);
397 return (*plparam
? 1 : -1);
401 CREATESTRUCT32W
*cs
= (CREATESTRUCT32W
*)HeapAlloc( SystemHeap
, 0,
404 *cs
= *(CREATESTRUCT32W
*)*plparam
;
405 if (HIWORD(cs
->lpszName
))
406 cs
->lpszName
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->lpszName
);
407 if (HIWORD(cs
->lpszClass
))
408 cs
->lpszClass
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->lpszClass
);
409 *plparam
= (LPARAM
)cs
;
412 default: /* No translation needed */
418 /**********************************************************************
419 * WINPROC_UnmapMsg32ATo32W
421 * Unmap a message that was mapped from Ansi to Unicode.
423 void WINPROC_UnmapMsg32ATo32W( UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
429 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
430 lstrcpynWtoA( (LPSTR
)*ptr
, (LPWSTR
)(ptr
+ 1), wParam
);
431 HeapFree( SystemHeap
, 0, ptr
);
435 free( (void *)lParam
);
440 CREATESTRUCT32W
*cs
= (CREATESTRUCT32W
*)lParam
;
441 if (HIWORD(cs
->lpszName
)) free( (LPVOID
)cs
->lpszName
);
442 if (HIWORD(cs
->lpszClass
)) free( (LPVOID
)cs
->lpszClass
);
443 HeapFree( SystemHeap
, 0, cs
);
450 /**********************************************************************
451 * WINPROC_MapMsg32WTo32A
453 * Map a message from Unicode to Ansi.
454 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
456 INT32
WINPROC_MapMsg32WTo32A( UINT32 msg
, WPARAM32 wParam
, LPARAM
*plparam
)
462 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( SystemHeap
, 0,
463 wParam
+ sizeof(LPARAM
) );
465 *ptr
++ = *plparam
; /* Store previous lParam */
466 *plparam
= (LPARAM
)ptr
;
470 *plparam
= (LPARAM
)STRING32_DupUniToAnsi( (LPCWSTR
)*plparam
);
471 return (*plparam
? 1 : -1);
475 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)HeapAlloc( SystemHeap
, 0,
478 *cs
= *(CREATESTRUCT32A
*)*plparam
;
479 if (HIWORD(cs
->lpszName
))
480 cs
->lpszName
= STRING32_DupUniToAnsi( (LPCWSTR
)cs
->lpszName
);
481 if (HIWORD(cs
->lpszClass
))
482 cs
->lpszClass
= STRING32_DupUniToAnsi( (LPCWSTR
)cs
->lpszClass
);
483 *plparam
= (LPARAM
)cs
;
486 default: /* No translation needed */
492 /**********************************************************************
493 * WINPROC_UnmapMsg32WTo32A
495 * Unmap a message that was mapped from Unicode to Ansi.
497 void WINPROC_UnmapMsg32WTo32A( UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
503 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
504 lstrcpynAtoW( (LPWSTR
)*ptr
, (LPSTR
)(ptr
+ 1), wParam
);
505 HeapFree( SystemHeap
, 0, ptr
);
509 free( (void *)lParam
);
514 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)lParam
;
515 if (HIWORD(cs
->lpszName
)) free( (LPVOID
)cs
->lpszName
);
516 if (HIWORD(cs
->lpszClass
)) free( (LPVOID
)cs
->lpszClass
);
517 HeapFree( SystemHeap
, 0, cs
);
524 /**********************************************************************
525 * WINPROC_MapMsg16To32A
527 * Map a message from 16- to 32-bit Ansi.
528 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
530 INT32
WINPROC_MapMsg16To32A( UINT16 msg16
, WPARAM16 wParam16
, UINT32
*pmsg32
,
531 WPARAM32
*pwparam32
, LPARAM
*plparam
)
533 *pmsg32
= (UINT32
)msg16
;
534 *pwparam32
= (WPARAM32
)wParam16
;
543 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
544 *plparam
= (LPARAM
)(HWND32
)LOWORD(*plparam
);
547 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
548 *pwparam32
= (WPARAM32
)(HDC32
)wParam16
;
549 *plparam
= (LPARAM
)(HWND32
)LOWORD(*plparam
);
553 DRAWITEMSTRUCT16
* dis16
= (DRAWITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
554 DRAWITEMSTRUCT32
*dis
= (DRAWITEMSTRUCT32
*)HeapAlloc(SystemHeap
, 0,
557 dis
->CtlType
= dis16
->CtlType
;
558 dis
->CtlID
= dis16
->CtlID
;
559 dis
->itemID
= dis16
->itemID
;
560 dis
->itemAction
= dis16
->itemAction
;
561 dis
->itemState
= dis16
->itemState
;
562 dis
->hwndItem
= dis16
->hwndItem
;
563 dis
->hDC
= dis16
->hDC
;
564 dis
->itemData
= dis16
->itemData
;
565 CONV_RECT16TO32( &dis16
->rcItem
, &dis
->rcItem
);
566 *plparam
= (LPARAM
)dis
;
569 case WM_GETMINMAXINFO
:
571 MINMAXINFO32
*mmi
= (MINMAXINFO32
*)HeapAlloc( SystemHeap
, 0,
572 sizeof(*mmi
) + sizeof(LPARAM
));
574 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16
*)PTR_SEG_TO_LIN(*plparam
),
576 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
577 *plparam
= (LPARAM
)mmi
;
581 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
584 *pwparam32
= (WPARAM32
)(HMENU32
)LOWORD(*plparam
);
585 *plparam
= (LPARAM
)(HMENU32
)HIWORD(*plparam
);
589 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
590 *plparam
= (LPARAM
)(HMENU32
)HIWORD(*plparam
);
594 NCCALCSIZE_PARAMS16
*nc16
;
595 NCCALCSIZE_PARAMS32
*nc
;
597 nc
= (NCCALCSIZE_PARAMS32
*)HeapAlloc( SystemHeap
, 0,
598 sizeof(*nc
) + sizeof(LPARAM
) );
600 nc16
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(*plparam
);
601 CONV_RECT16TO32( &nc16
->rgrc
[0], &nc
->rgrc
[0] );
604 nc
->lppos
= (WINDOWPOS32
*)HeapAlloc( SystemHeap
, 0,
605 sizeof(*nc
->lppos
) );
606 CONV_RECT16TO32( &nc16
->rgrc
[1], &nc
->rgrc
[1] );
607 CONV_RECT16TO32( &nc16
->rgrc
[2], &nc
->rgrc
[2] );
608 if (nc
->lppos
) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc16
->lppos
), nc
->lppos
);
610 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
611 *plparam
= (LPARAM
)nc
;
617 CREATESTRUCT16
*cs16
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
618 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)HeapAlloc( SystemHeap
, 0,
619 sizeof(*cs
) + sizeof(LPARAM
) );
621 STRUCT32_CREATESTRUCT16to32A( cs16
, cs
);
622 cs
->lpszName
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->lpszName
);
623 cs
->lpszClass
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->lpszClass
);
624 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
625 *plparam
= (LPARAM
)cs
;
628 case WM_PARENTNOTIFY
:
629 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
631 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
632 *plparam
= (LPARAM
)(HWND32
)LOWORD(*plparam
);
636 *pwparam32
= MAKEWPARAM( wParam16
, 0 /* FIXME? */ );
640 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
642 case WM_WINDOWPOSCHANGING
:
643 case WM_WINDOWPOSCHANGED
:
645 WINDOWPOS32
*wp
= (WINDOWPOS32
*)HeapAlloc( SystemHeap
, 0,
646 sizeof(*wp
) + sizeof(LPARAM
) );
648 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(*plparam
),
650 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
651 *plparam
= (LPARAM
)wp
;
654 case WM_ASKCBFORMATNAME
:
657 case WM_DEVMODECHANGE
:
661 case WM_PAINTCLIPBOARD
:
662 case WM_SIZECLIPBOARD
:
663 case WM_WININICHANGE
:
664 fprintf( stderr
, "MapMsg16To32A: message %04x needs translation\n",
668 default: /* No translation needed */
674 /**********************************************************************
675 * WINPROC_UnmapMsg16To32A
677 * Unmap a message that was mapped from 16- to 32-bit Ansi.
679 void WINPROC_UnmapMsg16To32A( UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
684 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
686 case WM_GETMINMAXINFO
:
688 MINMAXINFO32
*mmi
= (MINMAXINFO32
*)lParam
;
689 lParam
= *(LPARAM
*)(mmi
+ 1);
690 STRUCT32_MINMAXINFO32to16( mmi
,
691 (MINMAXINFO16
*)PTR_SEG_TO_LIN(lParam
));
692 HeapFree( SystemHeap
, 0, mmi
);
697 NCCALCSIZE_PARAMS16
*nc16
;
698 NCCALCSIZE_PARAMS32
*nc
= (NCCALCSIZE_PARAMS32
*)lParam
;
699 lParam
= *(LPARAM
*)(nc
+ 1);
700 nc16
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(lParam
);
701 CONV_RECT32TO16( &nc
->rgrc
[0], &nc16
->rgrc
[0] );
704 CONV_RECT32TO16( &nc
->rgrc
[1], &nc16
->rgrc
[1] );
705 CONV_RECT32TO16( &nc
->rgrc
[2], &nc16
->rgrc
[2] );
708 STRUCT32_WINDOWPOS32to16( nc
->lppos
,
709 (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc16
->lppos
));
710 HeapFree( SystemHeap
, 0, nc
->lppos
);
713 HeapFree( SystemHeap
, 0, nc
);
719 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)lParam
;
720 lParam
= *(LPARAM
*)(cs
+ 1);
721 STRUCT32_CREATESTRUCT32Ato16( cs
,
722 (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
723 HeapFree( SystemHeap
, 0, cs
);
726 case WM_WINDOWPOSCHANGING
:
727 case WM_WINDOWPOSCHANGED
:
729 WINDOWPOS32
*wp
= (WINDOWPOS32
*)lParam
;
730 lParam
= *(LPARAM
*)(wp
+ 1);
731 STRUCT32_WINDOWPOS32to16(wp
,(WINDOWPOS16
*)PTR_SEG_TO_LIN(lParam
));
732 HeapFree( SystemHeap
, 0, wp
);
739 /**********************************************************************
740 * WINPROC_MapMsg16To32W
742 * Map a message from 16- to 32-bit Unicode.
743 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
745 INT32
WINPROC_MapMsg16To32W( UINT16 msg16
, WPARAM16 wParam16
, UINT32
*pmsg32
,
746 WPARAM32
*pwparam32
, LPARAM
*plparam
)
752 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
753 return WINPROC_MapMsg32ATo32W( *pmsg32
, *pwparam32
, plparam
);
757 CREATESTRUCT16
*cs16
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
758 CREATESTRUCT32W
*cs
= (CREATESTRUCT32W
*)HeapAlloc( SystemHeap
, 0,
759 sizeof(*cs
) + sizeof(LPARAM
) );
761 STRUCT32_CREATESTRUCT16to32A( cs16
, (CREATESTRUCT32A
*)cs
);
762 cs
->lpszName
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->lpszName
);
763 cs
->lpszClass
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->lpszClass
);
764 if (HIWORD(cs
->lpszName
))
765 cs
->lpszName
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->lpszName
);
766 if (HIWORD(cs
->lpszClass
))
767 cs
->lpszClass
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->lpszClass
);
768 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
769 *plparam
= (LPARAM
)cs
;
772 default: /* No Unicode translation needed */
773 return WINPROC_MapMsg16To32A( msg16
, wParam16
, pmsg32
,
774 pwparam32
, plparam
);
779 /**********************************************************************
780 * WINPROC_UnmapMsg16To32W
782 * Unmap a message that was mapped from 16- to 32-bit Unicode.
784 void WINPROC_UnmapMsg16To32W( UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
790 WINPROC_UnmapMsg32ATo32W( msg
, wParam
, lParam
);
795 CREATESTRUCT32W
*cs
= (CREATESTRUCT32W
*)lParam
;
796 lParam
= *(LPARAM
*)(cs
+ 1);
797 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A
*)cs
,
798 (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
799 if (HIWORD(cs
->lpszName
)) free( (LPVOID
)cs
->lpszName
);
800 if (HIWORD(cs
->lpszClass
)) free( (LPVOID
)cs
->lpszClass
);
801 HeapFree( SystemHeap
, 0, cs
);
805 WINPROC_UnmapMsg16To32A( msg
, wParam
, lParam
);
811 /**********************************************************************
812 * WINPROC_MapMsg32ATo16
814 * Map a message from 32-bit Ansi to 16-bit.
815 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
817 INT32
WINPROC_MapMsg32ATo16( UINT32 msg32
, WPARAM32 wParam32
, UINT16
*pmsg16
,
818 WPARAM16
*pwparam16
, LPARAM
*plparam
)
820 *pmsg16
= (UINT16
)msg32
;
821 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
828 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
832 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
834 case WM_CTLCOLORMSGBOX
:
835 case WM_CTLCOLOREDIT
:
836 case WM_CTLCOLORLISTBOX
:
839 case WM_CTLCOLORSCROLLBAR
:
840 case WM_CTLCOLORSTATIC
:
841 *pmsg16
= WM_CTLCOLOR
;
842 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
843 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
847 DRAWITEMSTRUCT32
*dis32
= (DRAWITEMSTRUCT32
*)*plparam
;
848 DRAWITEMSTRUCT16
*dis
= SEGPTR_NEW(DRAWITEMSTRUCT16
);
850 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
851 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
852 dis
->itemID
= (UINT16
)dis32
->itemID
;
853 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
854 dis
->itemState
= (UINT16
)dis32
->itemState
;
855 dis
->hwndItem
= (HWND16
)dis32
->hwndItem
;
856 dis
->hDC
= (HDC16
)dis32
->hDC
;
857 dis
->itemData
= dis32
->itemData
;
858 CONV_RECT32TO16( &dis32
->rcItem
, &dis
->rcItem
);
859 *plparam
= (LPARAM
)SEGPTR_GET(dis
);
862 case WM_GETMINMAXINFO
:
864 MINMAXINFO16
*mmi
= (MINMAXINFO16
*)SEGPTR_ALLOC( sizeof(*mmi
) +
867 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32
*)*plparam
, mmi
);
868 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
869 *plparam
= (LPARAM
)SEGPTR_GET(mmi
);
875 *pwparam16
= (WPARAM16
)MIN( wParam32
, 0xff80 ); /* Must be < 64K */
876 if (!(str
= SEGPTR_ALLOC(*pwparam16
+ sizeof(LPARAM
)))) return -1;
877 *((LPARAM
*)str
)++ = *plparam
; /* Store the previous lParam */
878 *plparam
= (LPARAM
)SEGPTR_GET(str
);
882 *pwparam16
= TRUE
; /* FIXME? */
883 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
884 (HMENU16
)LOWORD(*plparam
) );
888 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
892 NCCALCSIZE_PARAMS32
*nc32
= (NCCALCSIZE_PARAMS32
*)*plparam
;
893 NCCALCSIZE_PARAMS16
*nc
= (NCCALCSIZE_PARAMS16
*)SEGPTR_ALLOC( sizeof(*nc
) + sizeof(LPARAM
) );
896 CONV_RECT32TO16( &nc32
->rgrc
[0], &nc
->rgrc
[0] );
900 CONV_RECT32TO16( &nc32
->rgrc
[1], &nc
->rgrc
[1] );
901 CONV_RECT32TO16( &nc32
->rgrc
[2], &nc
->rgrc
[2] );
902 if (!(wp
= SEGPTR_NEW(WINDOWPOS16
)))
907 STRUCT32_WINDOWPOS32to16( nc32
->lppos
, wp
);
908 nc
->lppos
= SEGPTR_GET(wp
);
910 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
911 *plparam
= (LPARAM
)SEGPTR_GET(nc
);
918 CREATESTRUCT32A
*cs32
= (CREATESTRUCT32A
*)*plparam
;
921 if (!(cs
= SEGPTR_NEW(CREATESTRUCT16
))) return -1;
922 STRUCT32_CREATESTRUCT32Ato16( cs32
, cs
);
923 name
= SEGPTR_STRDUP( cs32
->lpszName
);
924 cls
= SEGPTR_STRDUP( cs32
->lpszClass
);
925 cs
->lpszName
= SEGPTR_GET(name
);
926 cs
->lpszClass
= SEGPTR_GET(cls
);
927 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
930 case WM_PARENTNOTIFY
:
931 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
932 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
933 /* else nothing to do */
937 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
939 *plparam
= (LPARAM
)SEGPTR_GET(str
);
942 case WM_WINDOWPOSCHANGING
:
943 case WM_WINDOWPOSCHANGED
:
945 WINDOWPOS16
*wp
= (WINDOWPOS16
*)SEGPTR_ALLOC( sizeof(*wp
) +
948 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32
*)*plparam
, wp
);
949 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
950 *plparam
= (LPARAM
)SEGPTR_GET(wp
);
953 case WM_ASKCBFORMATNAME
:
956 case WM_DEVMODECHANGE
:
960 case WM_PAINTCLIPBOARD
:
961 case WM_SIZECLIPBOARD
:
962 case WM_WININICHANGE
:
963 fprintf( stderr
, "MapMsg32ATo16: message %04x needs translation\n",
967 default: /* No translation needed */
973 /**********************************************************************
974 * WINPROC_UnmapMsg32ATo16
976 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
978 void WINPROC_UnmapMsg32ATo16( UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
983 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
985 case WM_GETMINMAXINFO
:
987 MINMAXINFO16
*mmi
= (MINMAXINFO16
*)PTR_SEG_TO_LIN(lParam
);
988 lParam
= *(LPARAM
*)(mmi
+ 1);
989 STRUCT32_MINMAXINFO16to32( mmi
, (MINMAXINFO32
*)lParam
);
995 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(lParam
);
996 lParam
= *((LPARAM
*)str
- 1);
997 strcpy( (LPSTR
)lParam
, str
);
998 SEGPTR_FREE( (LPARAM
*)str
- 1 );
1003 NCCALCSIZE_PARAMS32
*nc32
;
1004 NCCALCSIZE_PARAMS16
*nc
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(lParam
);
1005 lParam
= *(LPARAM
*)(nc
+ 1);
1006 nc32
= (NCCALCSIZE_PARAMS32
*)lParam
;
1007 CONV_RECT16TO32( &nc
->rgrc
[0], &nc32
->rgrc
[0] );
1010 CONV_RECT16TO32( &nc
->rgrc
[1], &nc32
->rgrc
[1] );
1011 CONV_RECT16TO32( &nc
->rgrc
[2], &nc32
->rgrc
[2] );
1012 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc
->lppos
),
1014 SEGPTR_FREE( PTR_SEG_TO_LIN(nc
->lppos
) );
1022 CREATESTRUCT16
*cs
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
1023 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->lpszName
) );
1024 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->lpszClass
) );
1029 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
1031 case WM_WINDOWPOSCHANGING
:
1032 case WM_WINDOWPOSCHANGED
:
1034 WINDOWPOS16
*wp
= (WINDOWPOS16
*)PTR_SEG_TO_LIN(lParam
);
1035 lParam
= *(LPARAM
*)(wp
+ 1);
1036 STRUCT32_WINDOWPOS16to32( wp
, (WINDOWPOS32
*)lParam
);
1044 /**********************************************************************
1045 * WINPROC_MapMsg32WTo16
1047 * Map a message from 32-bit Unicode to 16-bit.
1048 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1050 INT32
WINPROC_MapMsg32WTo16( UINT32 msg32
, WPARAM32 wParam32
, UINT16
*pmsg16
,
1051 WPARAM16
*pwparam16
, LPARAM
*plparam
)
1059 CREATESTRUCT32W
*cs32
= (CREATESTRUCT32W
*)*plparam
;
1061 if (!(cs
= SEGPTR_NEW(CREATESTRUCT16
))) return -1;
1062 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A
*)cs32
, cs
);
1063 if (HIWORD(cs32
->lpszName
))
1065 LPSTR name
= SEGPTR_ALLOC( lstrlen32W(cs32
->lpszName
) + 1 );
1066 STRING32_UniToAnsi( name
, cs32
->lpszName
);
1067 cs
->lpszName
= SEGPTR_GET(name
);
1069 else cs
->lpszName
= (SEGPTR
)cs32
->lpszName
;
1070 if (HIWORD(cs32
->lpszClass
))
1072 LPSTR name
= SEGPTR_ALLOC( lstrlen32W(cs32
->lpszClass
) + 1 );
1073 STRING32_UniToAnsi( name
, cs32
->lpszClass
);
1074 cs
->lpszClass
= SEGPTR_GET(name
);
1076 else cs
->lpszClass
= (SEGPTR
)cs32
->lpszClass
;
1077 *pmsg16
= (UINT16
)msg32
;
1078 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1079 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
1084 LPSTR str
= SEGPTR_ALLOC( lstrlen32W((LPWSTR
)*plparam
) + 1 );
1085 if (!str
) return -1;
1086 STRING32_UniToAnsi( str
, (LPWSTR
)*plparam
);
1087 *pmsg16
= (UINT16
)msg32
;
1088 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1089 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1092 default: /* No Unicode translation needed */
1093 return WINPROC_MapMsg32ATo16( msg32
, wParam32
, pmsg16
,
1094 pwparam16
, plparam
);
1099 /**********************************************************************
1100 * WINPROC_UnmapMsg32WTo16
1102 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1104 void WINPROC_UnmapMsg32WTo16( UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
1110 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(lParam
);
1111 lParam
= *((LPARAM
*)str
- 1);
1112 STRING32_AnsiToUni( (LPWSTR
)lParam
, str
);
1113 SEGPTR_FREE( (LPARAM
*)str
- 1 );
1117 WINPROC_UnmapMsg32ATo16( msg
, wParam
, lParam
);
1123 /**********************************************************************
1124 * WINPROC_CallProc32ATo32W
1126 * Call a window procedure, translating args from Ansi to Unicode.
1128 static LRESULT
WINPROC_CallProc32ATo32W( WNDPROC32 func
, HWND32 hwnd
,
1129 UINT32 msg
, WPARAM32 wParam
,
1134 if (WINPROC_MapMsg32ATo32W( msg
, wParam
, &lParam
) == -1) return 0;
1135 result
= CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1136 WINPROC_UnmapMsg32ATo32W( msg
, wParam
, lParam
);
1141 /**********************************************************************
1142 * WINPROC_CallProc32WTo32A
1144 * Call a window procedure, translating args from Unicode to Ansi.
1146 static LRESULT
WINPROC_CallProc32WTo32A( WNDPROC32 func
, HWND32 hwnd
,
1147 UINT32 msg
, WPARAM32 wParam
,
1152 if (WINPROC_MapMsg32WTo32A( msg
, wParam
, &lParam
) == -1) return 0;
1153 result
= CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1154 WINPROC_UnmapMsg32WTo32A( msg
, wParam
, lParam
);
1159 /**********************************************************************
1160 * WINPROC_CallProc16To32A
1162 * Call a 32-bit window procedure, translating the 16-bit args.
1164 LRESULT
WINPROC_CallProc16To32A( HWND16 hwnd
, UINT16 msg
,
1165 WPARAM16 wParam
, LPARAM lParam
,
1172 if (WINPROC_MapMsg16To32A( msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
1174 result
= CallWndProc32( func
, hwnd
, msg32
, wParam32
, lParam
);
1175 WINPROC_UnmapMsg16To32A( msg32
, wParam32
, lParam
);
1180 /**********************************************************************
1181 * WINPROC_CallProc16To32W
1183 * Call a 32-bit window procedure, translating the 16-bit args.
1185 LRESULT
WINPROC_CallProc16To32W( HWND16 hwnd
, UINT16 msg
,
1186 WPARAM16 wParam
, LPARAM lParam
,
1193 if (WINPROC_MapMsg16To32W( msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
1195 result
= CallWndProc32( func
, hwnd
, msg32
, wParam32
, lParam
);
1196 WINPROC_UnmapMsg16To32W( msg32
, wParam32
, lParam
);
1201 /**********************************************************************
1202 * WINPROC_CallProc32ATo16
1204 * Call a 16-bit window procedure, translating the 32-bit args.
1206 static LRESULT
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND32 hwnd
,
1207 UINT32 msg
, WPARAM32 wParam
,
1213 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1214 WORD ds
= wndPtr
? wndPtr
->hInstance
: CURRENT_DS
;
1216 if (WINPROC_MapMsg32ATo16( msg
, wParam
, &msg16
, &wParam16
, &lParam
) == -1)
1218 result
= CallWndProc16( func
, ds
, hwnd
, msg16
, wParam16
, lParam
);
1219 WINPROC_UnmapMsg32ATo16( msg16
, wParam16
, lParam
);
1224 /**********************************************************************
1225 * WINPROC_CallProc32WTo16
1227 * Call a 16-bit window procedure, translating the 32-bit args.
1229 static LRESULT
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND32 hwnd
,
1230 UINT32 msg
, WPARAM32 wParam
,
1236 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1238 if (WINPROC_MapMsg32WTo16( msg
, wParam
, &msg16
, &wParam16
, &lParam
) == -1)
1240 result
= CallWndProc16( func
, wndPtr
? wndPtr
->hInstance
: CURRENT_DS
,
1241 hwnd
, msg16
, wParam16
, lParam
);
1242 WINPROC_UnmapMsg32WTo16( msg16
, wParam16
, lParam
);
1247 /**********************************************************************
1248 * CallWindowProc16 (USER.122)
1250 LRESULT
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
1251 WPARAM16 wParam
, LPARAM lParam
)
1254 WINDOWPROC
*proc
= WINPROC_GetPtr( func
);
1258 wndPtr
= WIN_FindWndPtr( hwnd
);
1259 return CallWndProc16( (FARPROC16
)func
,
1260 wndPtr
? wndPtr
->hInstance
: CURRENT_DS
,
1261 hwnd
, msg
, wParam
, lParam
);
1264 wndPtr
= WIN_FindWndPtr( hwnd
);
1265 return CallWndProc16( WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_16
),
1266 wndPtr
? wndPtr
->hInstance
: CURRENT_DS
,
1267 hwnd
, msg
, wParam
, lParam
);
1273 if (!proc
->thunk
.t_from32
.proc
) return 0;
1274 wndPtr
= WIN_FindWndPtr( hwnd
);
1276 if ((msg
== WM_CREATE
) || (msg
== WM_NCCREATE
))
1278 CREATESTRUCT16
*cs
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
1279 /* Build the CREATESTRUCT on the 16-bit stack. */
1280 /* This is really ugly, but some programs (notably the */
1281 /* "Undocumented Windows" examples) want it that way. */
1282 return CallWndProcNCCREATE16( proc
->thunk
.t_from32
.proc
,
1283 wndPtr
? wndPtr
->hInstance
: CURRENT_DS
, cs
->dwExStyle
,
1284 cs
->lpszClass
, cs
->lpszName
, cs
->style
, cs
->x
, cs
->y
,
1285 cs
->cx
, cs
->cy
, cs
->hwndParent
, cs
->hMenu
, cs
->hInstance
,
1286 (LONG
)cs
->lpCreateParams
, hwnd
, msg
, wParam
,
1287 MAKELONG( IF1632_Saved16_sp
-sizeof(CREATESTRUCT16
),
1288 IF1632_Saved16_ss
) );
1291 return CallWndProc16( proc
->thunk
.t_from32
.proc
,
1292 wndPtr
? wndPtr
->hInstance
: CURRENT_DS
,
1293 hwnd
, msg
, wParam
, lParam
);
1295 if (!proc
->thunk
.t_from16
.proc
) return 0;
1296 return WINPROC_CallProc16To32A( hwnd
, msg
, wParam
, lParam
,
1297 proc
->thunk
.t_from16
.proc
);
1299 if (!proc
->thunk
.t_from16
.proc
) return 0;
1300 return WINPROC_CallProc16To32W( hwnd
, msg
, wParam
, lParam
,
1301 proc
->thunk
.t_from16
.proc
);
1303 fprintf( stderr
, "CallWindowProc16: invalid proc %p\n", proc
);
1309 /**********************************************************************
1310 * CallWindowProc32A (USER32.17)
1312 LRESULT
CallWindowProc32A( WNDPROC32 func
, HWND32 hwnd
, UINT32 msg
,
1313 WPARAM32 wParam
, LPARAM lParam
)
1315 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
1317 if (!proc
) return CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1320 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32A
);
1321 return CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1327 if (!proc
->thunk
.t_from32
.proc
) return 0;
1328 return WINPROC_CallProc32ATo16( proc
->thunk
.t_from32
.proc
,
1329 hwnd
, msg
, wParam
, lParam
);
1331 if (!proc
->thunk
.t_from16
.proc
) return 0;
1332 return CallWndProc32( proc
->thunk
.t_from16
.proc
,
1333 hwnd
, msg
, wParam
, lParam
);
1335 if (!proc
->thunk
.t_from16
.proc
) return 0;
1336 return WINPROC_CallProc32ATo32W( proc
->thunk
.t_from16
.proc
,
1337 hwnd
, msg
, wParam
, lParam
);
1339 fprintf( stderr
, "CallWindowProc32A: invalid proc %p\n", proc
);
1345 /**********************************************************************
1346 * CallWindowProc32W (USER32.18)
1348 LRESULT
CallWindowProc32W( WNDPROC32 func
, HWND32 hwnd
, UINT32 msg
,
1349 WPARAM32 wParam
, LPARAM lParam
)
1351 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
1353 if (!proc
) return CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1356 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32W
);
1357 return CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1363 if (!proc
->thunk
.t_from32
.proc
) return 0;
1364 return WINPROC_CallProc32WTo16( proc
->thunk
.t_from32
.proc
,
1365 hwnd
, msg
, wParam
, lParam
);
1367 if (!proc
->thunk
.t_from16
.proc
) return 0;
1368 return WINPROC_CallProc32WTo32A( proc
->thunk
.t_from16
.proc
,
1369 hwnd
, msg
, wParam
, lParam
);
1371 if (!proc
->thunk
.t_from16
.proc
) return 0;
1372 return CallWndProc32( proc
->thunk
.t_from16
.proc
,
1373 hwnd
, msg
, wParam
, lParam
);
1375 fprintf( stderr
, "CallWindowProc32W: invalid proc %p\n", proc
);