2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
14 #include "wine/winbase16.h"
15 #include "wine/winuser16.h"
16 #include "stackframe.h"
17 #include "builtin16.h"
20 #include "selectors.h"
24 #include "debugtools.h"
30 DECLARE_DEBUG_CHANNEL(msg
);
31 DECLARE_DEBUG_CHANNEL(relay
);
32 DECLARE_DEBUG_CHANNEL(win
);
34 /* Window procedure 16-to-32-bit thunk,
35 * see BuildSpec16File() in tools/build.c */
40 WORD pushw_bp
; /* pushw %bp */
41 BYTE pushl_func
; /* pushl $proc */
43 WORD pushw_ax
; /* pushw %ax */
44 BYTE pushl_relay
; /* pushl $relay */
45 void (*relay
)(); /* WINPROC_Thunk16To32A/W() */
46 BYTE lcall
; /* lcall cs:glue */
47 void (*glue
)(); /* __wine_call_from_16_long */
48 WORD cs
; /* __FLATCS */
49 WORD lret
; /* lret $10 */
51 } WINPROC_THUNK_FROM16
;
54 /* Window procedure 32-to-16-bit thunk,
55 * see BuildSpec32File() in tools/build.c */
59 BYTE popl_eax
; /* popl %eax (return address) */
60 BYTE pushl_func
; /* pushl $proc */
61 WNDPROC16 proc WINE_PACKED
;
62 BYTE pushl_eax
; /* pushl %eax */
63 BYTE jmp
; /* jmp relay (relative jump)*/
64 void (*relay
)() WINE_PACKED
; /* WINPROC_CallProc32ATo16() */
65 } WINPROC_THUNK_FROM32
;
67 /* Simple jmp to call 32-bit procedure directly */
70 BYTE jmp
; /* jmp proc (relative jump) */
71 WNDPROC proc WINE_PACKED
;
76 WINPROC_THUNK_FROM16 t_from16
;
77 WINPROC_THUNK_FROM32 t_from32
;
80 typedef struct tagWINDOWPROC
82 WINPROC_THUNK thunk
; /* Thunk */
83 WINPROC_JUMP jmp
; /* Jump */
84 struct tagWINDOWPROC
*next
; /* Next window proc */
85 UINT magic
; /* Magic number */
86 WINDOWPROCTYPE type
; /* Function type */
87 WINDOWPROCUSER user
; /* Function user */
90 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
92 #define WINPROC_THUNKPROC(pproc) \
93 (((pproc)->type == WIN_PROC_16) ? \
94 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
95 (WNDPROC16)((pproc)->thunk.t_from16.proc))
97 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
98 UINT msg
, WPARAM wParam
,
100 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
101 UINT msg
, WPARAM wParam
,
103 static LRESULT WINAPI
WINPROC_Thunk16To32A( WNDPROC func
, LPBYTE args
);
104 static LRESULT WINAPI
WINPROC_Thunk16To32W( WNDPROC func
, LPBYTE args
);
106 static HANDLE WinProcHeap
;
109 /**********************************************************************
112 BOOL
WINPROC_Init(void)
114 WinProcHeap
= HeapCreate( HEAP_WINE_SEGPTR
| HEAP_WINE_CODESEG
, 0, 0 );
117 WARN_(relay
)("Unable to create winproc heap\n" );
125 /* Some window procedures modify register they shouldn't, or are not
126 * properly declared stdcall; so we need a small assembly wrapper to
128 extern LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
129 WPARAM wParam
, LPARAM lParam
);
130 __ASM_GLOBAL_FUNC( WINPROC_wrapper
,
140 "movl 8(%ebp),%eax\n\t"
142 "leal -12(%ebp),%esp\n\t"
149 static inline LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
150 WPARAM wParam
, LPARAM lParam
)
152 return proc( hwnd
, msg
, wParam
, lParam
);
154 #endif /* __i386__ */
156 /**********************************************************************
157 * WINPROC_CallWndProc32
159 * Call a 32-bit WndProc.
161 static LRESULT
WINPROC_CallWndProc( WNDPROC proc
, HWND hwnd
, UINT msg
,
162 WPARAM wParam
, LPARAM lParam
)
167 TRACE_(relay
)("(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
168 proc
, hwnd
, SPY_GetMsgName(msg
), wParam
, lParam
);
169 /* To avoid any deadlocks, all the locks on the windows structures
170 must be suspended before the control is passed to the application */
171 iWndsLocks
= WIN_SuspendWndsLock();
172 retvalue
= WINPROC_wrapper( proc
, hwnd
, msg
, wParam
, lParam
);
173 WIN_RestoreWndsLock(iWndsLocks
);
174 TRACE_(relay
)("(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx) ret=%08lx\n",
175 proc
, hwnd
, SPY_GetMsgName(msg
), wParam
, lParam
, retvalue
);
179 /***********************************************************************
180 * WINPROC_CallWndProc16
182 * Call a 16-bit window procedure
184 static LRESULT WINAPI
WINPROC_CallWndProc16( WNDPROC16 proc
, HWND16 hwnd
,
185 UINT16 msg
, WPARAM16 wParam
,
191 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
193 TEB
*teb
= NtCurrentTeb();
196 /* Window procedures want ax = hInstance, ds = es = ss */
198 memset(&context
, '\0', sizeof(context
));
199 context
.SegDs
= context
.SegEs
= SELECTOROF(teb
->cur_stack
);
200 context
.Eax
= wndPtr
? wndPtr
->hInstance
: context
.SegDs
;
201 context
.SegCs
= SELECTOROF(proc
);
202 context
.Eip
= OFFSETOF(proc
);
203 context
.Ebp
= OFFSETOF(teb
->cur_stack
)
204 + (WORD
)&((STACK16FRAME
*)0)->bp
;
206 WIN_ReleaseWndPtr(wndPtr
);
210 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
211 work if structures passed in lParam are placed in the stack/data
212 segment. Programmers easily make the mistake of converting lParam
213 to a near rather than a far pointer, since Windows apparently
214 allows this. We copy the structures to the 16 bit stack; this is
215 ugly but makes these programs work. */
220 offset
= sizeof(CREATESTRUCT16
); break;
222 offset
= sizeof(DRAWITEMSTRUCT16
); break;
224 offset
= sizeof(COMPAREITEMSTRUCT16
); break;
228 void *s
= PTR_SEG_TO_LIN(lParam
);
229 lParam
= stack16_push( offset
);
230 memcpy( PTR_SEG_TO_LIN(lParam
), s
, offset
);
234 iWndsLocks
= WIN_SuspendWndsLock();
236 args
= (WORD
*)THREAD_STACK16(teb
) - 5;
237 args
[0] = LOWORD(lParam
);
238 args
[1] = HIWORD(lParam
);
243 wine_call_to_16_regs_short( &context
, 5 * sizeof(WORD
) );
244 ret
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
245 if (offset
) stack16_pop( offset
);
247 WIN_RestoreWndsLock(iWndsLocks
);
253 /**********************************************************************
256 * Return a pointer to the win proc.
258 static WINDOWPROC
*WINPROC_GetPtr( WNDPROC16 handle
)
263 /* ptr cannot be < 64K */
264 if (!HIWORD(handle
)) return NULL
;
266 /* Check for a linear pointer */
268 ptr
= (BYTE
*)handle
;
269 /* First check if it is the jmp address */
270 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->jmp
);
271 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
273 /* Now it must be the thunk address */
274 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
275 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
278 /* Check for a segmented pointer */
280 if (!IsBadReadPtr16( (SEGPTR
)handle
, sizeof(proc
->thunk
) ))
282 ptr
= (BYTE
*)PTR_SEG_TO_LIN(handle
);
283 /* It must be the thunk address */
284 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
285 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
293 /**********************************************************************
294 * WINPROC_AllocWinProc
296 * Allocate a new window procedure.
298 static WINDOWPROC
*WINPROC_AllocWinProc( WNDPROC16 func
, WINDOWPROCTYPE type
,
299 WINDOWPROCUSER user
)
301 WINDOWPROC
*proc
, *oldproc
;
303 /* Allocate a window procedure */
305 if (!(proc
= HeapAlloc( WinProcHeap
, 0, sizeof(WINDOWPROC
) ))) return 0;
307 /* Check if the function is already a win proc */
309 if ((oldproc
= WINPROC_GetPtr( func
)))
318 proc
->thunk
.t_from32
.popl_eax
= 0x58; /* popl %eax */
319 proc
->thunk
.t_from32
.pushl_func
= 0x68; /* pushl $proc */
320 proc
->thunk
.t_from32
.proc
= func
;
321 proc
->thunk
.t_from32
.pushl_eax
= 0x50; /* pushl %eax */
322 proc
->thunk
.t_from32
.jmp
= 0xe9; /* jmp relay*/
323 proc
->thunk
.t_from32
.relay
= /* relative jump */
324 (void(*)())((DWORD
)WINPROC_CallProc32ATo16
-
325 (DWORD
)(&proc
->thunk
.t_from32
.relay
+ 1));
329 proc
->thunk
.t_from16
.pushw_bp
= 0x5566; /* pushw %bp */
330 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
331 proc
->thunk
.t_from16
.proc
= (FARPROC
)func
;
332 proc
->thunk
.t_from16
.pushw_ax
= 0x5066; /* pushw %ax */
333 proc
->thunk
.t_from16
.pushl_relay
= 0x68; /* pushl $relay */
334 proc
->thunk
.t_from16
.relay
= (type
== WIN_PROC_32A
) ?
335 (void(*)())WINPROC_Thunk16To32A
:
336 (void(*)())WINPROC_Thunk16To32W
;
337 proc
->thunk
.t_from16
.lcall
= 0x9a; /* lcall cs:glue */
338 proc
->thunk
.t_from16
.glue
= (void*)__wine_call_from_16_long
;
339 proc
->thunk
.t_from16
.cs
= __get_cs();
340 proc
->thunk
.t_from16
.lret
= 0xca66;
341 proc
->thunk
.t_from16
.nArgs
= 10;
342 proc
->jmp
.jmp
= 0xe9;
343 /* Fixup relative jump */
344 proc
->jmp
.proc
= (WNDPROC
)((DWORD
)func
-
345 (DWORD
)(&proc
->jmp
.proc
+ 1));
348 /* Should not happen */
351 proc
->magic
= WINPROC_MAGIC
;
356 TRACE_(win
)("(%08x,%d): returning %08x\n",
357 (UINT
)func
, type
, (UINT
)proc
);
362 /**********************************************************************
365 * Get a window procedure pointer that can be passed to the Windows program.
367 WNDPROC16
WINPROC_GetProc( HWINDOWPROC proc
, WINDOWPROCTYPE type
)
369 if (!proc
) return NULL
;
370 if (type
== WIN_PROC_16
) /* We want a 16:16 address */
372 if (((WINDOWPROC
*)proc
)->type
== WIN_PROC_16
)
373 return ((WINDOWPROC
*)proc
)->thunk
.t_from32
.proc
;
375 return (WNDPROC16
)HEAP_GetSegptr( WinProcHeap
, 0,
376 &((WINDOWPROC
*)proc
)->thunk
);
378 else /* We want a 32-bit address */
380 if (((WINDOWPROC
*)proc
)->type
== WIN_PROC_16
)
381 return (WNDPROC16
)&((WINDOWPROC
*)proc
)->thunk
;
382 else if (type
!= ((WINDOWPROC
*)proc
)->type
)
383 /* Have to return the jmp address if types don't match */
384 return (WNDPROC16
)&((WINDOWPROC
*)proc
)->jmp
;
386 /* Some Win16 programs want to get back the proc they set */
387 return (WNDPROC16
)((WINDOWPROC
*)proc
)->thunk
.t_from16
.proc
;
392 /**********************************************************************
395 * Set the window procedure for a window or class. There are
396 * three tree classes of winproc callbacks:
398 * 1) class -> wp - not subclassed
399 * class -> wp -> wp -> wp -> wp - SetClassLong()
401 * 2) window -' / - not subclassed
402 * window -> wp -> wp ' - SetWindowLong()
404 * 3) timer -> wp - SetTimer()
406 * Initially, winproc of the window points to the current winproc
407 * thunk of its class. Subclassing prepends a new thunk to the
408 * window winproc chain at the head of the list. Thus, window thunk
409 * list includes class thunks and the latter are preserved when the
410 * window is destroyed.
413 BOOL
WINPROC_SetProc( HWINDOWPROC
*pFirst
, WNDPROC16 func
,
414 WINDOWPROCTYPE type
, WINDOWPROCUSER user
)
416 BOOL bRecycle
= FALSE
;
417 WINDOWPROC
*proc
, **ppPrev
;
419 /* Check if function is already in the list */
421 ppPrev
= (WINDOWPROC
**)pFirst
;
422 proc
= WINPROC_GetPtr( func
);
429 if ((*ppPrev
)->user
!= user
)
431 /* terminal thunk is being restored */
433 WINPROC_FreeProc( *pFirst
, (*ppPrev
)->user
);
434 *(WINDOWPROC
**)pFirst
= *ppPrev
;
443 if (((*ppPrev
)->type
== type
) &&
444 (func
== WINPROC_THUNKPROC(*ppPrev
)))
451 /* WPF_CLASS thunk terminates window thunk list */
452 if ((*ppPrev
)->user
!= user
) break;
453 ppPrev
= &(*ppPrev
)->next
;
458 /* Extract this thunk from the list */
460 *ppPrev
= proc
->next
;
462 else /* Allocate a new one */
464 if (proc
) /* Was already a win proc */
467 func
= WINPROC_THUNKPROC(proc
);
469 proc
= WINPROC_AllocWinProc( func
, type
, user
);
470 if (!proc
) return FALSE
;
473 /* Add the win proc at the head of the list */
475 TRACE_(win
)("(%08x,%08x,%d): res=%08x\n",
476 (UINT
)*pFirst
, (UINT
)func
, type
, (UINT
)proc
);
477 proc
->next
= *(WINDOWPROC
**)pFirst
;
478 *(WINDOWPROC
**)pFirst
= proc
;
483 /**********************************************************************
486 * Free a list of win procs.
488 void WINPROC_FreeProc( HWINDOWPROC proc
, WINDOWPROCUSER user
)
492 WINDOWPROC
*next
= ((WINDOWPROC
*)proc
)->next
;
493 if (((WINDOWPROC
*)proc
)->user
!= user
) break;
494 TRACE_(win
)("freeing %08x\n", (UINT
)proc
);
495 HeapFree( WinProcHeap
, 0, proc
);
501 /**********************************************************************
502 * WINPROC_GetProcType
504 * Return the window procedure type.
506 WINDOWPROCTYPE
WINPROC_GetProcType( HWINDOWPROC proc
)
509 (((WINDOWPROC
*)proc
)->magic
!= WINPROC_MAGIC
))
510 return WIN_PROC_INVALID
;
511 return ((WINDOWPROC
*)proc
)->type
;
513 /**********************************************************************
514 * WINPROC_TestCBForStr
516 * Return TRUE if the lparam is a string
518 static BOOL
WINPROC_TestCBForStr ( HWND hwnd
)
521 WND
* wnd
= WIN_FindWndPtr(hwnd
);
522 retvalue
= ( !(LOWORD(wnd
->dwStyle
) & (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) ||
523 (LOWORD(wnd
->dwStyle
) & CBS_HASSTRINGS
) );
524 WIN_ReleaseWndPtr(wnd
);
527 /**********************************************************************
528 * WINPROC_TestLBForStr
530 * Return TRUE if the lparam is a string
532 static BOOL
WINPROC_TestLBForStr ( HWND hwnd
)
535 WND
* wnd
= WIN_FindWndPtr(hwnd
);
536 retvalue
= ( !(LOWORD(wnd
->dwStyle
) & (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) ||
537 (LOWORD(wnd
->dwStyle
) & LBS_HASSTRINGS
) );
538 WIN_ReleaseWndPtr(wnd
);
542 /**********************************************************************
543 * WINPROC_MapMsg32ATo32W
545 * Map a message from Ansi to Unicode.
546 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
549 * WM_CHARTOITEM, WM_MENUCHAR
552 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
553 * the first four bytes are the handle of the icon
554 * when the WM_SETTEXT message has been used to set the icon
556 INT
WINPROC_MapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
562 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
563 *pwparam
* sizeof(WCHAR
) + sizeof(LPARAM
) );
565 *ptr
++ = *plparam
; /* Store previous lParam */
566 *plparam
= (LPARAM
)ptr
;
569 /* lparam is string (0-terminated) */
571 case WM_WININICHANGE
:
574 case CB_FINDSTRINGEXACT
:
575 case CB_SELECTSTRING
:
579 case LB_SELECTSTRING
:
581 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
582 return (*plparam
? 1 : -1);
588 { CREATESTRUCTW cs
; /* new structure */
589 LPCWSTR lpszName
; /* allocated Name */
590 LPCWSTR lpszClass
; /* allocated Class */
593 struct s
*xs
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct s
));
595 xs
->cs
= *(CREATESTRUCTW
*)*plparam
;
596 if (HIWORD(xs
->cs
.lpszName
))
597 xs
->lpszName
= xs
->cs
.lpszName
= HEAP_strdupAtoW( GetProcessHeap(), 0,
598 (LPCSTR
)xs
->cs
.lpszName
);
599 if (HIWORD(xs
->cs
.lpszClass
))
600 xs
->lpszClass
= xs
->cs
.lpszClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
601 (LPCSTR
)xs
->cs
.lpszClass
);
602 *plparam
= (LPARAM
)xs
;
607 MDICREATESTRUCTW
*cs
=
608 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
610 *cs
= *(MDICREATESTRUCTW
*)*plparam
;
611 if (HIWORD(cs
->szClass
))
612 cs
->szClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
613 (LPCSTR
)cs
->szClass
);
614 if (HIWORD(cs
->szTitle
))
615 cs
->szTitle
= HEAP_strdupAtoW( GetProcessHeap(), 0,
616 (LPCSTR
)cs
->szTitle
);
617 *plparam
= (LPARAM
)cs
;
623 case LB_INSERTSTRING
:
624 if ( WINPROC_TestLBForStr( hwnd
))
625 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
626 return (*plparam
? 1 : -1);
628 case LB_GETTEXT
: /* fixme: fixed sized buffer */
629 { if ( WINPROC_TestLBForStr( hwnd
))
630 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
632 *ptr
++ = *plparam
; /* Store previous lParam */
633 *plparam
= (LPARAM
)ptr
;
640 case CB_INSERTSTRING
:
641 if ( WINPROC_TestCBForStr( hwnd
))
642 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
643 return (*plparam
? 1 : -1);
645 case CB_GETLBTEXT
: /* fixme: fixed sized buffer */
646 { if ( WINPROC_TestCBForStr( hwnd
))
647 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
649 *ptr
++ = *plparam
; /* Store previous lParam */
650 *plparam
= (LPARAM
)ptr
;
657 { WORD len
= (WORD
)*plparam
;
658 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(WCHAR
) );
660 *ptr
++ = *plparam
; /* Store previous lParam */
661 *((WORD
*) ptr
) = len
; /* Store the length */
662 *plparam
= (LPARAM
)ptr
;
670 case EM_SETPASSWORDCHAR
:
674 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wch
, 1);
679 case WM_ASKCBFORMATNAME
:
680 case WM_DEVMODECHANGE
:
681 case WM_PAINTCLIPBOARD
:
682 case WM_SIZECLIPBOARD
:
683 FIXME_(msg
)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg
), msg
);
685 default: /* No translation needed */
691 /**********************************************************************
692 * WINPROC_UnmapMsg32ATo32W
694 * Unmap a message that was mapped from Ansi to Unicode.
696 void WINPROC_UnmapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
702 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
703 if (wParam
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
704 (LPSTR
)*ptr
, wParam
, NULL
, NULL
))
705 ((LPSTR
)*ptr
)[wParam
-1] = 0;
706 HeapFree( GetProcessHeap(), 0, ptr
);
714 { CREATESTRUCTW cs
; /* new structure */
715 LPWSTR lpszName
; /* allocated Name */
716 LPWSTR lpszClass
; /* allocated Class */
718 struct s
*xs
= (struct s
*)lParam
;
719 if (xs
->lpszName
) HeapFree( GetProcessHeap(), 0, xs
->lpszName
);
720 if (xs
->lpszClass
) HeapFree( GetProcessHeap(), 0, xs
->lpszClass
);
721 HeapFree( GetProcessHeap(), 0, xs
);
727 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
728 if (HIWORD(cs
->szTitle
))
729 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
730 if (HIWORD(cs
->szClass
))
731 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
732 HeapFree( GetProcessHeap(), 0, cs
);
737 case WM_WININICHANGE
:
740 case CB_FINDSTRINGEXACT
:
741 case CB_SELECTSTRING
:
745 case LB_SELECTSTRING
:
747 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
752 case LB_INSERTSTRING
:
753 if ( WINPROC_TestLBForStr( hwnd
))
754 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
758 { if ( WINPROC_TestLBForStr( hwnd
))
759 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
760 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
761 HeapFree( GetProcessHeap(), 0, ptr
);
768 case CB_INSERTSTRING
:
769 if ( WINPROC_TestCBForStr( hwnd
))
770 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
774 { if ( WINPROC_TestCBForStr( hwnd
))
775 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
776 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
777 HeapFree( GetProcessHeap(), 0, ptr
);
784 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lParam */
785 WORD len
= *(WORD
*) lParam
;
786 if (len
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
787 (LPSTR
)*ptr
, len
, NULL
, NULL
))
788 ((LPSTR
)*ptr
)[len
-1] = 0;
789 HeapFree( GetProcessHeap(), 0, ptr
);
796 /**********************************************************************
797 * WINPROC_MapMsg32WTo32A
799 * Map a message from Unicode to Ansi.
800 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
802 INT
WINPROC_MapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
808 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
809 *pwparam
+ sizeof(LPARAM
) );
811 *ptr
++ = *plparam
; /* Store previous lParam */
812 *plparam
= (LPARAM
)ptr
;
817 case WM_WININICHANGE
:
820 case CB_FINDSTRINGEXACT
:
821 case CB_SELECTSTRING
:
825 case LB_SELECTSTRING
:
827 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
828 return (*plparam
? 1 : -1);
833 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
836 *cs
= *(CREATESTRUCTA
*)*plparam
;
837 if (HIWORD(cs
->lpszName
))
838 cs
->lpszName
= HEAP_strdupWtoA( GetProcessHeap(), 0,
839 (LPCWSTR
)cs
->lpszName
);
840 if (HIWORD(cs
->lpszClass
))
841 cs
->lpszClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
842 (LPCWSTR
)cs
->lpszClass
);
843 *plparam
= (LPARAM
)cs
;
848 MDICREATESTRUCTA
*cs
=
849 (MDICREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
851 *cs
= *(MDICREATESTRUCTA
*)*plparam
;
852 if (HIWORD(cs
->szTitle
))
853 cs
->szTitle
= HEAP_strdupWtoA( GetProcessHeap(), 0,
854 (LPCWSTR
)cs
->szTitle
);
855 if (HIWORD(cs
->szClass
))
856 cs
->szClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
857 (LPCWSTR
)cs
->szClass
);
858 *plparam
= (LPARAM
)cs
;
864 case LB_INSERTSTRING
:
865 if ( WINPROC_TestLBForStr( hwnd
))
866 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
867 return (*plparam
? 1 : -1);
869 case LB_GETTEXT
: /* fixme: fixed sized buffer */
870 { if ( WINPROC_TestLBForStr( hwnd
))
871 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
873 *ptr
++ = *plparam
; /* Store previous lParam */
874 *plparam
= (LPARAM
)ptr
;
881 case CB_INSERTSTRING
:
882 if ( WINPROC_TestCBForStr( hwnd
))
883 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
884 return (*plparam
? 1 : -1);
886 case CB_GETLBTEXT
: /* fixme: fixed sized buffer */
887 { if ( WINPROC_TestCBForStr( hwnd
))
888 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
890 *ptr
++ = *plparam
; /* Store previous lParam */
891 *plparam
= (LPARAM
)ptr
;
898 { WORD len
= (WORD
)*plparam
;
899 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(CHAR
) );
901 *ptr
++ = *plparam
; /* Store previous lParam */
902 *((WORD
*) ptr
) = len
; /* Store the length */
903 *plparam
= (LPARAM
)ptr
;
911 case EM_SETPASSWORDCHAR
:
913 WCHAR wch
= *pwparam
;
915 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
920 case WM_ASKCBFORMATNAME
:
921 case WM_DEVMODECHANGE
:
922 case WM_PAINTCLIPBOARD
:
923 case WM_SIZECLIPBOARD
:
924 FIXME_(msg
)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg
),msg
);
926 default: /* No translation needed */
932 /**********************************************************************
933 * WINPROC_UnmapMsg32WTo32A
935 * Unmap a message that was mapped from Unicode to Ansi.
937 void WINPROC_UnmapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
943 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
946 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, wParam
))
947 ((LPWSTR
)*ptr
)[wParam
-1] = 0;
949 HeapFree( GetProcessHeap(), 0, ptr
);
954 case WM_WININICHANGE
:
957 case CB_FINDSTRINGEXACT
:
958 case CB_SELECTSTRING
:
962 case LB_SELECTSTRING
:
964 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
970 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
971 if (HIWORD(cs
->lpszName
))
972 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszName
);
973 if (HIWORD(cs
->lpszClass
))
974 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszClass
);
975 HeapFree( GetProcessHeap(), 0, cs
);
981 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
982 if (HIWORD(cs
->szTitle
))
983 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
984 if (HIWORD(cs
->szClass
))
985 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
986 HeapFree( GetProcessHeap(), 0, cs
);
992 case LB_INSERTSTRING
:
993 if ( WINPROC_TestLBForStr( hwnd
))
994 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
998 if ( WINPROC_TestLBForStr( hwnd
))
1000 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1001 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1002 HeapFree( GetProcessHeap(), 0, ptr
);
1008 case CB_INSERTSTRING
:
1009 if ( WINPROC_TestCBForStr( hwnd
))
1010 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1014 if ( WINPROC_TestCBForStr( hwnd
))
1016 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1017 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1018 HeapFree( GetProcessHeap(), 0, ptr
);
1022 /* Multiline edit */
1024 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lparam */
1025 WORD len
= *(WORD
*)ptr
;
1028 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, len
))
1029 ((LPWSTR
)*ptr
)[len
-1] = 0;
1031 HeapFree( GetProcessHeap(), 0, ptr
);
1038 /**********************************************************************
1039 * WINPROC_MapMsg16To32A
1041 * Map a message from 16- to 32-bit Ansi.
1042 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1044 INT
WINPROC_MapMsg16To32A( UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1045 WPARAM
*pwparam32
, LPARAM
*plparam
)
1047 *pmsg32
= (UINT
)msg16
;
1048 *pwparam32
= (WPARAM
)wParam16
;
1055 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1056 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
1060 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1061 *plparam
= (LPARAM
)(HWND
)HIWORD(*plparam
);
1064 if ( HIWORD(*plparam
) > CTLCOLOR_STATIC
) return -1;
1065 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
1066 *pwparam32
= (WPARAM
)(HDC
)wParam16
;
1067 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
1069 case WM_COMPAREITEM
:
1071 COMPAREITEMSTRUCT16
* cis16
= (COMPAREITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1072 COMPAREITEMSTRUCT
*cis
= (COMPAREITEMSTRUCT
*)
1073 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis
));
1074 if (!cis
) return -1;
1075 cis
->CtlType
= cis16
->CtlType
;
1076 cis
->CtlID
= cis16
->CtlID
;
1077 cis
->hwndItem
= cis16
->hwndItem
;
1078 cis
->itemID1
= cis16
->itemID1
;
1079 cis
->itemData1
= cis16
->itemData1
;
1080 cis
->itemID2
= cis16
->itemID2
;
1081 cis
->itemData2
= cis16
->itemData2
;
1082 cis
->dwLocaleId
= 0; /* FIXME */
1083 *plparam
= (LPARAM
)cis
;
1088 DELETEITEMSTRUCT16
* dis16
= (DELETEITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1089 DELETEITEMSTRUCT
*dis
= (DELETEITEMSTRUCT
*)
1090 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis
));
1091 if (!dis
) return -1;
1092 dis
->CtlType
= dis16
->CtlType
;
1093 dis
->CtlID
= dis16
->CtlID
;
1094 dis
->hwndItem
= dis16
->hwndItem
;
1095 dis
->itemData
= dis16
->itemData
;
1096 *plparam
= (LPARAM
)dis
;
1099 case WM_MEASUREITEM
:
1101 MEASUREITEMSTRUCT16
* mis16
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1102 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)
1103 HeapAlloc(GetProcessHeap(), 0,
1104 sizeof(*mis
) + sizeof(LPARAM
));
1105 if (!mis
) return -1;
1106 mis
->CtlType
= mis16
->CtlType
;
1107 mis
->CtlID
= mis16
->CtlID
;
1108 mis
->itemID
= mis16
->itemID
;
1109 mis
->itemWidth
= mis16
->itemWidth
;
1110 mis
->itemHeight
= mis16
->itemHeight
;
1111 mis
->itemData
= mis16
->itemData
;
1112 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1113 *plparam
= (LPARAM
)mis
;
1118 DRAWITEMSTRUCT16
* dis16
= (DRAWITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1119 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)HeapAlloc(GetProcessHeap(), 0,
1121 if (!dis
) return -1;
1122 dis
->CtlType
= dis16
->CtlType
;
1123 dis
->CtlID
= dis16
->CtlID
;
1124 dis
->itemID
= dis16
->itemID
;
1125 dis
->itemAction
= dis16
->itemAction
;
1126 dis
->itemState
= dis16
->itemState
;
1127 dis
->hwndItem
= dis16
->hwndItem
;
1128 dis
->hDC
= dis16
->hDC
;
1129 dis
->itemData
= dis16
->itemData
;
1130 CONV_RECT16TO32( &dis16
->rcItem
, &dis
->rcItem
);
1131 *plparam
= (LPARAM
)dis
;
1134 case WM_GETMINMAXINFO
:
1136 MINMAXINFO
*mmi
= (MINMAXINFO
*)HeapAlloc( GetProcessHeap(), 0,
1137 sizeof(*mmi
) + sizeof(LPARAM
));
1138 if (!mmi
) return -1;
1139 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16
*)PTR_SEG_TO_LIN(*plparam
),
1141 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1142 *plparam
= (LPARAM
)mmi
;
1147 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
1151 MDICREATESTRUCT16
*cs16
=
1152 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1153 MDICREATESTRUCTA
*cs
=
1154 (MDICREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
1155 sizeof(*cs
) + sizeof(LPARAM
) );
1157 STRUCT32_MDICREATESTRUCT16to32A( cs16
, cs
);
1158 cs
->szTitle
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->szTitle
);
1159 cs
->szClass
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->szClass
);
1160 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1161 *plparam
= (LPARAM
)cs
;
1164 case WM_MDIGETACTIVE
:
1165 *plparam
= (LPARAM
)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL
) );
1166 *(BOOL
*)(*plparam
) = 0;
1170 *pmsg32
=WM_MDIREFRESHMENU
;
1171 *pwparam32
= (WPARAM
)(HMENU
)LOWORD(*plparam
);
1172 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1175 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1176 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1179 if((LOWORD(*plparam
) & MF_POPUP
) && (LOWORD(*plparam
) != 0xFFFF))
1181 HMENU hmenu
=(HMENU
)HIWORD(*plparam
);
1182 UINT Pos
=MENU_FindSubMenu( &hmenu
, wParam16
);
1183 if(Pos
==0xFFFF) Pos
=0; /* NO_SELECTED_ITEM */
1184 *pwparam32
= MAKEWPARAM( Pos
, LOWORD(*plparam
) );
1186 else *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1187 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1189 case WM_MDIACTIVATE
:
1192 *pwparam32
= (WPARAM
)(HWND
)HIWORD(*plparam
);
1193 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
1195 else /* message sent to MDI client */
1196 *pwparam32
= wParam16
;
1200 NCCALCSIZE_PARAMS16
*nc16
;
1201 NCCALCSIZE_PARAMS
*nc
;
1203 nc
= (NCCALCSIZE_PARAMS
*)HeapAlloc( GetProcessHeap(), 0,
1204 sizeof(*nc
) + sizeof(LPARAM
) );
1206 nc16
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(*plparam
);
1207 CONV_RECT16TO32( &nc16
->rgrc
[0], &nc
->rgrc
[0] );
1210 nc
->lppos
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1211 sizeof(*nc
->lppos
) );
1212 CONV_RECT16TO32( &nc16
->rgrc
[1], &nc
->rgrc
[1] );
1213 CONV_RECT16TO32( &nc16
->rgrc
[2], &nc
->rgrc
[2] );
1214 if (nc
->lppos
) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc16
->lppos
), nc
->lppos
);
1216 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1217 *plparam
= (LPARAM
)nc
;
1223 CREATESTRUCT16
*cs16
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1224 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
1225 sizeof(*cs
) + sizeof(LPARAM
) );
1227 STRUCT32_CREATESTRUCT16to32A( cs16
, cs
);
1228 cs
->lpszName
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->lpszName
);
1229 cs
->lpszClass
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->lpszClass
);
1230 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1231 *plparam
= (LPARAM
)cs
;
1234 case WM_PARENTNOTIFY
:
1235 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
1237 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1238 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
1241 case WM_WINDOWPOSCHANGING
:
1242 case WM_WINDOWPOSCHANGED
:
1244 WINDOWPOS
*wp
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1245 sizeof(*wp
) + sizeof(LPARAM
) );
1247 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(*plparam
),
1249 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1250 *plparam
= (LPARAM
)wp
;
1256 LPMSG16 msg16
= (LPMSG16
)PTR_SEG_TO_LIN(*plparam
);
1257 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1259 if (!msg32
) return -1;
1260 msg32
->hwnd
= msg16
->hwnd
;
1261 msg32
->lParam
= msg16
->lParam
;
1262 msg32
->time
= msg16
->time
;
1263 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1264 /* this is right, right? */
1265 if (WINPROC_MapMsg16To32A(msg16
->message
,msg16
->wParam
,
1266 &msg32
->message
,&msg32
->wParam
,
1267 &msg32
->lParam
)<0) {
1268 HeapFree( GetProcessHeap(), 0, msg32
);
1271 *plparam
= (LPARAM
)msg32
;
1276 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
1278 case WM_ACTIVATEAPP
:
1280 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1281 a 32bit window. Might be superflous with 32bit interprocess
1284 HTASK16 htask
= (HTASK16
) *plparam
;
1285 DWORD idThread
= (DWORD
)((TDB
*)GlobalLock16(htask
))->teb
->tid
;
1286 *plparam
= (LPARAM
) idThread
;
1289 case WM_ASKCBFORMATNAME
:
1290 case WM_DEVMODECHANGE
:
1291 case WM_PAINTCLIPBOARD
:
1292 case WM_SIZECLIPBOARD
:
1293 case WM_WININICHANGE
:
1294 FIXME_(msg
)("message %04x needs translation\n",msg16
);
1297 default: /* No translation needed */
1303 /**********************************************************************
1304 * WINPROC_UnmapMsg16To32A
1306 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1308 LRESULT
WINPROC_UnmapMsg16To32A( HWND16 hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1313 case WM_COMPAREITEM
:
1316 HeapFree( GetProcessHeap(), 0, (LPVOID
)lParam
);
1318 case WM_MEASUREITEM
:
1320 MEASUREITEMSTRUCT16
*mis16
;
1321 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)lParam
;
1322 lParam
= *(LPARAM
*)(mis
+ 1);
1323 mis16
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
1324 mis16
->itemWidth
= (UINT16
)mis
->itemWidth
;
1325 mis16
->itemHeight
= (UINT16
)mis
->itemHeight
;
1326 HeapFree( GetProcessHeap(), 0, mis
);
1329 case WM_GETMINMAXINFO
:
1331 MINMAXINFO
*mmi
= (MINMAXINFO
*)lParam
;
1332 lParam
= *(LPARAM
*)(mmi
+ 1);
1333 STRUCT32_MINMAXINFO32to16( mmi
,
1334 (MINMAXINFO16
*)PTR_SEG_TO_LIN(lParam
));
1335 HeapFree( GetProcessHeap(), 0, mmi
);
1340 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1341 lParam
= *(LPARAM
*)(cs
+ 1);
1342 STRUCT32_MDICREATESTRUCT32Ato16( cs
,
1343 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1344 HeapFree( GetProcessHeap(), 0, cs
);
1347 case WM_MDIGETACTIVE
:
1348 result
= MAKELONG( LOWORD(result
), (BOOL16
)(*(BOOL
*)lParam
) );
1349 HeapFree( GetProcessHeap(), 0, (BOOL
*)lParam
);
1353 NCCALCSIZE_PARAMS16
*nc16
;
1354 NCCALCSIZE_PARAMS
*nc
= (NCCALCSIZE_PARAMS
*)lParam
;
1355 lParam
= *(LPARAM
*)(nc
+ 1);
1356 nc16
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(lParam
);
1357 CONV_RECT32TO16( &nc
->rgrc
[0], &nc16
->rgrc
[0] );
1360 CONV_RECT32TO16( &nc
->rgrc
[1], &nc16
->rgrc
[1] );
1361 CONV_RECT32TO16( &nc
->rgrc
[2], &nc16
->rgrc
[2] );
1364 STRUCT32_WINDOWPOS32to16( nc
->lppos
,
1365 (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc16
->lppos
));
1366 HeapFree( GetProcessHeap(), 0, nc
->lppos
);
1369 HeapFree( GetProcessHeap(), 0, nc
);
1375 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1376 lParam
= *(LPARAM
*)(cs
+ 1);
1377 STRUCT32_CREATESTRUCT32Ato16( cs
,
1378 (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1379 HeapFree( GetProcessHeap(), 0, cs
);
1382 case WM_WINDOWPOSCHANGING
:
1383 case WM_WINDOWPOSCHANGED
:
1385 WINDOWPOS
*wp
= (WINDOWPOS
*)lParam
;
1386 lParam
= *(LPARAM
*)(wp
+ 1);
1387 STRUCT32_WINDOWPOS32to16(wp
,(WINDOWPOS16
*)PTR_SEG_TO_LIN(lParam
));
1388 HeapFree( GetProcessHeap(), 0, wp
);
1394 LPMSG msg32
= (LPMSG
)lParam
;
1396 WINPROC_UnmapMsg16To32A( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1398 HeapFree( GetProcessHeap(), 0, msg32
);
1406 /**********************************************************************
1407 * WINPROC_MapMsg16To32W
1409 * Map a message from 16- to 32-bit Unicode.
1410 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1412 INT
WINPROC_MapMsg16To32W( HWND16 hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1413 WPARAM
*pwparam32
, LPARAM
*plparam
)
1415 *pmsg32
=(UINT
)msg16
;
1416 *pwparam32
= (WPARAM
)wParam16
;
1421 WORD len
= (WORD
)*plparam
;
1422 LPARAM
*ptr
= (LPARAM
*)HeapAlloc(GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof(WORD
) + len
* sizeof(WCHAR
));
1424 *ptr
++ = *plparam
; /* Store previous lParam */
1425 *((WORD
*)ptr
) = len
; /* Store the length */
1426 *plparam
= (LPARAM
)ptr
;
1430 case EM_REPLACESEL16
:
1434 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
1435 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)*plparam
, -1, NULL
, 0);
1436 str
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1438 MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)*plparam
, -1, str
, len
);
1439 *plparam
= (LPARAM
)str
;
1445 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
1446 return WINPROC_MapMsg32ATo32W( hwnd
, *pmsg32
, pwparam32
, plparam
);
1450 CREATESTRUCT16
*cs16
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1451 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1452 sizeof(*cs
) + sizeof(LPARAM
) );
1454 STRUCT32_CREATESTRUCT16to32A( cs16
, (CREATESTRUCTA
*)cs
);
1455 cs
->lpszName
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->lpszName
);
1456 cs
->lpszClass
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->lpszClass
);
1457 if (HIWORD(cs
->lpszName
))
1458 cs
->lpszName
= HEAP_strdupAtoW( GetProcessHeap(), 0,
1459 (LPCSTR
)cs
->lpszName
);
1460 if (HIWORD(cs
->lpszClass
))
1461 cs
->lpszClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
1462 (LPCSTR
)cs
->lpszClass
);
1463 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1464 *plparam
= (LPARAM
)cs
;
1469 MDICREATESTRUCT16
*cs16
=
1470 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1471 MDICREATESTRUCTW
*cs
=
1472 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1473 sizeof(*cs
) + sizeof(LPARAM
) );
1475 STRUCT32_MDICREATESTRUCT16to32A( cs16
, (MDICREATESTRUCTA
*)cs
);
1476 cs
->szTitle
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->szTitle
);
1477 cs
->szClass
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->szClass
);
1478 if (HIWORD(cs
->szTitle
))
1479 cs
->szTitle
= HEAP_strdupAtoW( GetProcessHeap(), 0,
1480 (LPCSTR
)cs
->szTitle
);
1481 if (HIWORD(cs
->szClass
))
1482 cs
->szClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
1483 (LPCSTR
)cs
->szClass
);
1484 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1485 *plparam
= (LPARAM
)cs
;
1491 LPMSG16 msg16
= (LPMSG16
)PTR_SEG_TO_LIN(*plparam
);
1492 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1494 if (!msg32
) return -1;
1495 msg32
->hwnd
= msg16
->hwnd
;
1496 msg32
->lParam
= msg16
->lParam
;
1497 msg32
->time
= msg16
->time
;
1498 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1499 /* this is right, right? */
1500 if (WINPROC_MapMsg16To32W(hwnd
, msg16
->message
,msg16
->wParam
,
1501 &msg32
->message
,&msg32
->wParam
,
1502 &msg32
->lParam
)<0) {
1503 HeapFree( GetProcessHeap(), 0, msg32
);
1506 *plparam
= (LPARAM
)msg32
;
1514 case WM_SYSDEADCHAR
:
1515 case EM_SETPASSWORDCHAR16
:
1519 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1524 default: /* No Unicode translation needed */
1525 return WINPROC_MapMsg16To32A( msg16
, wParam16
, pmsg32
,
1526 pwparam32
, plparam
);
1531 /**********************************************************************
1532 * WINPROC_UnmapMsg16To32W
1534 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1536 LRESULT
WINPROC_UnmapMsg16To32W( HWND16 hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1543 LPARAM
*ptr
= (LPARAM
*)lParam
- 1; /* get the old lParam */
1544 WORD len
= *(WORD
*)lParam
;
1545 *ptr
= (LPARAM
)PTR_SEG_TO_LIN(*ptr
);
1546 if(len
> 0 && !WideCharToMultiByte(CP_ACP
, 0, (LPWSTR
)lParam
, -1,
1547 (LPSTR
)*ptr
, len
, NULL
, NULL
))
1548 ((LPSTR
)*ptr
)[len
-1] = 0;
1549 HeapFree(GetProcessHeap(), 0, ptr
);
1553 case EM_REPLACESEL16
:
1554 HeapFree(GetProcessHeap(), 0, (void *)lParam
);
1559 WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
);
1564 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)lParam
;
1565 lParam
= *(LPARAM
*)(cs
+ 1);
1566 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs
,
1567 (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1568 if (HIWORD(cs
->lpszName
))
1569 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszName
);
1570 if (HIWORD(cs
->lpszClass
))
1571 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszClass
);
1572 HeapFree( GetProcessHeap(), 0, cs
);
1577 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
1578 lParam
= *(LPARAM
*)(cs
+ 1);
1579 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs
,
1580 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1581 if (HIWORD(cs
->szTitle
))
1582 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
1583 if (HIWORD(cs
->szClass
))
1584 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
1585 HeapFree( GetProcessHeap(), 0, cs
);
1591 LPMSG msg32
= (LPMSG
)lParam
;
1593 WINPROC_UnmapMsg16To32W( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1595 HeapFree( GetProcessHeap(), 0, msg32
);
1599 return WINPROC_UnmapMsg16To32A( hwnd
, msg
, wParam
, lParam
, result
);
1605 /**********************************************************************
1606 * WINPROC_MapMsg32ATo16
1608 * Map a message from 32-bit Ansi to 16-bit.
1609 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1611 INT
WINPROC_MapMsg32ATo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
1612 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
1615 *pmsg16
= (UINT16
)msg32
;
1616 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1624 *pmsg16
= (UINT16
)msg32
+ (BM_GETCHECK16
- BM_GETCHECK
);
1633 case EM_SCROLLCARET
:
1636 case EM_GETLINECOUNT
:
1648 case EM_LINEFROMCHAR
:
1649 case EM_SETTABSTOPS
:
1650 case EM_SETPASSWORDCHAR
:
1651 case EM_EMPTYUNDOBUFFER
:
1652 case EM_GETFIRSTVISIBLELINE
:
1653 case EM_SETREADONLY
:
1654 case EM_SETWORDBREAKPROC
:
1655 case EM_GETWORDBREAKPROC
:
1656 case EM_GETPASSWORDCHAR
:
1657 *pmsg16
= (UINT16
)msg32
+ (EM_GETSEL16
- EM_GETSEL
);
1662 case LB_DELETESTRING
:
1663 case LB_GETANCHORINDEX
:
1664 case LB_GETCARETINDEX
:
1667 case LB_GETHORIZONTALEXTENT
:
1668 case LB_GETITEMDATA
:
1669 case LB_GETITEMHEIGHT
:
1671 case LB_GETSELCOUNT
:
1673 case LB_GETTOPINDEX
:
1674 case LB_RESETCONTENT
:
1675 case LB_SELITEMRANGE
:
1676 case LB_SELITEMRANGEEX
:
1677 case LB_SETANCHORINDEX
:
1678 case LB_SETCARETINDEX
:
1679 case LB_SETCOLUMNWIDTH
:
1681 case LB_SETHORIZONTALEXTENT
:
1682 case LB_SETITEMDATA
:
1683 case LB_SETITEMHEIGHT
:
1685 case LB_SETTOPINDEX
:
1686 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1688 case CB_DELETESTRING
:
1690 case CB_GETLBTEXTLEN
:
1692 case CB_RESETCONTENT
:
1696 case CB_SHOWDROPDOWN
:
1697 case CB_SETITEMDATA
:
1698 case CB_SETITEMHEIGHT
:
1699 case CB_GETITEMHEIGHT
:
1700 case CB_SETEXTENDEDUI
:
1701 case CB_GETEXTENDEDUI
:
1702 case CB_GETDROPPEDSTATE
:
1703 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1706 *pmsg16
= CB_GETEDITSEL16
;
1711 case LB_FINDSTRINGEXACT
:
1712 case LB_INSERTSTRING
:
1713 case LB_SELECTSTRING
:
1717 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
1718 if (!str
) return -1;
1719 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1721 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1726 case CB_FINDSTRINGEXACT
:
1727 case CB_INSERTSTRING
:
1728 case CB_SELECTSTRING
:
1731 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
1732 if (!str
) return -1;
1733 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1735 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1738 case LB_GETITEMRECT
:
1741 rect
= (RECT16
*)SEGPTR_ALLOC( sizeof(RECT16
) + sizeof(LPARAM
) );
1742 if (!rect
) return -1;
1743 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1744 *plparam
= (LPARAM
)SEGPTR_GET(rect
);
1746 *pmsg16
= LB_GETITEMRECT16
;
1748 case LB_GETSELITEMS
:
1751 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1752 if (!(items
= SEGPTR_ALLOC( *pwparam16
* sizeof(INT16
)
1753 + sizeof(LPARAM
)))) return -1;
1754 *((LPARAM
*)items
)++ = *plparam
; /* Store the previous lParam */
1755 *plparam
= (LPARAM
)SEGPTR_GET(items
);
1757 *pmsg16
= LB_GETSELITEMS16
;
1759 case LB_SETTABSTOPS
:
1764 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1765 if (!(stops
= SEGPTR_ALLOC( *pwparam16
* sizeof(INT16
)
1766 + sizeof(LPARAM
)))) return -1;
1767 for (i
= 0; i
< *pwparam16
; i
++) stops
[i
] = *((LPINT
)*plparam
+i
);
1768 *plparam
= (LPARAM
)SEGPTR_GET(stops
);
1771 *pmsg16
= LB_SETTABSTOPS16
;
1774 case CB_GETDROPPEDCONTROLRECT
:
1777 rect
= (RECT16
*)SEGPTR_ALLOC( sizeof(RECT16
) + sizeof(LPARAM
) );
1778 if (!rect
) return -1;
1779 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1780 *plparam
= (LPARAM
)SEGPTR_GET(rect
);
1782 *pmsg16
= CB_GETDROPPEDCONTROLRECT16
;
1786 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1787 *pmsg16
= LB_GETTEXT16
;
1791 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1792 *pmsg16
= CB_GETLBTEXT16
;
1797 *plparam
= MAKELONG( (INT16
)(INT
)wParam32
, (INT16
)*plparam
);
1798 *pmsg16
= EM_SETSEL16
;
1805 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
1809 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
1811 case WM_CTLCOLORMSGBOX
:
1812 case WM_CTLCOLOREDIT
:
1813 case WM_CTLCOLORLISTBOX
:
1814 case WM_CTLCOLORBTN
:
1815 case WM_CTLCOLORDLG
:
1816 case WM_CTLCOLORSCROLLBAR
:
1817 case WM_CTLCOLORSTATIC
:
1818 *pmsg16
= WM_CTLCOLOR
;
1819 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
1820 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
1822 case WM_COMPAREITEM
:
1824 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)*plparam
;
1825 COMPAREITEMSTRUCT16
*cis
= SEGPTR_NEW(COMPAREITEMSTRUCT16
);
1826 if (!cis
) return -1;
1827 cis
->CtlType
= (UINT16
)cis32
->CtlType
;
1828 cis
->CtlID
= (UINT16
)cis32
->CtlID
;
1829 cis
->hwndItem
= (HWND16
)cis32
->hwndItem
;
1830 cis
->itemID1
= (UINT16
)cis32
->itemID1
;
1831 cis
->itemData1
= cis32
->itemData1
;
1832 cis
->itemID2
= (UINT16
)cis32
->itemID2
;
1833 cis
->itemData2
= cis32
->itemData2
;
1834 *plparam
= (LPARAM
)SEGPTR_GET(cis
);
1839 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)*plparam
;
1840 DELETEITEMSTRUCT16
*dis
= SEGPTR_NEW(DELETEITEMSTRUCT16
);
1841 if (!dis
) return -1;
1842 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1843 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1844 dis
->itemID
= (UINT16
)dis32
->itemID
;
1845 dis
->hwndItem
= (HWND16
)dis32
->hwndItem
;
1846 dis
->itemData
= dis32
->itemData
;
1847 *plparam
= (LPARAM
)SEGPTR_GET(dis
);
1852 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)*plparam
;
1853 DRAWITEMSTRUCT16
*dis
= SEGPTR_NEW(DRAWITEMSTRUCT16
);
1854 if (!dis
) return -1;
1855 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1856 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1857 dis
->itemID
= (UINT16
)dis32
->itemID
;
1858 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
1859 dis
->itemState
= (UINT16
)dis32
->itemState
;
1860 dis
->hwndItem
= (HWND16
)dis32
->hwndItem
;
1861 dis
->hDC
= (HDC16
)dis32
->hDC
;
1862 dis
->itemData
= dis32
->itemData
;
1863 CONV_RECT32TO16( &dis32
->rcItem
, &dis
->rcItem
);
1864 *plparam
= (LPARAM
)SEGPTR_GET(dis
);
1867 case WM_MEASUREITEM
:
1869 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)*plparam
;
1870 MEASUREITEMSTRUCT16
*mis
= (MEASUREITEMSTRUCT16
*)
1871 SEGPTR_ALLOC(sizeof(*mis
)+sizeof(LPARAM
));
1872 if (!mis
) return -1;
1873 mis
->CtlType
= (UINT16
)mis32
->CtlType
;
1874 mis
->CtlID
= (UINT16
)mis32
->CtlID
;
1875 mis
->itemID
= (UINT16
)mis32
->itemID
;
1876 mis
->itemWidth
= (UINT16
)mis32
->itemWidth
;
1877 mis
->itemHeight
= (UINT16
)mis32
->itemHeight
;
1878 mis
->itemData
= mis32
->itemData
;
1879 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1880 *plparam
= (LPARAM
)SEGPTR_GET(mis
);
1883 case WM_GETMINMAXINFO
:
1885 MINMAXINFO16
*mmi
= (MINMAXINFO16
*)SEGPTR_ALLOC( sizeof(*mmi
) +
1887 if (!mmi
) return -1;
1888 STRUCT32_MINMAXINFO32to16( (MINMAXINFO
*)*plparam
, mmi
);
1889 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1890 *plparam
= (LPARAM
)SEGPTR_GET(mmi
);
1896 *pwparam16
= (WPARAM16
)min( wParam32
, 0xff80 ); /* Must be < 64K */
1897 if (!(str
= SEGPTR_ALLOC(*pwparam16
+ sizeof(LPARAM
)))) return -1;
1898 *((LPARAM
*)str
)++ = *plparam
; /* Store the previous lParam */
1899 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1904 MDICREATESTRUCT16
*cs
;
1905 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)*plparam
;
1908 if (!(cs
= SEGPTR_NEW(MDICREATESTRUCT16
))) return -1;
1909 STRUCT32_MDICREATESTRUCT32Ato16( cs32
, cs
);
1910 name
= SEGPTR_STRDUP( cs32
->szTitle
);
1911 cls
= SEGPTR_STRDUP( cs32
->szClass
);
1912 cs
->szTitle
= SEGPTR_GET(name
);
1913 cs
->szClass
= SEGPTR_GET(cls
);
1914 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
1917 case WM_MDIGETACTIVE
:
1920 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
1921 (HMENU16
)LOWORD(*plparam
) );
1922 *pwparam16
= (*plparam
== 0);
1925 if(HIWORD(wParam32
) & MF_POPUP
)
1928 if (((UINT
)HIWORD(wParam32
) != 0xFFFF) || (*plparam
))
1930 if((hmenu
= GetSubMenu((HMENU16
)*plparam
, *pwparam16
)))
1936 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
1938 case WM_MDIACTIVATE
:
1939 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
1941 *pwparam16
= ((HWND
)*plparam
== hwnd
);
1942 *plparam
= MAKELPARAM( (HWND16
)LOWORD(*plparam
),
1943 (HWND16
)LOWORD(wParam32
) );
1947 *pwparam16
= (HWND
)wParam32
;
1953 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)*plparam
;
1954 NCCALCSIZE_PARAMS16
*nc
= (NCCALCSIZE_PARAMS16
*)SEGPTR_ALLOC( sizeof(*nc
) + sizeof(LPARAM
) );
1957 CONV_RECT32TO16( &nc32
->rgrc
[0], &nc
->rgrc
[0] );
1961 CONV_RECT32TO16( &nc32
->rgrc
[1], &nc
->rgrc
[1] );
1962 CONV_RECT32TO16( &nc32
->rgrc
[2], &nc
->rgrc
[2] );
1963 if (!(wp
= SEGPTR_NEW(WINDOWPOS16
)))
1968 STRUCT32_WINDOWPOS32to16( nc32
->lppos
, wp
);
1969 nc
->lppos
= SEGPTR_GET(wp
);
1971 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1972 *plparam
= (LPARAM
)SEGPTR_GET(nc
);
1979 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)*plparam
;
1982 if (!(cs
= SEGPTR_NEW(CREATESTRUCT16
))) return -1;
1983 STRUCT32_CREATESTRUCT32Ato16( cs32
, cs
);
1984 name
= SEGPTR_STRDUP( cs32
->lpszName
);
1985 cls
= SEGPTR_STRDUP( cs32
->lpszClass
);
1986 cs
->lpszName
= SEGPTR_GET(name
);
1987 cs
->lpszClass
= SEGPTR_GET(cls
);
1988 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
1991 case WM_PARENTNOTIFY
:
1992 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
1993 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
1994 /* else nothing to do */
1997 *plparam
= MapLS( (NMHDR
*)*plparam
); /* NMHDR is already 32-bit */
2001 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
2002 if (!str
) return -1;
2003 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2006 case WM_WINDOWPOSCHANGING
:
2007 case WM_WINDOWPOSCHANGED
:
2009 WINDOWPOS16
*wp
= (WINDOWPOS16
*)SEGPTR_ALLOC( sizeof(*wp
) +
2012 STRUCT32_WINDOWPOS32to16( (WINDOWPOS
*)*plparam
, wp
);
2013 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
2014 *plparam
= (LPARAM
)SEGPTR_GET(wp
);
2019 LPMSG msg32
= (LPMSG
) *plparam
;
2020 LPMSG16 msg16
= (LPMSG16
) SEGPTR_NEW( MSG16
);
2022 if (!msg16
) return -1;
2023 msg16
->hwnd
= msg32
->hwnd
;
2024 msg16
->lParam
= msg32
->lParam
;
2025 msg16
->time
= msg32
->time
;
2026 CONV_POINT32TO16(&msg32
->pt
,&msg16
->pt
);
2027 /* this is right, right? */
2028 if (WINPROC_MapMsg32ATo16(msg32
->hwnd
,msg32
->message
,msg32
->wParam
,
2029 &msg16
->message
,&msg16
->wParam
, &msg16
->lParam
)<0) {
2030 SEGPTR_FREE( msg16
);
2033 *plparam
= (LPARAM
)SEGPTR_GET(msg16
);
2038 case WM_ACTIVATEAPP
:
2040 *plparam
= (LPARAM
)THREAD_IdToTEB((DWORD
) *plparam
)->htask16
;
2043 case WM_ASKCBFORMATNAME
:
2044 case WM_DEVMODECHANGE
:
2045 case WM_PAINTCLIPBOARD
:
2046 case WM_SIZECLIPBOARD
:
2047 case WM_WININICHANGE
:
2048 FIXME_(msg
)("message %04x needs translation\n", msg32
);
2050 case WM_SIZING
: /* should not be send to 16-bit apps */
2052 default: /* No translation needed */
2058 /**********************************************************************
2059 * WINPROC_UnmapMsg32ATo16
2061 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2063 void WINPROC_UnmapMsg32ATo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2072 case LB_FINDSTRINGEXACT
:
2073 case LB_INSERTSTRING
:
2074 case LB_SELECTSTRING
:
2075 case LB_SETTABSTOPS
:
2078 case CB_FINDSTRINGEXACT
:
2079 case CB_INSERTSTRING
:
2080 case CB_SELECTSTRING
:
2082 case WM_COMPAREITEM
:
2086 SEGPTR_FREE( PTR_SEG_TO_LIN(p16
->lParam
) );
2089 case CB_GETDROPPEDCONTROLRECT
:
2090 case LB_GETITEMRECT
:
2092 RECT16
*rect
= (RECT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2093 p16
->lParam
= *(LPARAM
*)(rect
+ 1);
2094 CONV_RECT16TO32( rect
, (RECT
*)(p16
->lParam
));
2095 SEGPTR_FREE( rect
);
2098 case LB_GETSELITEMS
:
2101 LPINT16 items
= (LPINT16
)PTR_SEG_TO_LIN(lParam
);
2102 p16
->lParam
= *((LPARAM
*)items
- 1);
2103 for (i
= 0; i
< p16
->wParam
; i
++) *((LPINT
)(p16
->lParam
) + i
) = items
[i
];
2104 SEGPTR_FREE( (LPARAM
*)items
- 1 );
2110 *((LPUINT
)(wParam
)) = LOWORD(p16
->lResult
);
2112 *((LPUINT
)(lParam
)) = HIWORD(p16
->lResult
); /* FIXME: substract 1? */
2117 UnMapLS( (SEGPTR
)(p16
->lParam
) );
2120 case WM_MEASUREITEM
:
2122 MEASUREITEMSTRUCT16
*mis
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2123 MEASUREITEMSTRUCT
*mis32
= *(MEASUREITEMSTRUCT
**)(mis
+ 1);
2124 mis32
->itemWidth
= mis
->itemWidth
;
2125 mis32
->itemHeight
= mis
->itemHeight
;
2129 case WM_GETMINMAXINFO
:
2131 MINMAXINFO16
*mmi
= (MINMAXINFO16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2132 p16
->lParam
= *(LPARAM
*)(mmi
+ 1);
2133 STRUCT32_MINMAXINFO16to32( mmi
, (MINMAXINFO
*)(p16
->lParam
) );
2139 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(p16
->lParam
);
2140 p16
->lParam
= *((LPARAM
*)str
- 1);
2141 lstrcpynA( (LPSTR
)(p16
->lParam
), str
, p16
->wParam
);
2142 SEGPTR_FREE( (LPARAM
*)str
- 1 );
2147 MDICREATESTRUCT16
*cs
= (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2148 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->szTitle
) );
2149 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->szClass
) );
2153 case WM_MDIGETACTIVE
:
2154 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(p16
->lResult
);
2155 p16
->lResult
= (HWND
)LOWORD(p16
->lResult
);
2159 NCCALCSIZE_PARAMS
*nc32
;
2160 NCCALCSIZE_PARAMS16
*nc
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2161 p16
->lParam
= *(LPARAM
*)(nc
+ 1);
2162 nc32
= (NCCALCSIZE_PARAMS
*)(p16
->lParam
);
2163 CONV_RECT16TO32( &nc
->rgrc
[0], &nc32
->rgrc
[0] );
2166 CONV_RECT16TO32( &nc
->rgrc
[1], &nc32
->rgrc
[1] );
2167 CONV_RECT16TO32( &nc
->rgrc
[2], &nc32
->rgrc
[2] );
2168 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc
->lppos
),
2170 SEGPTR_FREE( PTR_SEG_TO_LIN(nc
->lppos
) );
2178 CREATESTRUCT16
*cs
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2179 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->lpszName
) );
2180 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->lpszClass
) );
2184 case WM_WINDOWPOSCHANGING
:
2185 case WM_WINDOWPOSCHANGED
:
2187 WINDOWPOS16
*wp
= (WINDOWPOS16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2188 p16
->lParam
= *(LPARAM
*)(wp
+ 1);
2189 STRUCT32_WINDOWPOS16to32( wp
, (WINDOWPOS
*)p16
->lParam
);
2194 UnMapLS(p16
->lParam
);
2199 LPMSG16 msg16
= (LPMSG16
)PTR_SEG_TO_LIN(p16
->lParam
);
2201 msgp16
.wParam
=msg16
->wParam
;
2202 msgp16
.lParam
=msg16
->lParam
;
2203 WINPROC_UnmapMsg32ATo16(((LPMSG
)lParam
)->hwnd
, ((LPMSG
)lParam
)->message
,
2204 ((LPMSG
)lParam
)->wParam
, ((LPMSG
)lParam
)->lParam
,
2213 /**********************************************************************
2214 * WINPROC_MapMsg32WTo16
2216 * Map a message from 32-bit Unicode to 16-bit.
2217 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2219 INT
WINPROC_MapMsg32WTo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
2220 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
2223 *pmsg16
= LOWORD(msg32
);
2224 *pwparam16
= LOWORD(wParam32
);
2229 case LB_FINDSTRINGEXACT
:
2230 case LB_INSERTSTRING
:
2231 case LB_SELECTSTRING
:
2235 LPSTR str
= SEGPTR_STRDUP_WtoA( (LPWSTR
)*plparam
);
2236 if (!str
) return -1;
2237 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2239 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2244 case CB_FINDSTRINGEXACT
:
2245 case CB_INSERTSTRING
:
2246 case CB_SELECTSTRING
:
2249 LPSTR str
= SEGPTR_STRDUP_WtoA( (LPWSTR
)*plparam
);
2250 if (!str
) return -1;
2251 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2253 *pmsg16
= (UINT16
)msg32
+ (CB_ADDSTRING16
- CB_ADDSTRING
);
2260 CREATESTRUCTW
*cs32
= (CREATESTRUCTW
*)*plparam
;
2263 if (!(cs
= SEGPTR_NEW(CREATESTRUCT16
))) return -1;
2264 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs32
, cs
);
2265 name
= SEGPTR_STRDUP_WtoA( cs32
->lpszName
);
2266 cls
= SEGPTR_STRDUP_WtoA( cs32
->lpszClass
);
2267 cs
->lpszName
= SEGPTR_GET(name
);
2268 cs
->lpszClass
= SEGPTR_GET(cls
);
2269 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
2274 MDICREATESTRUCT16
*cs
;
2275 MDICREATESTRUCTW
*cs32
= (MDICREATESTRUCTW
*)*plparam
;
2278 if (!(cs
= SEGPTR_NEW(MDICREATESTRUCT16
))) return -1;
2279 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs32
, cs
);
2280 name
= SEGPTR_STRDUP_WtoA( cs32
->szTitle
);
2281 cls
= SEGPTR_STRDUP_WtoA( cs32
->szClass
);
2282 cs
->szTitle
= SEGPTR_GET(name
);
2283 cs
->szClass
= SEGPTR_GET(cls
);
2284 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
2289 LPSTR str
= SEGPTR_STRDUP_WtoA( (LPWSTR
)*plparam
);
2290 if (!str
) return -1;
2291 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2296 if ( WINPROC_TestLBForStr( hwnd
))
2298 LPSTR str
= (LPSTR
) SEGPTR_ALLOC( 256 ); /* fixme: fixed sized buffer */
2299 if (!str
) return -1;
2300 *pmsg16
= (msg32
== LB_GETTEXT
)? LB_GETTEXT16
: CB_GETLBTEXT16
;
2301 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2308 case WM_SYSDEADCHAR
:
2310 WCHAR wch
= wParam32
;
2312 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2317 default: /* No Unicode translation needed (?) */
2318 return WINPROC_MapMsg32ATo16( hwnd
, msg32
, wParam32
, pmsg16
,
2319 pwparam16
, plparam
);
2324 /**********************************************************************
2325 * WINPROC_UnmapMsg32WTo16
2327 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2329 void WINPROC_UnmapMsg32WTo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2336 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(p16
->lParam
);
2337 p16
->lParam
= *((LPARAM
*)str
- 1);
2338 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)p16
->lParam
, 0x7fffffff );
2339 SEGPTR_FREE( (LPARAM
*)str
- 1 );
2344 if ( WINPROC_TestLBForStr( hwnd
))
2346 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(p16
->lParam
);
2347 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)lParam
, 0x7fffffff );
2348 SEGPTR_FREE( (LPARAM
*) str
);
2352 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, p16
);
2358 /**********************************************************************
2359 * WINPROC_CallProc32ATo32W
2361 * Call a window procedure, translating args from Ansi to Unicode.
2363 static LRESULT
WINPROC_CallProc32ATo32W( WNDPROC func
, HWND hwnd
,
2364 UINT msg
, WPARAM wParam
,
2369 if (WINPROC_MapMsg32ATo32W( hwnd
, msg
, &wParam
, &lParam
) == -1) return 0;
2370 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2371 WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
);
2376 /**********************************************************************
2377 * WINPROC_CallProc32WTo32A
2379 * Call a window procedure, translating args from Unicode to Ansi.
2381 static LRESULT
WINPROC_CallProc32WTo32A( WNDPROC func
, HWND hwnd
,
2382 UINT msg
, WPARAM wParam
,
2387 if (WINPROC_MapMsg32WTo32A( hwnd
, msg
, &wParam
, &lParam
) == -1) return 0;
2388 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2389 WINPROC_UnmapMsg32WTo32A( hwnd
, msg
, wParam
, lParam
);
2394 /**********************************************************************
2395 * WINPROC_CallProc16To32A
2397 * Call a 32-bit window procedure, translating the 16-bit args.
2399 static LRESULT
WINPROC_CallProc16To32A( WNDPROC func
, HWND16 hwnd
,
2400 UINT16 msg
, WPARAM16 wParam
,
2407 if (WINPROC_MapMsg16To32A( msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2409 result
= WINPROC_CallWndProc( func
, hwnd
, msg32
, wParam32
, lParam
);
2410 return WINPROC_UnmapMsg16To32A( hwnd
, msg32
, wParam32
, lParam
, result
);
2413 /**********************************************************************
2414 * WINPROC_Thunk16To32A
2416 static LRESULT WINAPI
WINPROC_Thunk16To32A( WNDPROC func
, LPBYTE args
)
2418 HWND16 hwnd
= *(HWND16
*)( args
+8 );
2419 UINT16 msg
= *(HWND16
*)( args
+6 );
2420 WPARAM16 wParam
= *(HWND16
*)( args
+4 );
2421 LPARAM lParam
= *(LPARAM
*)( args
+0 );
2423 return WINPROC_CallProc16To32A( func
, hwnd
, msg
, wParam
, lParam
);
2427 /**********************************************************************
2428 * WINPROC_CallProc16To32W
2430 * Call a 32-bit window procedure, translating the 16-bit args.
2432 static LRESULT
WINPROC_CallProc16To32W( WNDPROC func
, HWND16 hwnd
,
2433 UINT16 msg
, WPARAM16 wParam
,
2440 if (WINPROC_MapMsg16To32W( hwnd
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2443 result
= WINPROC_CallWndProc( func
, hwnd
, msg32
, wParam32
, lParam
);
2445 return WINPROC_UnmapMsg16To32W( hwnd
, msg32
, wParam32
, lParam
, result
);
2448 /**********************************************************************
2449 * WINPROC_Thunk16To32W
2451 static LRESULT WINAPI
WINPROC_Thunk16To32W( WNDPROC func
, LPBYTE args
)
2453 HWND16 hwnd
= *(HWND16
*)( args
+8 );
2454 UINT16 msg
= *(HWND16
*)( args
+6 );
2455 WPARAM16 wParam
= *(HWND16
*)( args
+4 );
2456 LPARAM lParam
= *(LPARAM
*)( args
+0 );
2458 return WINPROC_CallProc16To32W( func
, hwnd
, msg
, wParam
, lParam
);
2461 /**********************************************************************
2462 * WINPROC_CallProc32ATo16
2464 * Call a 16-bit window procedure, translating the 32-bit args.
2466 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
2467 UINT msg
, WPARAM wParam
,
2473 mp16
.lParam
= lParam
;
2474 if (WINPROC_MapMsg32ATo16( hwnd
, msg
, wParam
,
2475 &msg16
, &mp16
.wParam
, &mp16
.lParam
) == -1)
2477 mp16
.lResult
= WINPROC_CallWndProc16( func
, hwnd
, msg16
,
2478 mp16
.wParam
, mp16
.lParam
);
2479 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2480 return mp16
.lResult
;
2484 /**********************************************************************
2485 * WINPROC_CallProc32WTo16
2487 * Call a 16-bit window procedure, translating the 32-bit args.
2489 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
2490 UINT msg
, WPARAM wParam
,
2496 mp16
.lParam
= lParam
;
2497 if (WINPROC_MapMsg32WTo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
,
2498 &mp16
.lParam
) == -1)
2500 mp16
.lResult
= WINPROC_CallWndProc16( func
, hwnd
, msg16
,
2501 mp16
.wParam
, mp16
.lParam
);
2502 WINPROC_UnmapMsg32WTo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2503 return mp16
.lResult
;
2507 /**********************************************************************
2508 * CallWindowProc16 (USER.122)
2510 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
2511 WPARAM16 wParam
, LPARAM lParam
)
2513 WINDOWPROC
*proc
= WINPROC_GetPtr( func
);
2516 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2519 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_16
);
2520 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2526 if (!proc
->thunk
.t_from32
.proc
) return 0;
2527 return WINPROC_CallWndProc16( proc
->thunk
.t_from32
.proc
,
2528 hwnd
, msg
, wParam
, lParam
);
2530 if (!proc
->thunk
.t_from16
.proc
) return 0;
2531 return WINPROC_CallProc16To32A( proc
->thunk
.t_from16
.proc
,
2532 hwnd
, msg
, wParam
, lParam
);
2534 if (!proc
->thunk
.t_from16
.proc
) return 0;
2535 return WINPROC_CallProc16To32W( proc
->thunk
.t_from16
.proc
,
2536 hwnd
, msg
, wParam
, lParam
);
2538 WARN_(relay
)("Invalid proc %p\n", proc
);
2544 /**********************************************************************
2545 * CallWindowProcA (USER32.18)
2547 * The CallWindowProc() function invokes the windows procedure _func_,
2548 * with _hwnd_ as the target window, the message specified by _msg_, and
2549 * the message parameters _wParam_ and _lParam_.
2551 * Some kinds of argument conversion may be done, I'm not sure what.
2553 * CallWindowProc() may be used for windows subclassing. Use
2554 * SetWindowLong() to set a new windows procedure for windows of the
2555 * subclass, and handle subclassed messages in the new windows
2556 * procedure. The new windows procedure may then use CallWindowProc()
2557 * with _func_ set to the parent class's windows procedure to dispatch
2558 * the message to the superclass.
2562 * The return value is message dependent.
2568 LRESULT WINAPI
CallWindowProcA(
2569 WNDPROC func
, /* [in] window procedure */
2570 HWND hwnd
, /* [in] target window */
2571 UINT msg
, /* [in] message */
2572 WPARAM wParam
, /* [in] message dependent parameter */
2573 LPARAM lParam
/* [in] message dependent parameter */
2575 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2577 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2580 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32A
);
2581 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2587 if (!proc
->thunk
.t_from32
.proc
) return 0;
2588 return WINPROC_CallProc32ATo16( proc
->thunk
.t_from32
.proc
,
2589 hwnd
, msg
, wParam
, lParam
);
2591 if (!proc
->thunk
.t_from16
.proc
) return 0;
2592 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2593 hwnd
, msg
, wParam
, lParam
);
2595 if (!proc
->thunk
.t_from16
.proc
) return 0;
2596 return WINPROC_CallProc32ATo32W( proc
->thunk
.t_from16
.proc
,
2597 hwnd
, msg
, wParam
, lParam
);
2599 WARN_(relay
)("Invalid proc %p\n", proc
);
2605 /**********************************************************************
2606 * CallWindowProcW (USER32.19)
2608 LRESULT WINAPI
CallWindowProcW( WNDPROC func
, HWND hwnd
, UINT msg
,
2609 WPARAM wParam
, LPARAM lParam
)
2611 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2613 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2616 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32W
);
2617 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2623 if (!proc
->thunk
.t_from32
.proc
) return 0;
2624 return WINPROC_CallProc32WTo16( proc
->thunk
.t_from32
.proc
,
2625 hwnd
, msg
, wParam
, lParam
);
2627 if (!proc
->thunk
.t_from16
.proc
) return 0;
2628 return WINPROC_CallProc32WTo32A( proc
->thunk
.t_from16
.proc
,
2629 hwnd
, msg
, wParam
, lParam
);
2631 if (!proc
->thunk
.t_from16
.proc
) return 0;
2632 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2633 hwnd
, msg
, wParam
, lParam
);
2635 WARN_(relay
)("Invalid proc %p\n", proc
);