2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
9 #include "wine/winbase16.h"
11 #include "stackframe.h"
12 #include "builtin16.h"
14 #include "selectors.h"
18 #include "debugtools.h"
24 DECLARE_DEBUG_CHANNEL(msg
)
25 DECLARE_DEBUG_CHANNEL(relay
)
26 DECLARE_DEBUG_CHANNEL(win
)
28 /* Window procedure 16-to-32-bit thunk,
29 * see BuildSpec16Files() in tools/build.c */
34 WORD pushw_bp
; /* pushw %bp */
35 BYTE pushl_func
; /* pushl $proc */
37 WORD pushw_ax
; /* pushw %ax */
38 BYTE pushl_relay
; /* pushl $relay */
39 void (*relay
)(); /* WINPROC_Thunk16To32A/W() */
40 BYTE lcall
; /* lcall cs:glue */
41 void (*glue
)(); /* CallFrom16Long */
42 WORD cs
; /* __FLATCS */
43 WORD lret
; /* lret $10 */
45 } WINPROC_THUNK_FROM16
;
48 /* Window procedure 32-to-16-bit thunk,
49 * see BuildSpec32Files() in tools/build.c */
53 BYTE popl_eax
; /* popl %eax (return address) */
54 BYTE pushl_func
; /* pushl $proc */
55 WNDPROC16 proc WINE_PACKED
;
56 BYTE pushl_eax
; /* pushl %eax */
57 BYTE jmp
; /* jmp relay (relative jump)*/
58 void (*relay
)() WINE_PACKED
; /* WINPROC_CallProc32ATo16() */
59 } WINPROC_THUNK_FROM32
;
61 /* Simple jmp to call 32-bit procedure directly */
64 BYTE jmp
; /* jmp proc (relative jump) */
65 WNDPROC proc WINE_PACKED
;
70 WINPROC_THUNK_FROM16 t_from16
;
71 WINPROC_THUNK_FROM32 t_from32
;
74 typedef struct tagWINDOWPROC
76 WINPROC_THUNK thunk
; /* Thunk */
77 WINPROC_JUMP jmp
; /* Jump */
78 struct tagWINDOWPROC
*next
; /* Next window proc */
79 UINT magic
; /* Magic number */
80 WINDOWPROCTYPE type
; /* Function type */
81 WINDOWPROCUSER user
; /* Function user */
84 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
86 #define WINPROC_THUNKPROC(pproc) \
87 (((pproc)->type == WIN_PROC_16) ? \
88 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
89 (WNDPROC16)((pproc)->thunk.t_from16.proc))
91 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
92 UINT msg
, WPARAM wParam
,
94 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
95 UINT msg
, WPARAM wParam
,
97 static LRESULT WINAPI
WINPROC_Thunk16To32A( WNDPROC func
, LPBYTE args
);
98 static LRESULT WINAPI
WINPROC_Thunk16To32W( WNDPROC func
, LPBYTE args
);
100 static HANDLE WinProcHeap
;
103 /**********************************************************************
106 BOOL
WINPROC_Init(void)
108 WinProcHeap
= HeapCreate( HEAP_WINE_SEGPTR
| HEAP_WINE_CODESEG
, 0, 0 );
111 WARN_(relay
)("Unable to create winproc heap\n" );
118 /**********************************************************************
119 * WINPROC_CallWndProc32
121 * Call a 32-bit WndProc.
123 static LRESULT
WINPROC_CallWndProc( WNDPROC proc
, HWND hwnd
, UINT msg
,
124 WPARAM wParam
, LPARAM lParam
)
129 TRACE_(relay
)("(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
130 proc
, hwnd
, SPY_GetMsgName(msg
), wParam
, lParam
);
131 /* To avoid any deadlocks, all the locks on the windows structures
132 must be suspended before the control is passed to the application */
133 iWndsLocks
= WIN_SuspendWndsLock();
134 retvalue
= proc( hwnd
, msg
, wParam
, lParam
);
135 WIN_RestoreWndsLock(iWndsLocks
);
139 /***********************************************************************
140 * WINPROC_CallWndProc16
142 * Call a 16-bit window procedure
144 static LRESULT WINAPI
WINPROC_CallWndProc16( WNDPROC16 proc
, HWND16 hwnd
,
145 UINT16 msg
, WPARAM16 wParam
,
151 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
153 TEB
*teb
= NtCurrentTeb();
156 /* Window procedures want ax = hInstance, ds = es = ss */
158 memset(&context
, '\0', sizeof(context
));
159 DS_reg(&context
) = SELECTOROF(teb
->cur_stack
);
160 ES_reg(&context
) = DS_reg(&context
);
161 EAX_reg(&context
) = wndPtr
? wndPtr
->hInstance
: DS_reg(&context
);
162 CS_reg(&context
) = SELECTOROF(proc
);
163 EIP_reg(&context
) = OFFSETOF(proc
);
164 EBP_reg(&context
) = OFFSETOF(teb
->cur_stack
)
165 + (WORD
)&((STACK16FRAME
*)0)->bp
;
167 WIN_ReleaseWndPtr(wndPtr
);
171 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
172 work if structures passed in lParam are placed in the stack/data
173 segment. Programmers easily make the mistake of converting lParam
174 to a near rather than a far pointer, since Windows apparently
175 allows this. We copy the structures to the 16 bit stack; this is
176 ugly but makes these programs work. */
181 offset
= sizeof(CREATESTRUCT16
); break;
183 offset
= sizeof(DRAWITEMSTRUCT16
); break;
185 offset
= sizeof(COMPAREITEMSTRUCT16
); break;
189 void *s
= PTR_SEG_TO_LIN(lParam
);
190 lParam
= stack16_push( offset
);
191 memcpy( PTR_SEG_TO_LIN(lParam
), s
, offset
);
195 iWndsLocks
= WIN_SuspendWndsLock();
197 args
= (WORD
*)THREAD_STACK16(teb
) - 5;
198 args
[0] = LOWORD(lParam
);
199 args
[1] = HIWORD(lParam
);
204 ret
= CallTo16RegisterShort( &context
, 5 * sizeof(WORD
) );
205 if (offset
) stack16_pop( offset
);
207 WIN_RestoreWndsLock(iWndsLocks
);
213 /**********************************************************************
216 * Return a pointer to the win proc.
218 static WINDOWPROC
*WINPROC_GetPtr( WNDPROC16 handle
)
223 /* Check for a linear pointer */
225 if (HEAP_IsInsideHeap( WinProcHeap
, 0, (LPVOID
)handle
))
227 ptr
= (BYTE
*)handle
;
228 /* First check if it is the jmp address */
229 if (*ptr
== 0xe9 /* jmp */) ptr
-= (int)&((WINDOWPROC
*)0)->jmp
-
230 (int)&((WINDOWPROC
*)0)->thunk
;
231 /* Now it must be the thunk address */
232 if (*ptr
== 0x58 /* popl eax */) ptr
-= (int)&((WINDOWPROC
*)0)->thunk
;
233 /* Now we have a pointer to the WINDOWPROC struct */
234 if (((WINDOWPROC
*)ptr
)->magic
== WINPROC_MAGIC
)
235 return (WINDOWPROC
*)ptr
;
238 /* Check for a segmented pointer */
240 if (!IsBadReadPtr16((SEGPTR
)handle
,sizeof(WINDOWPROC
)-sizeof(proc
->thunk
)))
242 ptr
= (BYTE
*)PTR_SEG_TO_LIN(handle
);
243 if (!HEAP_IsInsideHeap( WinProcHeap
, 0, ptr
)) return NULL
;
244 /* It must be the thunk address */
245 if (*ptr
== 0x58 /* popl eax */) ptr
-= (int)&((WINDOWPROC
*)0)->thunk
;
246 /* Now we have a pointer to the WINDOWPROC struct */
247 if (((WINDOWPROC
*)ptr
)->magic
== WINPROC_MAGIC
)
248 return (WINDOWPROC
*)ptr
;
255 /**********************************************************************
256 * WINPROC_AllocWinProc
258 * Allocate a new window procedure.
260 static WINDOWPROC
*WINPROC_AllocWinProc( WNDPROC16 func
, WINDOWPROCTYPE type
,
261 WINDOWPROCUSER user
)
263 WINDOWPROC
*proc
, *oldproc
;
265 /* Allocate a window procedure */
267 if (!(proc
= HeapAlloc( WinProcHeap
, 0, sizeof(WINDOWPROC
) ))) return 0;
269 /* Check if the function is already a win proc */
271 if ((oldproc
= WINPROC_GetPtr( func
)))
280 proc
->thunk
.t_from32
.popl_eax
= 0x58; /* popl %eax */
281 proc
->thunk
.t_from32
.pushl_func
= 0x68; /* pushl $proc */
282 proc
->thunk
.t_from32
.proc
= func
;
283 proc
->thunk
.t_from32
.pushl_eax
= 0x50; /* pushl %eax */
284 proc
->thunk
.t_from32
.jmp
= 0xe9; /* jmp relay*/
285 proc
->thunk
.t_from32
.relay
= /* relative jump */
286 (void(*)())((DWORD
)WINPROC_CallProc32ATo16
-
287 (DWORD
)(&proc
->thunk
.t_from32
.relay
+ 1));
291 proc
->thunk
.t_from16
.pushw_bp
= 0x5566; /* pushw %bp */
292 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
293 proc
->thunk
.t_from16
.proc
= (FARPROC
)func
;
294 proc
->thunk
.t_from16
.pushw_ax
= 0x5066; /* pushw %ax */
295 proc
->thunk
.t_from16
.pushl_relay
= 0x68; /* pushl $relay */
296 proc
->thunk
.t_from16
.relay
= (type
== WIN_PROC_32A
) ?
297 (void(*)())WINPROC_Thunk16To32A
:
298 (void(*)())WINPROC_Thunk16To32W
;
299 proc
->thunk
.t_from16
.lcall
= 0x9a; /* lcall cs:glue */
300 proc
->thunk
.t_from16
.glue
= (void*)CallFrom16Long
;
301 GET_CS(proc
->thunk
.t_from16
.cs
);
302 proc
->thunk
.t_from16
.lret
= 0xca66;
303 proc
->thunk
.t_from16
.nArgs
= 10;
304 proc
->jmp
.jmp
= 0xe9;
305 /* Fixup relative jump */
306 proc
->jmp
.proc
= (WNDPROC
)((DWORD
)func
-
307 (DWORD
)(&proc
->jmp
.proc
+ 1));
310 /* Should not happen */
313 proc
->magic
= WINPROC_MAGIC
;
318 TRACE_(win
)("(%08x,%d): returning %08x\n",
319 (UINT
)func
, type
, (UINT
)proc
);
324 /**********************************************************************
327 * Get a window procedure pointer that can be passed to the Windows program.
329 WNDPROC16
WINPROC_GetProc( HWINDOWPROC proc
, WINDOWPROCTYPE type
)
331 if (!proc
) return NULL
;
332 if (type
== WIN_PROC_16
) /* We want a 16:16 address */
334 if (((WINDOWPROC
*)proc
)->type
== WIN_PROC_16
)
335 return ((WINDOWPROC
*)proc
)->thunk
.t_from32
.proc
;
337 return (WNDPROC16
)HEAP_GetSegptr( WinProcHeap
, 0,
338 &((WINDOWPROC
*)proc
)->thunk
);
340 else /* We want a 32-bit address */
342 if (((WINDOWPROC
*)proc
)->type
== WIN_PROC_16
)
343 return (WNDPROC16
)&((WINDOWPROC
*)proc
)->thunk
;
344 else if (type
!= ((WINDOWPROC
*)proc
)->type
)
345 /* Have to return the jmp address if types don't match */
346 return (WNDPROC16
)&((WINDOWPROC
*)proc
)->jmp
;
348 /* Some Win16 programs want to get back the proc they set */
349 return (WNDPROC16
)((WINDOWPROC
*)proc
)->thunk
.t_from16
.proc
;
354 /**********************************************************************
357 * Set the window procedure for a window or class. There are
358 * three tree classes of winproc callbacks:
360 * 1) class -> wp - not subclassed
361 * class -> wp -> wp -> wp -> wp - SetClassLong()
363 * 2) window -' / - not subclassed
364 * window -> wp -> wp ' - SetWindowLong()
366 * 3) timer -> wp - SetTimer()
368 * Initially, winproc of the window points to the current winproc
369 * thunk of its class. Subclassing prepends a new thunk to the
370 * window winproc chain at the head of the list. Thus, window thunk
371 * list includes class thunks and the latter are preserved when the
372 * window is destroyed.
375 BOOL
WINPROC_SetProc( HWINDOWPROC
*pFirst
, WNDPROC16 func
,
376 WINDOWPROCTYPE type
, WINDOWPROCUSER user
)
378 BOOL bRecycle
= FALSE
;
379 WINDOWPROC
*proc
, **ppPrev
;
381 /* Check if function is already in the list */
383 ppPrev
= (WINDOWPROC
**)pFirst
;
384 proc
= WINPROC_GetPtr( func
);
391 if ((*ppPrev
)->user
!= user
)
393 /* terminal thunk is being restored */
395 WINPROC_FreeProc( *pFirst
, (*ppPrev
)->user
);
396 *(WINDOWPROC
**)pFirst
= *ppPrev
;
405 if (((*ppPrev
)->type
== type
) &&
406 (func
== WINPROC_THUNKPROC(*ppPrev
)))
413 /* WPF_CLASS thunk terminates window thunk list */
414 if ((*ppPrev
)->user
!= user
) break;
415 ppPrev
= &(*ppPrev
)->next
;
420 /* Extract this thunk from the list */
422 *ppPrev
= proc
->next
;
424 else /* Allocate a new one */
426 if (proc
) /* Was already a win proc */
429 func
= WINPROC_THUNKPROC(proc
);
431 proc
= WINPROC_AllocWinProc( func
, type
, user
);
432 if (!proc
) return FALSE
;
435 /* Add the win proc at the head of the list */
437 TRACE_(win
)("(%08x,%08x,%d): res=%08x\n",
438 (UINT
)*pFirst
, (UINT
)func
, type
, (UINT
)proc
);
439 proc
->next
= *(WINDOWPROC
**)pFirst
;
440 *(WINDOWPROC
**)pFirst
= proc
;
445 /**********************************************************************
448 * Free a list of win procs.
450 void WINPROC_FreeProc( HWINDOWPROC proc
, WINDOWPROCUSER user
)
454 WINDOWPROC
*next
= ((WINDOWPROC
*)proc
)->next
;
455 if (((WINDOWPROC
*)proc
)->user
!= user
) break;
456 TRACE_(win
)("freeing %08x\n", (UINT
)proc
);
457 HeapFree( WinProcHeap
, 0, proc
);
463 /**********************************************************************
464 * WINPROC_GetProcType
466 * Return the window procedure type.
468 WINDOWPROCTYPE
WINPROC_GetProcType( HWINDOWPROC proc
)
471 (((WINDOWPROC
*)proc
)->magic
!= WINPROC_MAGIC
))
472 return WIN_PROC_INVALID
;
473 return ((WINDOWPROC
*)proc
)->type
;
475 /**********************************************************************
476 * WINPROC_TestCBForStr
478 * Return TRUE if the lparam is a string
480 static BOOL
WINPROC_TestCBForStr ( HWND hwnd
)
483 WND
* wnd
= WIN_FindWndPtr(hwnd
);
484 retvalue
= ( !(LOWORD(wnd
->dwStyle
) & (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) ||
485 (LOWORD(wnd
->dwStyle
) & CBS_HASSTRINGS
) );
486 WIN_ReleaseWndPtr(wnd
);
489 /**********************************************************************
490 * WINPROC_TestLBForStr
492 * Return TRUE if the lparam is a string
494 static BOOL
WINPROC_TestLBForStr ( HWND hwnd
)
497 WND
* wnd
= WIN_FindWndPtr(hwnd
);
498 retvalue
= ( !(LOWORD(wnd
->dwStyle
) & (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) ||
499 (LOWORD(wnd
->dwStyle
) & LBS_HASSTRINGS
) );
500 WIN_ReleaseWndPtr(wnd
);
504 /**********************************************************************
505 * WINPROC_MapMsg32ATo32W
507 * Map a message from Ansi to Unicode.
508 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
511 * WM_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR, WM_SYSDEADCHAR
514 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
515 * the first four bytes are the handle of the icon
516 * when the WM_SETTEXT message has been used to set the icon
518 INT
WINPROC_MapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM
*plparam
)
524 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( SystemHeap
, 0,
525 wParam
* sizeof(WCHAR
) + sizeof(LPARAM
) );
527 *ptr
++ = *plparam
; /* Store previous lParam */
528 *plparam
= (LPARAM
)ptr
;
531 /* lparam is string (0-terminated) */
533 case WM_WININICHANGE
:
536 case CB_FINDSTRINGEXACT
:
537 case CB_SELECTSTRING
:
541 case LB_SELECTSTRING
:
543 *plparam
= (LPARAM
)HEAP_strdupAtoW( SystemHeap
, 0, (LPCSTR
)*plparam
);
544 return (*plparam
? 1 : -1);
549 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)HeapAlloc( SystemHeap
, 0,
552 *cs
= *(CREATESTRUCTW
*)*plparam
;
553 if (HIWORD(cs
->lpszName
))
554 cs
->lpszName
= HEAP_strdupAtoW( SystemHeap
, 0,
555 (LPCSTR
)cs
->lpszName
);
556 if (HIWORD(cs
->lpszClass
))
557 cs
->lpszClass
= HEAP_strdupAtoW( SystemHeap
, 0,
558 (LPCSTR
)cs
->lpszClass
);
559 *plparam
= (LPARAM
)cs
;
564 MDICREATESTRUCTW
*cs
=
565 (MDICREATESTRUCTW
*)HeapAlloc( SystemHeap
, 0, sizeof(*cs
) );
567 *cs
= *(MDICREATESTRUCTW
*)*plparam
;
568 if (HIWORD(cs
->szClass
))
569 cs
->szClass
= HEAP_strdupAtoW( SystemHeap
, 0,
570 (LPCSTR
)cs
->szClass
);
571 if (HIWORD(cs
->szTitle
))
572 cs
->szTitle
= HEAP_strdupAtoW( SystemHeap
, 0,
573 (LPCSTR
)cs
->szTitle
);
574 *plparam
= (LPARAM
)cs
;
580 case LB_INSERTSTRING
:
581 if ( WINPROC_TestLBForStr( hwnd
))
582 *plparam
= (LPARAM
)HEAP_strdupAtoW( SystemHeap
, 0, (LPCSTR
)*plparam
);
583 return (*plparam
? 1 : -1);
585 case LB_GETTEXT
: /* fixme: fixed sized buffer */
586 { if ( WINPROC_TestLBForStr( hwnd
))
587 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( SystemHeap
, 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
589 *ptr
++ = *plparam
; /* Store previous lParam */
590 *plparam
= (LPARAM
)ptr
;
597 case CB_INSERTSTRING
:
598 if ( WINPROC_TestCBForStr( hwnd
))
599 *plparam
= (LPARAM
)HEAP_strdupAtoW( SystemHeap
, 0, (LPCSTR
)*plparam
);
600 return (*plparam
? 1 : -1);
602 case CB_GETLBTEXT
: /* fixme: fixed sized buffer */
603 { if ( WINPROC_TestCBForStr( hwnd
))
604 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( SystemHeap
, 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
606 *ptr
++ = *plparam
; /* Store previous lParam */
607 *plparam
= (LPARAM
)ptr
;
614 { WORD len
= (WORD
)*plparam
;
615 LPARAM
*ptr
= (LPARAM
*) HEAP_xalloc( SystemHeap
, 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(WCHAR
) );
617 *ptr
++ = *plparam
; /* Store previous lParam */
618 *((WORD
*) ptr
) = len
; /* Store the length */
619 *plparam
= (LPARAM
)ptr
;
623 case WM_ASKCBFORMATNAME
:
624 case WM_DEVMODECHANGE
:
625 case WM_PAINTCLIPBOARD
:
626 case WM_SIZECLIPBOARD
:
627 case EM_SETPASSWORDCHAR
:
628 FIXME_(msg
)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg
), msg
);
630 default: /* No translation needed */
636 /**********************************************************************
637 * WINPROC_UnmapMsg32ATo32W
639 * Unmap a message that was mapped from Ansi to Unicode.
641 void WINPROC_UnmapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
647 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
648 lstrcpynWtoA( (LPSTR
)*ptr
, (LPWSTR
)lParam
, wParam
);
649 HeapFree( SystemHeap
, 0, ptr
);
656 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)lParam
;
657 if (HIWORD(cs
->lpszName
))
658 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->lpszName
);
659 if (HIWORD(cs
->lpszClass
))
660 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->lpszClass
);
661 HeapFree( SystemHeap
, 0, cs
);
667 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
668 if (HIWORD(cs
->szTitle
))
669 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->szTitle
);
670 if (HIWORD(cs
->szClass
))
671 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->szClass
);
672 HeapFree( SystemHeap
, 0, cs
);
677 case WM_WININICHANGE
:
680 case CB_FINDSTRINGEXACT
:
681 case CB_SELECTSTRING
:
685 case LB_SELECTSTRING
:
687 HeapFree( SystemHeap
, 0, (void *)lParam
);
692 case LB_INSERTSTRING
:
693 if ( WINPROC_TestLBForStr( hwnd
))
694 HeapFree( SystemHeap
, 0, (void *)lParam
);
698 { if ( WINPROC_TestLBForStr( hwnd
))
699 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
700 lstrcpyWtoA( (LPSTR
)*ptr
, (LPWSTR
)(lParam
) );
701 HeapFree( SystemHeap
, 0, ptr
);
708 case CB_INSERTSTRING
:
709 if ( WINPROC_TestCBForStr( hwnd
))
710 HeapFree( SystemHeap
, 0, (void *)lParam
);
714 { if ( WINPROC_TestCBForStr( hwnd
))
715 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
716 lstrcpyWtoA( (LPSTR
)*ptr
, (LPWSTR
)(lParam
) );
717 HeapFree( SystemHeap
, 0, ptr
);
724 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lParam */
725 WORD len
= *(WORD
*) lParam
;
726 lstrcpynWtoA( (LPSTR
)*ptr
, (LPWSTR
)lParam
, len
);
727 HeapFree( SystemHeap
, 0, ptr
);
734 /**********************************************************************
735 * WINPROC_MapMsg32WTo32A
737 * Map a message from Unicode to Ansi.
738 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
740 INT
WINPROC_MapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM
*plparam
)
745 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( SystemHeap
, 0,
746 wParam
+ sizeof(LPARAM
) );
748 *ptr
++ = *plparam
; /* Store previous lParam */
749 *plparam
= (LPARAM
)ptr
;
754 case WM_WININICHANGE
:
757 case CB_FINDSTRINGEXACT
:
758 case CB_SELECTSTRING
:
762 case LB_SELECTSTRING
:
764 *plparam
= (LPARAM
)HEAP_strdupWtoA( SystemHeap
, 0, (LPCWSTR
)*plparam
);
765 return (*plparam
? 1 : -1);
770 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( SystemHeap
, 0,
773 *cs
= *(CREATESTRUCTA
*)*plparam
;
774 if (HIWORD(cs
->lpszName
))
775 cs
->lpszName
= HEAP_strdupWtoA( SystemHeap
, 0,
776 (LPCWSTR
)cs
->lpszName
);
777 if (HIWORD(cs
->lpszClass
))
778 cs
->lpszClass
= HEAP_strdupWtoA( SystemHeap
, 0,
779 (LPCWSTR
)cs
->lpszClass
);
780 *plparam
= (LPARAM
)cs
;
785 MDICREATESTRUCTA
*cs
=
786 (MDICREATESTRUCTA
*)HeapAlloc( SystemHeap
, 0, sizeof(*cs
) );
788 *cs
= *(MDICREATESTRUCTA
*)*plparam
;
789 if (HIWORD(cs
->szTitle
))
790 cs
->szTitle
= HEAP_strdupWtoA( SystemHeap
, 0,
791 (LPCWSTR
)cs
->szTitle
);
792 if (HIWORD(cs
->szClass
))
793 cs
->szClass
= HEAP_strdupWtoA( SystemHeap
, 0,
794 (LPCWSTR
)cs
->szClass
);
795 *plparam
= (LPARAM
)cs
;
801 case LB_INSERTSTRING
:
802 if ( WINPROC_TestLBForStr( hwnd
))
803 *plparam
= (LPARAM
)HEAP_strdupWtoA( SystemHeap
, 0, (LPCWSTR
)*plparam
);
804 return (*plparam
? 1 : -1);
806 case LB_GETTEXT
: /* fixme: fixed sized buffer */
807 { if ( WINPROC_TestLBForStr( hwnd
))
808 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( SystemHeap
, 0, 256 + sizeof(LPARAM
) );
810 *ptr
++ = *plparam
; /* Store previous lParam */
811 *plparam
= (LPARAM
)ptr
;
818 case CB_INSERTSTRING
:
819 if ( WINPROC_TestCBForStr( hwnd
))
820 *plparam
= (LPARAM
)HEAP_strdupWtoA( SystemHeap
, 0, (LPCWSTR
)*plparam
);
821 return (*plparam
? 1 : -1);
823 case CB_GETLBTEXT
: /* fixme: fixed sized buffer */
824 { if ( WINPROC_TestCBForStr( hwnd
))
825 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( SystemHeap
, 0, 256 + sizeof(LPARAM
) );
827 *ptr
++ = *plparam
; /* Store previous lParam */
828 *plparam
= (LPARAM
)ptr
;
835 { WORD len
= (WORD
)*plparam
;
836 LPARAM
*ptr
= (LPARAM
*) HEAP_xalloc( SystemHeap
, 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(CHAR
) );
838 *ptr
++ = *plparam
; /* Store previous lParam */
839 *((WORD
*) ptr
) = len
; /* Store the length */
840 *plparam
= (LPARAM
)ptr
;
844 case WM_ASKCBFORMATNAME
:
845 case WM_DEVMODECHANGE
:
846 case WM_PAINTCLIPBOARD
:
847 case WM_SIZECLIPBOARD
:
848 case EM_SETPASSWORDCHAR
:
849 FIXME_(msg
)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg
),msg
);
851 default: /* No translation needed */
857 /**********************************************************************
858 * WINPROC_UnmapMsg32WTo32A
860 * Unmap a message that was mapped from Unicode to Ansi.
862 void WINPROC_UnmapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
868 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
869 lstrcpynAtoW( (LPWSTR
)*ptr
, (LPSTR
)lParam
, wParam
);
870 HeapFree( SystemHeap
, 0, ptr
);
875 case WM_WININICHANGE
:
878 case CB_FINDSTRINGEXACT
:
879 case CB_SELECTSTRING
:
883 case LB_SELECTSTRING
:
885 HeapFree( SystemHeap
, 0, (void *)lParam
);
891 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
892 if (HIWORD(cs
->lpszName
))
893 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->lpszName
);
894 if (HIWORD(cs
->lpszClass
))
895 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->lpszClass
);
896 HeapFree( SystemHeap
, 0, cs
);
902 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
903 if (HIWORD(cs
->szTitle
))
904 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->szTitle
);
905 if (HIWORD(cs
->szClass
))
906 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->szClass
);
907 HeapFree( SystemHeap
, 0, cs
);
913 case LB_INSERTSTRING
:
914 if ( WINPROC_TestLBForStr( hwnd
))
915 HeapFree( SystemHeap
, 0, (void *)lParam
);
919 { if ( WINPROC_TestLBForStr( hwnd
))
920 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
921 lstrcpyAtoW( (LPWSTR
)*ptr
, (LPSTR
)(lParam
) );
922 HeapFree( SystemHeap
, 0, ptr
);
929 case CB_INSERTSTRING
:
930 if ( WINPROC_TestCBForStr( hwnd
))
931 HeapFree( SystemHeap
, 0, (void *)lParam
);
935 { if ( WINPROC_TestCBForStr( hwnd
))
936 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
937 lstrcpyAtoW( (LPWSTR
)*ptr
, (LPSTR
)(lParam
) );
938 HeapFree( SystemHeap
, 0, ptr
);
945 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lparam */
946 WORD len
= *(WORD
*)ptr
;
947 lstrcpynAtoW( (LPWSTR
) *ptr
, (LPSTR
)lParam
, len
);
948 HeapFree( SystemHeap
, 0, ptr
);
955 /**********************************************************************
956 * WINPROC_MapMsg16To32A
958 * Map a message from 16- to 32-bit Ansi.
959 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
961 INT
WINPROC_MapMsg16To32A( UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
962 WPARAM
*pwparam32
, LPARAM
*plparam
)
964 *pmsg32
= (UINT
)msg16
;
965 *pwparam32
= (WPARAM
)wParam16
;
972 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
973 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
977 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
978 *plparam
= (LPARAM
)(HWND
)HIWORD(*plparam
);
981 if ( HIWORD(*plparam
) > CTLCOLOR_STATIC
) return -1;
982 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
983 *pwparam32
= (WPARAM
)(HDC
)wParam16
;
984 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
988 COMPAREITEMSTRUCT16
* cis16
= (COMPAREITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
989 COMPAREITEMSTRUCT
*cis
= (COMPAREITEMSTRUCT
*)
990 HeapAlloc(SystemHeap
, 0, sizeof(*cis
));
992 cis
->CtlType
= cis16
->CtlType
;
993 cis
->CtlID
= cis16
->CtlID
;
994 cis
->hwndItem
= cis16
->hwndItem
;
995 cis
->itemID1
= cis16
->itemID1
;
996 cis
->itemData1
= cis16
->itemData1
;
997 cis
->itemID2
= cis16
->itemID2
;
998 cis
->itemData2
= cis16
->itemData2
;
999 cis
->dwLocaleId
= 0; /* FIXME */
1000 *plparam
= (LPARAM
)cis
;
1005 DELETEITEMSTRUCT16
* dis16
= (DELETEITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1006 DELETEITEMSTRUCT
*dis
= (DELETEITEMSTRUCT
*)
1007 HeapAlloc(SystemHeap
, 0, sizeof(*dis
));
1008 if (!dis
) return -1;
1009 dis
->CtlType
= dis16
->CtlType
;
1010 dis
->CtlID
= dis16
->CtlID
;
1011 dis
->hwndItem
= dis16
->hwndItem
;
1012 dis
->itemData
= dis16
->itemData
;
1013 *plparam
= (LPARAM
)dis
;
1016 case WM_MEASUREITEM
:
1018 MEASUREITEMSTRUCT16
* mis16
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1019 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)
1020 HeapAlloc(SystemHeap
, 0,
1021 sizeof(*mis
) + sizeof(LPARAM
));
1022 if (!mis
) return -1;
1023 mis
->CtlType
= mis16
->CtlType
;
1024 mis
->CtlID
= mis16
->CtlID
;
1025 mis
->itemID
= mis16
->itemID
;
1026 mis
->itemWidth
= mis16
->itemWidth
;
1027 mis
->itemHeight
= mis16
->itemHeight
;
1028 mis
->itemData
= mis16
->itemData
;
1029 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1030 *plparam
= (LPARAM
)mis
;
1035 DRAWITEMSTRUCT16
* dis16
= (DRAWITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1036 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)HeapAlloc(SystemHeap
, 0,
1038 if (!dis
) return -1;
1039 dis
->CtlType
= dis16
->CtlType
;
1040 dis
->CtlID
= dis16
->CtlID
;
1041 dis
->itemID
= dis16
->itemID
;
1042 dis
->itemAction
= dis16
->itemAction
;
1043 dis
->itemState
= dis16
->itemState
;
1044 dis
->hwndItem
= dis16
->hwndItem
;
1045 dis
->hDC
= dis16
->hDC
;
1046 dis
->itemData
= dis16
->itemData
;
1047 CONV_RECT16TO32( &dis16
->rcItem
, &dis
->rcItem
);
1048 *plparam
= (LPARAM
)dis
;
1051 case WM_GETMINMAXINFO
:
1053 MINMAXINFO
*mmi
= (MINMAXINFO
*)HeapAlloc( SystemHeap
, 0,
1054 sizeof(*mmi
) + sizeof(LPARAM
));
1055 if (!mmi
) return -1;
1056 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16
*)PTR_SEG_TO_LIN(*plparam
),
1058 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1059 *plparam
= (LPARAM
)mmi
;
1064 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
1068 MDICREATESTRUCT16
*cs16
=
1069 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1070 MDICREATESTRUCTA
*cs
=
1071 (MDICREATESTRUCTA
*)HeapAlloc( SystemHeap
, 0,
1072 sizeof(*cs
) + sizeof(LPARAM
) );
1074 STRUCT32_MDICREATESTRUCT16to32A( cs16
, cs
);
1075 cs
->szTitle
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->szTitle
);
1076 cs
->szClass
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->szClass
);
1077 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1078 *plparam
= (LPARAM
)cs
;
1081 case WM_MDIGETACTIVE
:
1082 *plparam
= (LPARAM
)HeapAlloc( SystemHeap
, 0, sizeof(BOOL
) );
1083 *(BOOL
*)(*plparam
) = 0;
1087 *pmsg32
=WM_MDIREFRESHMENU
;
1088 *pwparam32
= (WPARAM
)(HMENU
)LOWORD(*plparam
);
1089 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1093 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1094 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1096 case WM_MDIACTIVATE
:
1099 *pwparam32
= (WPARAM
)(HWND
)HIWORD(*plparam
);
1100 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
1102 else /* message sent to MDI client */
1103 *pwparam32
= wParam16
;
1107 NCCALCSIZE_PARAMS16
*nc16
;
1108 NCCALCSIZE_PARAMS
*nc
;
1110 nc
= (NCCALCSIZE_PARAMS
*)HeapAlloc( SystemHeap
, 0,
1111 sizeof(*nc
) + sizeof(LPARAM
) );
1113 nc16
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(*plparam
);
1114 CONV_RECT16TO32( &nc16
->rgrc
[0], &nc
->rgrc
[0] );
1117 nc
->lppos
= (WINDOWPOS
*)HeapAlloc( SystemHeap
, 0,
1118 sizeof(*nc
->lppos
) );
1119 CONV_RECT16TO32( &nc16
->rgrc
[1], &nc
->rgrc
[1] );
1120 CONV_RECT16TO32( &nc16
->rgrc
[2], &nc
->rgrc
[2] );
1121 if (nc
->lppos
) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc16
->lppos
), nc
->lppos
);
1123 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1124 *plparam
= (LPARAM
)nc
;
1130 CREATESTRUCT16
*cs16
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1131 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( SystemHeap
, 0,
1132 sizeof(*cs
) + sizeof(LPARAM
) );
1134 STRUCT32_CREATESTRUCT16to32A( cs16
, cs
);
1135 cs
->lpszName
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->lpszName
);
1136 cs
->lpszClass
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->lpszClass
);
1137 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1138 *plparam
= (LPARAM
)cs
;
1141 case WM_PARENTNOTIFY
:
1142 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
1144 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1145 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
1148 case WM_WINDOWPOSCHANGING
:
1149 case WM_WINDOWPOSCHANGED
:
1151 WINDOWPOS
*wp
= (WINDOWPOS
*)HeapAlloc( SystemHeap
, 0,
1152 sizeof(*wp
) + sizeof(LPARAM
) );
1154 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(*plparam
),
1156 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1157 *plparam
= (LPARAM
)wp
;
1163 LPMSG16 msg16
= (LPMSG16
)PTR_SEG_TO_LIN(*plparam
);
1164 LPMSG msg32
= (LPMSG
)HeapAlloc( SystemHeap
, 0, sizeof(MSG
) );
1166 if (!msg32
) return -1;
1167 msg32
->hwnd
= msg16
->hwnd
;
1168 msg32
->lParam
= msg16
->lParam
;
1169 msg32
->time
= msg16
->time
;
1170 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1171 /* this is right, right? */
1172 if (WINPROC_MapMsg16To32A(msg16
->message
,msg16
->wParam
,
1173 &msg32
->message
,&msg32
->wParam
,
1174 &msg32
->lParam
)<0) {
1175 HeapFree( SystemHeap
, 0, msg32
);
1178 *plparam
= (LPARAM
)msg32
;
1183 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
1185 case WM_ACTIVATEAPP
:
1187 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1188 a 32bit window. Might be superflous with 32bit interprocess
1191 HTASK16 htask
= (HTASK16
) *plparam
;
1192 DWORD idThread
= (DWORD
)((TDB
*)GlobalLock16(htask
))->teb
->tid
;
1193 *plparam
= (LPARAM
) idThread
;
1196 case WM_ASKCBFORMATNAME
:
1197 case WM_DEVMODECHANGE
:
1198 case WM_PAINTCLIPBOARD
:
1199 case WM_SIZECLIPBOARD
:
1200 case WM_WININICHANGE
:
1201 FIXME_(msg
)("message %04x needs translation\n",msg16
);
1204 default: /* No translation needed */
1210 /**********************************************************************
1211 * WINPROC_UnmapMsg16To32A
1213 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1215 LRESULT
WINPROC_UnmapMsg16To32A( HWND16 hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1220 case WM_COMPAREITEM
:
1223 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
1225 case WM_MEASUREITEM
:
1227 MEASUREITEMSTRUCT16
*mis16
;
1228 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)lParam
;
1229 lParam
= *(LPARAM
*)(mis
+ 1);
1230 mis16
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
1231 mis16
->itemWidth
= (UINT16
)mis
->itemWidth
;
1232 mis16
->itemHeight
= (UINT16
)mis
->itemHeight
;
1233 HeapFree( SystemHeap
, 0, mis
);
1236 case WM_GETMINMAXINFO
:
1238 MINMAXINFO
*mmi
= (MINMAXINFO
*)lParam
;
1239 lParam
= *(LPARAM
*)(mmi
+ 1);
1240 STRUCT32_MINMAXINFO32to16( mmi
,
1241 (MINMAXINFO16
*)PTR_SEG_TO_LIN(lParam
));
1242 HeapFree( SystemHeap
, 0, mmi
);
1247 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1248 lParam
= *(LPARAM
*)(cs
+ 1);
1249 STRUCT32_MDICREATESTRUCT32Ato16( cs
,
1250 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1251 HeapFree( SystemHeap
, 0, cs
);
1254 case WM_MDIGETACTIVE
:
1255 result
= MAKELONG( LOWORD(result
), (BOOL16
)(*(BOOL
*)lParam
) );
1256 HeapFree( SystemHeap
, 0, (BOOL
*)lParam
);
1260 NCCALCSIZE_PARAMS16
*nc16
;
1261 NCCALCSIZE_PARAMS
*nc
= (NCCALCSIZE_PARAMS
*)lParam
;
1262 lParam
= *(LPARAM
*)(nc
+ 1);
1263 nc16
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(lParam
);
1264 CONV_RECT32TO16( &nc
->rgrc
[0], &nc16
->rgrc
[0] );
1267 CONV_RECT32TO16( &nc
->rgrc
[1], &nc16
->rgrc
[1] );
1268 CONV_RECT32TO16( &nc
->rgrc
[2], &nc16
->rgrc
[2] );
1271 STRUCT32_WINDOWPOS32to16( nc
->lppos
,
1272 (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc16
->lppos
));
1273 HeapFree( SystemHeap
, 0, nc
->lppos
);
1276 HeapFree( SystemHeap
, 0, nc
);
1282 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1283 lParam
= *(LPARAM
*)(cs
+ 1);
1284 STRUCT32_CREATESTRUCT32Ato16( cs
,
1285 (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1286 HeapFree( SystemHeap
, 0, cs
);
1289 case WM_WINDOWPOSCHANGING
:
1290 case WM_WINDOWPOSCHANGED
:
1292 WINDOWPOS
*wp
= (WINDOWPOS
*)lParam
;
1293 lParam
= *(LPARAM
*)(wp
+ 1);
1294 STRUCT32_WINDOWPOS32to16(wp
,(WINDOWPOS16
*)PTR_SEG_TO_LIN(lParam
));
1295 HeapFree( SystemHeap
, 0, wp
);
1301 LPMSG msg32
= (LPMSG
)lParam
;
1303 WINPROC_UnmapMsg16To32A( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1305 HeapFree( SystemHeap
, 0, msg32
);
1313 /**********************************************************************
1314 * WINPROC_MapMsg16To32W
1316 * Map a message from 16- to 32-bit Unicode.
1317 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1319 INT
WINPROC_MapMsg16To32W( HWND16 hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1320 WPARAM
*pwparam32
, LPARAM
*plparam
)
1326 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
1327 return WINPROC_MapMsg32ATo32W( hwnd
, *pmsg32
, *pwparam32
, plparam
);
1331 CREATESTRUCT16
*cs16
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1332 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)HeapAlloc( SystemHeap
, 0,
1333 sizeof(*cs
) + sizeof(LPARAM
) );
1335 STRUCT32_CREATESTRUCT16to32A( cs16
, (CREATESTRUCTA
*)cs
);
1336 cs
->lpszName
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->lpszName
);
1337 cs
->lpszClass
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->lpszClass
);
1338 if (HIWORD(cs
->lpszName
))
1339 cs
->lpszName
= HEAP_strdupAtoW( SystemHeap
, 0,
1340 (LPCSTR
)cs
->lpszName
);
1341 if (HIWORD(cs
->lpszClass
))
1342 cs
->lpszClass
= HEAP_strdupAtoW( SystemHeap
, 0,
1343 (LPCSTR
)cs
->lpszClass
);
1344 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1345 *plparam
= (LPARAM
)cs
;
1350 MDICREATESTRUCT16
*cs16
=
1351 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1352 MDICREATESTRUCTW
*cs
=
1353 (MDICREATESTRUCTW
*)HeapAlloc( SystemHeap
, 0,
1354 sizeof(*cs
) + sizeof(LPARAM
) );
1356 STRUCT32_MDICREATESTRUCT16to32A( cs16
, (MDICREATESTRUCTA
*)cs
);
1357 cs
->szTitle
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->szTitle
);
1358 cs
->szClass
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->szClass
);
1359 if (HIWORD(cs
->szTitle
))
1360 cs
->szTitle
= HEAP_strdupAtoW( SystemHeap
, 0,
1361 (LPCSTR
)cs
->szTitle
);
1362 if (HIWORD(cs
->szClass
))
1363 cs
->szClass
= HEAP_strdupAtoW( SystemHeap
, 0,
1364 (LPCSTR
)cs
->szClass
);
1365 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1366 *plparam
= (LPARAM
)cs
;
1372 LPMSG16 msg16
= (LPMSG16
)PTR_SEG_TO_LIN(*plparam
);
1373 LPMSG msg32
= (LPMSG
)HeapAlloc( SystemHeap
, 0, sizeof(MSG
) );
1375 if (!msg32
) return -1;
1376 msg32
->hwnd
= msg16
->hwnd
;
1377 msg32
->lParam
= msg16
->lParam
;
1378 msg32
->time
= msg16
->time
;
1379 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1380 /* this is right, right? */
1381 if (WINPROC_MapMsg16To32W(hwnd
, msg16
->message
,msg16
->wParam
,
1382 &msg32
->message
,&msg32
->wParam
,
1383 &msg32
->lParam
)<0) {
1384 HeapFree( SystemHeap
, 0, msg32
);
1387 *plparam
= (LPARAM
)msg32
;
1391 default: /* No Unicode translation needed */
1392 return WINPROC_MapMsg16To32A( msg16
, wParam16
, pmsg32
,
1393 pwparam32
, plparam
);
1398 /**********************************************************************
1399 * WINPROC_UnmapMsg16To32W
1401 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1403 LRESULT
WINPROC_UnmapMsg16To32W( HWND16 hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1410 WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
);
1415 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)lParam
;
1416 lParam
= *(LPARAM
*)(cs
+ 1);
1417 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs
,
1418 (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1419 if (HIWORD(cs
->lpszName
))
1420 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->lpszName
);
1421 if (HIWORD(cs
->lpszClass
))
1422 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->lpszClass
);
1423 HeapFree( SystemHeap
, 0, cs
);
1428 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
1429 lParam
= *(LPARAM
*)(cs
+ 1);
1430 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs
,
1431 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1432 if (HIWORD(cs
->szTitle
))
1433 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->szTitle
);
1434 if (HIWORD(cs
->szClass
))
1435 HeapFree( SystemHeap
, 0, (LPVOID
)cs
->szClass
);
1436 HeapFree( SystemHeap
, 0, cs
);
1442 LPMSG msg32
= (LPMSG
)lParam
;
1444 WINPROC_UnmapMsg16To32W( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1446 HeapFree( SystemHeap
, 0, msg32
);
1450 return WINPROC_UnmapMsg16To32A( hwnd
, msg
, wParam
, lParam
, result
);
1456 /**********************************************************************
1457 * WINPROC_MapMsg32ATo16
1459 * Map a message from 32-bit Ansi to 16-bit.
1460 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1462 INT
WINPROC_MapMsg32ATo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
1463 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
1466 *pmsg16
= (UINT16
)msg32
;
1467 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1475 *pmsg16
= (UINT16
)msg32
+ (BM_GETCHECK16
- BM_GETCHECK
);
1484 case EM_SCROLLCARET
:
1487 case EM_GETLINECOUNT
:
1499 case EM_LINEFROMCHAR
:
1500 case EM_SETTABSTOPS
:
1501 case EM_SETPASSWORDCHAR
:
1502 case EM_EMPTYUNDOBUFFER
:
1503 case EM_GETFIRSTVISIBLELINE
:
1504 case EM_SETREADONLY
:
1505 case EM_SETWORDBREAKPROC
:
1506 case EM_GETWORDBREAKPROC
:
1507 case EM_GETPASSWORDCHAR
:
1508 *pmsg16
= (UINT16
)msg32
+ (EM_GETSEL16
- EM_GETSEL
);
1513 case LB_DELETESTRING
:
1514 case LB_GETANCHORINDEX
:
1515 case LB_GETCARETINDEX
:
1518 case LB_GETHORIZONTALEXTENT
:
1519 case LB_GETITEMDATA
:
1520 case LB_GETITEMHEIGHT
:
1522 case LB_GETSELCOUNT
:
1524 case LB_GETTOPINDEX
:
1525 case LB_RESETCONTENT
:
1526 case LB_SELITEMRANGE
:
1527 case LB_SELITEMRANGEEX
:
1528 case LB_SETANCHORINDEX
:
1529 case LB_SETCARETINDEX
:
1530 case LB_SETCOLUMNWIDTH
:
1532 case LB_SETHORIZONTALEXTENT
:
1533 case LB_SETITEMDATA
:
1534 case LB_SETITEMHEIGHT
:
1536 case LB_SETTOPINDEX
:
1537 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1539 case CB_DELETESTRING
:
1541 case CB_GETLBTEXTLEN
:
1543 case CB_RESETCONTENT
:
1547 case CB_SHOWDROPDOWN
:
1548 case CB_SETITEMDATA
:
1549 case CB_SETITEMHEIGHT
:
1550 case CB_GETITEMHEIGHT
:
1551 case CB_SETEXTENDEDUI
:
1552 case CB_GETEXTENDEDUI
:
1553 case CB_GETDROPPEDSTATE
:
1554 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1557 *pmsg16
= CB_GETEDITSEL16
;
1562 case LB_FINDSTRINGEXACT
:
1563 case LB_INSERTSTRING
:
1564 case LB_SELECTSTRING
:
1568 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
1569 if (!str
) return -1;
1570 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1572 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1577 case CB_FINDSTRINGEXACT
:
1578 case CB_INSERTSTRING
:
1579 case CB_SELECTSTRING
:
1582 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
1583 if (!str
) return -1;
1584 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1586 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1589 case LB_GETITEMRECT
:
1592 rect
= (RECT16
*)SEGPTR_ALLOC( sizeof(RECT16
) + sizeof(LPARAM
) );
1593 if (!rect
) return -1;
1594 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1595 *plparam
= (LPARAM
)SEGPTR_GET(rect
);
1597 *pmsg16
= LB_GETITEMRECT16
;
1599 case LB_GETSELITEMS
:
1602 *pwparam16
= (WPARAM16
)MIN( wParam32
, 0x7f80 ); /* Must be < 64K */
1603 if (!(items
= SEGPTR_ALLOC( *pwparam16
* sizeof(INT16
)
1604 + sizeof(LPARAM
)))) return -1;
1605 *((LPARAM
*)items
)++ = *plparam
; /* Store the previous lParam */
1606 *plparam
= (LPARAM
)SEGPTR_GET(items
);
1608 *pmsg16
= LB_GETSELITEMS16
;
1610 case LB_SETTABSTOPS
:
1615 *pwparam16
= (WPARAM16
)MIN( wParam32
, 0x7f80 ); /* Must be < 64K */
1616 if (!(stops
= SEGPTR_ALLOC( *pwparam16
* sizeof(INT16
)
1617 + sizeof(LPARAM
)))) return -1;
1618 for (i
= 0; i
< *pwparam16
; i
++) stops
[i
] = *((LPINT
)*plparam
+i
);
1619 *plparam
= (LPARAM
)SEGPTR_GET(stops
);
1622 *pmsg16
= LB_SETTABSTOPS16
;
1625 case CB_GETDROPPEDCONTROLRECT
:
1628 rect
= (RECT16
*)SEGPTR_ALLOC( sizeof(RECT16
) + sizeof(LPARAM
) );
1629 if (!rect
) return -1;
1630 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1631 *plparam
= (LPARAM
)SEGPTR_GET(rect
);
1633 *pmsg16
= CB_GETDROPPEDCONTROLRECT16
;
1637 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1638 *pmsg16
= LB_GETTEXT16
;
1642 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1643 *pmsg16
= CB_GETLBTEXT16
;
1648 *plparam
= MAKELONG( (INT16
)(INT
)wParam32
, (INT16
)*plparam
);
1649 *pmsg16
= EM_SETSEL16
;
1656 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
1660 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
1662 case WM_CTLCOLORMSGBOX
:
1663 case WM_CTLCOLOREDIT
:
1664 case WM_CTLCOLORLISTBOX
:
1665 case WM_CTLCOLORBTN
:
1666 case WM_CTLCOLORDLG
:
1667 case WM_CTLCOLORSCROLLBAR
:
1668 case WM_CTLCOLORSTATIC
:
1669 *pmsg16
= WM_CTLCOLOR
;
1670 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
1671 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
1673 case WM_COMPAREITEM
:
1675 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)*plparam
;
1676 COMPAREITEMSTRUCT16
*cis
= SEGPTR_NEW(COMPAREITEMSTRUCT16
);
1677 if (!cis
) return -1;
1678 cis
->CtlType
= (UINT16
)cis32
->CtlType
;
1679 cis
->CtlID
= (UINT16
)cis32
->CtlID
;
1680 cis
->hwndItem
= (HWND16
)cis32
->hwndItem
;
1681 cis
->itemID1
= (UINT16
)cis32
->itemID1
;
1682 cis
->itemData1
= cis32
->itemData1
;
1683 cis
->itemID2
= (UINT16
)cis32
->itemID2
;
1684 cis
->itemData2
= cis32
->itemData2
;
1685 *plparam
= (LPARAM
)SEGPTR_GET(cis
);
1690 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)*plparam
;
1691 DELETEITEMSTRUCT16
*dis
= SEGPTR_NEW(DELETEITEMSTRUCT16
);
1692 if (!dis
) return -1;
1693 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1694 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1695 dis
->itemID
= (UINT16
)dis32
->itemID
;
1696 dis
->hwndItem
= (HWND16
)dis32
->hwndItem
;
1697 dis
->itemData
= dis32
->itemData
;
1698 *plparam
= (LPARAM
)SEGPTR_GET(dis
);
1703 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)*plparam
;
1704 DRAWITEMSTRUCT16
*dis
= SEGPTR_NEW(DRAWITEMSTRUCT16
);
1705 if (!dis
) return -1;
1706 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1707 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1708 dis
->itemID
= (UINT16
)dis32
->itemID
;
1709 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
1710 dis
->itemState
= (UINT16
)dis32
->itemState
;
1711 dis
->hwndItem
= (HWND16
)dis32
->hwndItem
;
1712 dis
->hDC
= (HDC16
)dis32
->hDC
;
1713 dis
->itemData
= dis32
->itemData
;
1714 CONV_RECT32TO16( &dis32
->rcItem
, &dis
->rcItem
);
1715 *plparam
= (LPARAM
)SEGPTR_GET(dis
);
1718 case WM_MEASUREITEM
:
1720 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)*plparam
;
1721 MEASUREITEMSTRUCT16
*mis
= (MEASUREITEMSTRUCT16
*)
1722 SEGPTR_ALLOC(sizeof(*mis
)+sizeof(LPARAM
));
1723 if (!mis
) return -1;
1724 mis
->CtlType
= (UINT16
)mis32
->CtlType
;
1725 mis
->CtlID
= (UINT16
)mis32
->CtlID
;
1726 mis
->itemID
= (UINT16
)mis32
->itemID
;
1727 mis
->itemWidth
= (UINT16
)mis32
->itemWidth
;
1728 mis
->itemHeight
= (UINT16
)mis32
->itemHeight
;
1729 mis
->itemData
= mis32
->itemData
;
1730 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1731 *plparam
= (LPARAM
)SEGPTR_GET(mis
);
1734 case WM_GETMINMAXINFO
:
1736 MINMAXINFO16
*mmi
= (MINMAXINFO16
*)SEGPTR_ALLOC( sizeof(*mmi
) +
1738 if (!mmi
) return -1;
1739 STRUCT32_MINMAXINFO32to16( (MINMAXINFO
*)*plparam
, mmi
);
1740 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1741 *plparam
= (LPARAM
)SEGPTR_GET(mmi
);
1747 *pwparam16
= (WPARAM16
)MIN( wParam32
, 0xff80 ); /* Must be < 64K */
1748 if (!(str
= SEGPTR_ALLOC(*pwparam16
+ sizeof(LPARAM
)))) return -1;
1749 *((LPARAM
*)str
)++ = *plparam
; /* Store the previous lParam */
1750 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1755 MDICREATESTRUCT16
*cs
;
1756 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)*plparam
;
1759 if (!(cs
= SEGPTR_NEW(MDICREATESTRUCT16
))) return -1;
1760 STRUCT32_MDICREATESTRUCT32Ato16( cs32
, cs
);
1761 name
= SEGPTR_STRDUP( cs32
->szTitle
);
1762 cls
= SEGPTR_STRDUP( cs32
->szClass
);
1763 cs
->szTitle
= SEGPTR_GET(name
);
1764 cs
->szClass
= SEGPTR_GET(cls
);
1765 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
1768 case WM_MDIGETACTIVE
:
1771 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
1772 (HMENU16
)LOWORD(*plparam
) );
1773 *pwparam16
= (*plparam
== 0);
1777 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
1779 case WM_MDIACTIVATE
:
1781 WND
*tempWnd
= WIN_FindWndPtr(hwnd
);
1782 if( WIDGETS_IsControl(tempWnd
, BIC32_MDICLIENT
) )
1784 *pwparam16
= (HWND
)wParam32
;
1789 *pwparam16
= ((HWND
)*plparam
== hwnd
);
1790 *plparam
= MAKELPARAM( (HWND16
)LOWORD(*plparam
),
1791 (HWND16
)LOWORD(wParam32
) );
1793 WIN_ReleaseWndPtr(tempWnd
);
1798 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)*plparam
;
1799 NCCALCSIZE_PARAMS16
*nc
= (NCCALCSIZE_PARAMS16
*)SEGPTR_ALLOC( sizeof(*nc
) + sizeof(LPARAM
) );
1802 CONV_RECT32TO16( &nc32
->rgrc
[0], &nc
->rgrc
[0] );
1806 CONV_RECT32TO16( &nc32
->rgrc
[1], &nc
->rgrc
[1] );
1807 CONV_RECT32TO16( &nc32
->rgrc
[2], &nc
->rgrc
[2] );
1808 if (!(wp
= SEGPTR_NEW(WINDOWPOS16
)))
1813 STRUCT32_WINDOWPOS32to16( nc32
->lppos
, wp
);
1814 nc
->lppos
= SEGPTR_GET(wp
);
1816 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1817 *plparam
= (LPARAM
)SEGPTR_GET(nc
);
1824 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)*plparam
;
1827 if (!(cs
= SEGPTR_NEW(CREATESTRUCT16
))) return -1;
1828 STRUCT32_CREATESTRUCT32Ato16( cs32
, cs
);
1829 name
= SEGPTR_STRDUP( cs32
->lpszName
);
1830 cls
= SEGPTR_STRDUP( cs32
->lpszClass
);
1831 cs
->lpszName
= SEGPTR_GET(name
);
1832 cs
->lpszClass
= SEGPTR_GET(cls
);
1833 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
1836 case WM_PARENTNOTIFY
:
1837 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
1838 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
1839 /* else nothing to do */
1842 *plparam
= MapLS( (NMHDR
*)*plparam
); /* NMHDR is already 32-bit */
1846 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
1847 if (!str
) return -1;
1848 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1851 case WM_WINDOWPOSCHANGING
:
1852 case WM_WINDOWPOSCHANGED
:
1854 WINDOWPOS16
*wp
= (WINDOWPOS16
*)SEGPTR_ALLOC( sizeof(*wp
) +
1857 STRUCT32_WINDOWPOS32to16( (WINDOWPOS
*)*plparam
, wp
);
1858 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1859 *plparam
= (LPARAM
)SEGPTR_GET(wp
);
1864 LPMSG msg32
= (LPMSG
) *plparam
;
1865 LPMSG16 msg16
= (LPMSG16
) SEGPTR_NEW( MSG16
);
1867 if (!msg16
) return -1;
1868 msg16
->hwnd
= msg32
->hwnd
;
1869 msg16
->lParam
= msg32
->lParam
;
1870 msg16
->time
= msg32
->time
;
1871 CONV_POINT32TO16(&msg32
->pt
,&msg16
->pt
);
1872 /* this is right, right? */
1873 if (WINPROC_MapMsg32ATo16(msg32
->hwnd
,msg32
->message
,msg32
->wParam
,
1874 &msg16
->message
,&msg16
->wParam
, &msg16
->lParam
)<0) {
1875 SEGPTR_FREE( msg16
);
1878 *plparam
= (LPARAM
)SEGPTR_GET(msg16
);
1883 case WM_ACTIVATEAPP
:
1885 *plparam
= (LPARAM
)THREAD_IdToTEB((DWORD
) *plparam
)->htask16
;
1888 case WM_ASKCBFORMATNAME
:
1889 case WM_DEVMODECHANGE
:
1890 case WM_PAINTCLIPBOARD
:
1891 case WM_SIZECLIPBOARD
:
1892 case WM_WININICHANGE
:
1893 FIXME_(msg
)("message %04x needs translation\n", msg32
);
1895 default: /* No translation needed */
1901 /**********************************************************************
1902 * WINPROC_UnmapMsg32ATo16
1904 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1906 void WINPROC_UnmapMsg32ATo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1915 case LB_FINDSTRINGEXACT
:
1916 case LB_INSERTSTRING
:
1917 case LB_SELECTSTRING
:
1918 case LB_SETTABSTOPS
:
1921 case CB_FINDSTRINGEXACT
:
1922 case CB_INSERTSTRING
:
1923 case CB_SELECTSTRING
:
1925 case WM_COMPAREITEM
:
1929 SEGPTR_FREE( PTR_SEG_TO_LIN(p16
->lParam
) );
1932 case CB_GETDROPPEDCONTROLRECT
:
1933 case LB_GETITEMRECT
:
1935 RECT16
*rect
= (RECT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
1936 p16
->lParam
= *(LPARAM
*)(rect
+ 1);
1937 CONV_RECT16TO32( rect
, (RECT
*)(p16
->lParam
));
1938 SEGPTR_FREE( rect
);
1941 case LB_GETSELITEMS
:
1944 LPINT16 items
= (LPINT16
)PTR_SEG_TO_LIN(lParam
);
1945 p16
->lParam
= *((LPARAM
*)items
- 1);
1946 for (i
= 0; i
< p16
->wParam
; i
++) *((LPINT
)(p16
->lParam
) + i
) = items
[i
];
1947 SEGPTR_FREE( (LPARAM
*)items
- 1 );
1953 *((LPUINT
)(wParam
)) = LOWORD(p16
->lResult
);
1955 *((LPUINT
)(lParam
)) = HIWORD(p16
->lResult
); /* FIXME: substract 1? */
1960 UnMapLS( (SEGPTR
)(p16
->lParam
) );
1963 case WM_MEASUREITEM
:
1965 MEASUREITEMSTRUCT16
*mis
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
1966 MEASUREITEMSTRUCT
*mis32
= *(MEASUREITEMSTRUCT
**)(mis
+ 1);
1967 mis32
->itemWidth
= mis
->itemWidth
;
1968 mis32
->itemHeight
= mis
->itemHeight
;
1972 case WM_GETMINMAXINFO
:
1974 MINMAXINFO16
*mmi
= (MINMAXINFO16
*)PTR_SEG_TO_LIN(p16
->lParam
);
1975 p16
->lParam
= *(LPARAM
*)(mmi
+ 1);
1976 STRUCT32_MINMAXINFO16to32( mmi
, (MINMAXINFO
*)(p16
->lParam
) );
1982 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(p16
->lParam
);
1983 p16
->lParam
= *((LPARAM
*)str
- 1);
1984 lstrcpynA( (LPSTR
)(p16
->lParam
), str
, p16
->wParam
);
1985 SEGPTR_FREE( (LPARAM
*)str
- 1 );
1990 MDICREATESTRUCT16
*cs
= (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
1991 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->szTitle
) );
1992 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->szClass
) );
1996 case WM_MDIGETACTIVE
:
1997 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(p16
->lResult
);
1998 p16
->lResult
= (HWND
)LOWORD(p16
->lResult
);
2002 NCCALCSIZE_PARAMS
*nc32
;
2003 NCCALCSIZE_PARAMS16
*nc
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2004 p16
->lParam
= *(LPARAM
*)(nc
+ 1);
2005 nc32
= (NCCALCSIZE_PARAMS
*)(p16
->lParam
);
2006 CONV_RECT16TO32( &nc
->rgrc
[0], &nc32
->rgrc
[0] );
2009 CONV_RECT16TO32( &nc
->rgrc
[1], &nc32
->rgrc
[1] );
2010 CONV_RECT16TO32( &nc
->rgrc
[2], &nc32
->rgrc
[2] );
2011 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc
->lppos
),
2013 SEGPTR_FREE( PTR_SEG_TO_LIN(nc
->lppos
) );
2021 CREATESTRUCT16
*cs
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2022 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->lpszName
) );
2023 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->lpszClass
) );
2027 case WM_WINDOWPOSCHANGING
:
2028 case WM_WINDOWPOSCHANGED
:
2030 WINDOWPOS16
*wp
= (WINDOWPOS16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2031 p16
->lParam
= *(LPARAM
*)(wp
+ 1);
2032 STRUCT32_WINDOWPOS16to32( wp
, (WINDOWPOS
*)p16
->lParam
);
2037 UnMapLS(p16
->lParam
);
2042 LPMSG16 msg16
= (LPMSG16
)PTR_SEG_TO_LIN(p16
->lParam
);
2044 msgp16
.wParam
=msg16
->wParam
;
2045 msgp16
.lParam
=msg16
->lParam
;
2046 WINPROC_UnmapMsg32ATo16(((LPMSG
)lParam
)->hwnd
, ((LPMSG
)lParam
)->message
,
2047 ((LPMSG
)lParam
)->wParam
, ((LPMSG
)lParam
)->lParam
,
2056 /**********************************************************************
2057 * WINPROC_MapMsg32WTo16
2059 * Map a message from 32-bit Unicode to 16-bit.
2060 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2062 INT
WINPROC_MapMsg32WTo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
2063 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
2070 case LB_FINDSTRINGEXACT
:
2071 case LB_INSERTSTRING
:
2072 case LB_SELECTSTRING
:
2076 LPSTR str
= SEGPTR_STRDUP_WtoA( (LPWSTR
)*plparam
);
2077 if (!str
) return -1;
2078 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
2079 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2081 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2086 case CB_FINDSTRINGEXACT
:
2087 case CB_INSERTSTRING
:
2088 case CB_SELECTSTRING
:
2091 LPSTR str
= SEGPTR_STRDUP_WtoA( (LPWSTR
)*plparam
);
2092 if (!str
) return -1;
2093 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
2094 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2096 *pmsg16
= (UINT16
)msg32
+ (CB_ADDSTRING16
- CB_ADDSTRING
);
2103 CREATESTRUCTW
*cs32
= (CREATESTRUCTW
*)*plparam
;
2106 if (!(cs
= SEGPTR_NEW(CREATESTRUCT16
))) return -1;
2107 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs32
, cs
);
2108 name
= SEGPTR_STRDUP_WtoA( cs32
->lpszName
);
2109 cls
= SEGPTR_STRDUP_WtoA( cs32
->lpszClass
);
2110 cs
->lpszName
= SEGPTR_GET(name
);
2111 cs
->lpszClass
= SEGPTR_GET(cls
);
2112 *pmsg16
= (UINT16
)msg32
;
2113 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
2114 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
2119 MDICREATESTRUCT16
*cs
;
2120 MDICREATESTRUCTW
*cs32
= (MDICREATESTRUCTW
*)*plparam
;
2123 if (!(cs
= SEGPTR_NEW(MDICREATESTRUCT16
))) return -1;
2124 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs32
, cs
);
2125 name
= SEGPTR_STRDUP_WtoA( cs32
->szTitle
);
2126 cls
= SEGPTR_STRDUP_WtoA( cs32
->szClass
);
2127 cs
->szTitle
= SEGPTR_GET(name
);
2128 cs
->szClass
= SEGPTR_GET(cls
);
2129 *pmsg16
= (UINT16
)msg32
;
2130 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
2131 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
2136 LPSTR str
= SEGPTR_STRDUP_WtoA( (LPWSTR
)*plparam
);
2137 if (!str
) return -1;
2138 *pmsg16
= (UINT16
)msg32
;
2139 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
2140 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2143 default: /* No Unicode translation needed */
2144 return WINPROC_MapMsg32ATo16( hwnd
, msg32
, wParam32
, pmsg16
,
2145 pwparam16
, plparam
);
2150 /**********************************************************************
2151 * WINPROC_UnmapMsg32WTo16
2153 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2155 void WINPROC_UnmapMsg32WTo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2162 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(p16
->lParam
);
2163 p16
->lParam
= *((LPARAM
*)str
- 1);
2164 lstrcpyAtoW( (LPWSTR
)(p16
->lParam
), str
);
2165 SEGPTR_FREE( (LPARAM
*)str
- 1 );
2169 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, p16
);
2175 /**********************************************************************
2176 * WINPROC_CallProc32ATo32W
2178 * Call a window procedure, translating args from Ansi to Unicode.
2180 static LRESULT
WINPROC_CallProc32ATo32W( WNDPROC func
, HWND hwnd
,
2181 UINT msg
, WPARAM wParam
,
2186 if (WINPROC_MapMsg32ATo32W( hwnd
, msg
, wParam
, &lParam
) == -1) return 0;
2187 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2188 WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
);
2193 /**********************************************************************
2194 * WINPROC_CallProc32WTo32A
2196 * Call a window procedure, translating args from Unicode to Ansi.
2198 static LRESULT
WINPROC_CallProc32WTo32A( WNDPROC func
, HWND hwnd
,
2199 UINT msg
, WPARAM wParam
,
2204 if (WINPROC_MapMsg32WTo32A( hwnd
, msg
, wParam
, &lParam
) == -1) return 0;
2205 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2206 WINPROC_UnmapMsg32WTo32A( hwnd
, msg
, wParam
, lParam
);
2211 /**********************************************************************
2212 * WINPROC_CallProc16To32A
2214 * Call a 32-bit window procedure, translating the 16-bit args.
2216 static LRESULT
WINPROC_CallProc16To32A( WNDPROC func
, HWND16 hwnd
,
2217 UINT16 msg
, WPARAM16 wParam
,
2224 if (WINPROC_MapMsg16To32A( msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2226 result
= WINPROC_CallWndProc( func
, hwnd
, msg32
, wParam32
, lParam
);
2227 return WINPROC_UnmapMsg16To32A( hwnd
, msg32
, wParam32
, lParam
, result
);
2230 /**********************************************************************
2231 * WINPROC_Thunk16To32A
2233 static LRESULT WINAPI
WINPROC_Thunk16To32A( WNDPROC func
, LPBYTE args
)
2235 HWND16 hwnd
= *(HWND16
*)( args
+8 );
2236 UINT16 msg
= *(HWND16
*)( args
+6 );
2237 WPARAM16 wParam
= *(HWND16
*)( args
+4 );
2238 LPARAM lParam
= *(LPARAM
*)( args
+0 );
2240 return WINPROC_CallProc16To32A( func
, hwnd
, msg
, wParam
, lParam
);
2244 /**********************************************************************
2245 * WINPROC_CallProc16To32W
2247 * Call a 32-bit window procedure, translating the 16-bit args.
2249 static LRESULT
WINPROC_CallProc16To32W( WNDPROC func
, HWND16 hwnd
,
2250 UINT16 msg
, WPARAM16 wParam
,
2257 if (WINPROC_MapMsg16To32W( hwnd
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2260 result
= WINPROC_CallWndProc( func
, hwnd
, msg32
, wParam32
, lParam
);
2262 return WINPROC_UnmapMsg16To32W( hwnd
, msg32
, wParam32
, lParam
, result
);
2265 /**********************************************************************
2266 * WINPROC_Thunk16To32W
2268 static LRESULT WINAPI
WINPROC_Thunk16To32W( WNDPROC func
, LPBYTE args
)
2270 HWND16 hwnd
= *(HWND16
*)( args
+8 );
2271 UINT16 msg
= *(HWND16
*)( args
+6 );
2272 WPARAM16 wParam
= *(HWND16
*)( args
+4 );
2273 LPARAM lParam
= *(LPARAM
*)( args
+0 );
2275 return WINPROC_CallProc16To32W( func
, hwnd
, msg
, wParam
, lParam
);
2278 /**********************************************************************
2279 * WINPROC_CallProc32ATo16
2281 * Call a 16-bit window procedure, translating the 32-bit args.
2283 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
2284 UINT msg
, WPARAM wParam
,
2290 mp16
.lParam
= lParam
;
2291 if (WINPROC_MapMsg32ATo16( hwnd
, msg
, wParam
,
2292 &msg16
, &mp16
.wParam
, &mp16
.lParam
) == -1)
2294 mp16
.lResult
= WINPROC_CallWndProc16( func
, hwnd
, msg16
,
2295 mp16
.wParam
, mp16
.lParam
);
2296 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2297 return mp16
.lResult
;
2301 /**********************************************************************
2302 * WINPROC_CallProc32WTo16
2304 * Call a 16-bit window procedure, translating the 32-bit args.
2306 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
2307 UINT msg
, WPARAM wParam
,
2313 mp16
.lParam
= lParam
;
2314 if (WINPROC_MapMsg32WTo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
,
2315 &mp16
.lParam
) == -1)
2317 mp16
.lResult
= WINPROC_CallWndProc16( func
, hwnd
, msg16
,
2318 mp16
.wParam
, mp16
.lParam
);
2319 WINPROC_UnmapMsg32WTo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2320 return mp16
.lResult
;
2324 /**********************************************************************
2325 * CallWindowProc16 (USER.122)
2327 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
2328 WPARAM16 wParam
, LPARAM lParam
)
2330 WINDOWPROC
*proc
= WINPROC_GetPtr( func
);
2333 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2336 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_16
);
2337 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2343 if (!proc
->thunk
.t_from32
.proc
) return 0;
2344 return WINPROC_CallWndProc16( proc
->thunk
.t_from32
.proc
,
2345 hwnd
, msg
, wParam
, lParam
);
2347 if (!proc
->thunk
.t_from16
.proc
) return 0;
2348 return WINPROC_CallProc16To32A( proc
->thunk
.t_from16
.proc
,
2349 hwnd
, msg
, wParam
, lParam
);
2351 if (!proc
->thunk
.t_from16
.proc
) return 0;
2352 return WINPROC_CallProc16To32W( proc
->thunk
.t_from16
.proc
,
2353 hwnd
, msg
, wParam
, lParam
);
2355 WARN_(relay
)("Invalid proc %p\n", proc
);
2361 /**********************************************************************
2362 * CallWindowProc32A (USER32.18)
2364 * The CallWindowProc() function invokes the windows procedure _func_,
2365 * with _hwnd_ as the target window, the message specified by _msg_, and
2366 * the message parameters _wParam_ and _lParam_.
2368 * Some kinds of argument conversion may be done, I'm not sure what.
2370 * CallWindowProc() may be used for windows subclassing. Use
2371 * SetWindowLong() to set a new windows procedure for windows of the
2372 * subclass, and handle subclassed messages in the new windows
2373 * procedure. The new windows procedure may then use CallWindowProc()
2374 * with _func_ set to the parent class's windows procedure to dispatch
2375 * the message to the superclass.
2379 * The return value is message dependent.
2385 LRESULT WINAPI
CallWindowProcA(
2386 WNDPROC func
, /* window procedure */
2387 HWND hwnd
, /* target window */
2388 UINT msg
, /* message */
2389 WPARAM wParam
, /* message dependent parameter */
2390 LPARAM lParam
/* message dependent parameter */
2392 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2394 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2397 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32A
);
2398 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2404 if (!proc
->thunk
.t_from32
.proc
) return 0;
2405 return WINPROC_CallProc32ATo16( proc
->thunk
.t_from32
.proc
,
2406 hwnd
, msg
, wParam
, lParam
);
2408 if (!proc
->thunk
.t_from16
.proc
) return 0;
2409 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2410 hwnd
, msg
, wParam
, lParam
);
2412 if (!proc
->thunk
.t_from16
.proc
) return 0;
2413 return WINPROC_CallProc32ATo32W( proc
->thunk
.t_from16
.proc
,
2414 hwnd
, msg
, wParam
, lParam
);
2416 WARN_(relay
)("Invalid proc %p\n", proc
);
2422 /**********************************************************************
2423 * CallWindowProc32W (USER32.19)
2425 LRESULT WINAPI
CallWindowProcW( WNDPROC func
, HWND hwnd
, UINT msg
,
2426 WPARAM wParam
, LPARAM lParam
)
2428 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2430 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2433 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32W
);
2434 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2440 if (!proc
->thunk
.t_from32
.proc
) return 0;
2441 return WINPROC_CallProc32WTo16( proc
->thunk
.t_from32
.proc
,
2442 hwnd
, msg
, wParam
, lParam
);
2444 if (!proc
->thunk
.t_from16
.proc
) return 0;
2445 return WINPROC_CallProc32WTo32A( proc
->thunk
.t_from16
.proc
,
2446 hwnd
, msg
, wParam
, lParam
);
2448 if (!proc
->thunk
.t_from16
.proc
) return 0;
2449 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2450 hwnd
, msg
, wParam
, lParam
);
2452 WARN_(relay
)("Invalid proc %p\n", proc
);