2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
11 #include "wine/winbase16.h"
12 #include "wine/winuser16.h"
13 #include "wine/winestring.h"
14 #include "stackframe.h"
15 #include "builtin16.h"
17 #include "selectors.h"
21 #include "debugtools.h"
28 DECLARE_DEBUG_CHANNEL(msg
)
29 DECLARE_DEBUG_CHANNEL(relay
)
30 DECLARE_DEBUG_CHANNEL(win
)
32 /* Window procedure 16-to-32-bit thunk,
33 * see BuildSpec16File() in tools/build.c */
38 WORD pushw_bp
; /* pushw %bp */
39 BYTE pushl_func
; /* pushl $proc */
41 WORD pushw_ax
; /* pushw %ax */
42 BYTE pushl_relay
; /* pushl $relay */
43 void (*relay
)(); /* WINPROC_Thunk16To32A/W() */
44 BYTE lcall
; /* lcall cs:glue */
45 void (*glue
)(); /* CallFrom16Long */
46 WORD cs
; /* __FLATCS */
47 WORD lret
; /* lret $10 */
49 } WINPROC_THUNK_FROM16
;
52 /* Window procedure 32-to-16-bit thunk,
53 * see BuildSpec32File() in tools/build.c */
57 BYTE popl_eax
; /* popl %eax (return address) */
58 BYTE pushl_func
; /* pushl $proc */
59 WNDPROC16 proc WINE_PACKED
;
60 BYTE pushl_eax
; /* pushl %eax */
61 BYTE jmp
; /* jmp relay (relative jump)*/
62 void (*relay
)() WINE_PACKED
; /* WINPROC_CallProc32ATo16() */
63 } WINPROC_THUNK_FROM32
;
65 /* Simple jmp to call 32-bit procedure directly */
68 BYTE jmp
; /* jmp proc (relative jump) */
69 WNDPROC proc WINE_PACKED
;
74 WINPROC_THUNK_FROM16 t_from16
;
75 WINPROC_THUNK_FROM32 t_from32
;
78 typedef struct tagWINDOWPROC
80 WINPROC_THUNK thunk
; /* Thunk */
81 WINPROC_JUMP jmp
; /* Jump */
82 struct tagWINDOWPROC
*next
; /* Next window proc */
83 UINT magic
; /* Magic number */
84 WINDOWPROCTYPE type
; /* Function type */
85 WINDOWPROCUSER user
; /* Function user */
88 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
90 #define WINPROC_THUNKPROC(pproc) \
91 (((pproc)->type == WIN_PROC_16) ? \
92 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
93 (WNDPROC16)((pproc)->thunk.t_from16.proc))
95 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
96 UINT msg
, WPARAM wParam
,
98 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
99 UINT msg
, WPARAM wParam
,
101 static LRESULT WINAPI
WINPROC_Thunk16To32A( WNDPROC func
, LPBYTE args
);
102 static LRESULT WINAPI
WINPROC_Thunk16To32W( WNDPROC func
, LPBYTE args
);
104 static HANDLE WinProcHeap
;
107 /**********************************************************************
110 BOOL
WINPROC_Init(void)
112 WinProcHeap
= HeapCreate( HEAP_WINE_SEGPTR
| HEAP_WINE_CODESEG
, 0, 0 );
115 WARN_(relay
)("Unable to create winproc heap\n" );
123 /* Some window procedures modify register they shouldn't, or are not
124 * properly declared stdcall; so we need a small assembly wrapper to
126 extern LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
127 WPARAM wParam
, LPARAM lParam
);
128 __ASM_GLOBAL_FUNC( WINPROC_wrapper
,
138 "movl 8(%ebp),%eax\n\t"
140 "leal -12(%ebp),%esp\n\t"
147 static inline LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
148 WPARAM wParam
, LPARAM lParam
)
150 return proc( hwnd
, msg
, wParam
, lParam
);
152 #endif /* __i386__ */
154 /**********************************************************************
155 * WINPROC_CallWndProc32
157 * Call a 32-bit WndProc.
159 static LRESULT
WINPROC_CallWndProc( WNDPROC proc
, HWND hwnd
, UINT msg
,
160 WPARAM wParam
, LPARAM lParam
)
165 TRACE_(relay
)("(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
166 proc
, hwnd
, SPY_GetMsgName(msg
), wParam
, lParam
);
167 /* To avoid any deadlocks, all the locks on the windows structures
168 must be suspended before the control is passed to the application */
169 iWndsLocks
= WIN_SuspendWndsLock();
170 retvalue
= WINPROC_wrapper( proc
, hwnd
, msg
, wParam
, lParam
);
171 WIN_RestoreWndsLock(iWndsLocks
);
172 TRACE_(relay
)("(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx) ret=%08lx\n",
173 proc
, hwnd
, SPY_GetMsgName(msg
), wParam
, lParam
, retvalue
);
177 /***********************************************************************
178 * WINPROC_CallWndProc16
180 * Call a 16-bit window procedure
182 static LRESULT WINAPI
WINPROC_CallWndProc16( WNDPROC16 proc
, HWND16 hwnd
,
183 UINT16 msg
, WPARAM16 wParam
,
189 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
191 TEB
*teb
= NtCurrentTeb();
194 /* Window procedures want ax = hInstance, ds = es = ss */
196 memset(&context
, '\0', sizeof(context
));
197 context
.SegDs
= context
.SegEs
= SELECTOROF(teb
->cur_stack
);
198 context
.Eax
= wndPtr
? wndPtr
->hInstance
: context
.SegDs
;
199 context
.SegCs
= SELECTOROF(proc
);
200 context
.Eip
= OFFSETOF(proc
);
201 context
.Ebp
= OFFSETOF(teb
->cur_stack
)
202 + (WORD
)&((STACK16FRAME
*)0)->bp
;
204 WIN_ReleaseWndPtr(wndPtr
);
208 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
209 work if structures passed in lParam are placed in the stack/data
210 segment. Programmers easily make the mistake of converting lParam
211 to a near rather than a far pointer, since Windows apparently
212 allows this. We copy the structures to the 16 bit stack; this is
213 ugly but makes these programs work. */
218 offset
= sizeof(CREATESTRUCT16
); break;
220 offset
= sizeof(DRAWITEMSTRUCT16
); break;
222 offset
= sizeof(COMPAREITEMSTRUCT16
); break;
226 void *s
= PTR_SEG_TO_LIN(lParam
);
227 lParam
= stack16_push( offset
);
228 memcpy( PTR_SEG_TO_LIN(lParam
), s
, offset
);
232 iWndsLocks
= WIN_SuspendWndsLock();
234 args
= (WORD
*)THREAD_STACK16(teb
) - 5;
235 args
[0] = LOWORD(lParam
);
236 args
[1] = HIWORD(lParam
);
241 CallTo16RegisterShort( &context
, 5 * sizeof(WORD
) );
242 ret
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
243 if (offset
) stack16_pop( offset
);
245 WIN_RestoreWndsLock(iWndsLocks
);
251 /**********************************************************************
254 * Return a pointer to the win proc.
256 static WINDOWPROC
*WINPROC_GetPtr( WNDPROC16 handle
)
261 /* Check for a linear pointer */
263 if (HEAP_IsInsideHeap( WinProcHeap
, 0, (LPVOID
)handle
))
265 ptr
= (BYTE
*)handle
;
266 /* First check if it is the jmp address */
267 if (*ptr
== 0xe9 /* jmp */) ptr
-= (int)&((WINDOWPROC
*)0)->jmp
-
268 (int)&((WINDOWPROC
*)0)->thunk
;
269 /* Now it must be the thunk address */
270 if (*ptr
== 0x58 /* popl eax */) ptr
-= (int)&((WINDOWPROC
*)0)->thunk
;
271 /* Now we have a pointer to the WINDOWPROC struct */
272 if (((WINDOWPROC
*)ptr
)->magic
== WINPROC_MAGIC
)
273 return (WINDOWPROC
*)ptr
;
276 /* Check for a segmented pointer */
278 if (!IsBadReadPtr16((SEGPTR
)handle
,sizeof(WINDOWPROC
)-sizeof(proc
->thunk
)))
280 ptr
= (BYTE
*)PTR_SEG_TO_LIN(handle
);
281 if (!HEAP_IsInsideHeap( WinProcHeap
, 0, ptr
)) return NULL
;
282 /* It must be the thunk address */
283 if (*ptr
== 0x58 /* popl eax */) ptr
-= (int)&((WINDOWPROC
*)0)->thunk
;
284 /* Now we have a pointer to the WINDOWPROC struct */
285 if (((WINDOWPROC
*)ptr
)->magic
== WINPROC_MAGIC
)
286 return (WINDOWPROC
*)ptr
;
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*)CallFrom16Long
;
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_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR, WM_SYSDEADCHAR
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 wParam
, LPARAM
*plparam
)
562 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
563 wParam
* 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
;
666 case WM_ASKCBFORMATNAME
:
667 case WM_DEVMODECHANGE
:
668 case WM_PAINTCLIPBOARD
:
669 case WM_SIZECLIPBOARD
:
670 case EM_SETPASSWORDCHAR
:
671 FIXME_(msg
)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg
), msg
);
673 default: /* No translation needed */
679 /**********************************************************************
680 * WINPROC_UnmapMsg32ATo32W
682 * Unmap a message that was mapped from Ansi to Unicode.
684 void WINPROC_UnmapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
690 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
691 lstrcpynWtoA( (LPSTR
)*ptr
, (LPWSTR
)lParam
, wParam
);
692 HeapFree( GetProcessHeap(), 0, ptr
);
700 { CREATESTRUCTW cs
; /* new structure */
701 LPWSTR lpszName
; /* allocated Name */
702 LPWSTR lpszClass
; /* allocated Class */
704 struct s
*xs
= (struct s
*)lParam
;
705 if (xs
->lpszName
) HeapFree( GetProcessHeap(), 0, xs
->lpszName
);
706 if (xs
->lpszClass
) HeapFree( GetProcessHeap(), 0, xs
->lpszClass
);
707 HeapFree( GetProcessHeap(), 0, xs
);
713 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
714 if (HIWORD(cs
->szTitle
))
715 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
716 if (HIWORD(cs
->szClass
))
717 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
718 HeapFree( GetProcessHeap(), 0, cs
);
723 case WM_WININICHANGE
:
726 case CB_FINDSTRINGEXACT
:
727 case CB_SELECTSTRING
:
731 case LB_SELECTSTRING
:
733 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
738 case LB_INSERTSTRING
:
739 if ( WINPROC_TestLBForStr( hwnd
))
740 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
744 { if ( WINPROC_TestLBForStr( hwnd
))
745 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
746 lstrcpyWtoA( (LPSTR
)*ptr
, (LPWSTR
)(lParam
) );
747 HeapFree( GetProcessHeap(), 0, ptr
);
754 case CB_INSERTSTRING
:
755 if ( WINPROC_TestCBForStr( hwnd
))
756 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
760 { if ( WINPROC_TestCBForStr( hwnd
))
761 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
762 lstrcpyWtoA( (LPSTR
)*ptr
, (LPWSTR
)(lParam
) );
763 HeapFree( GetProcessHeap(), 0, ptr
);
770 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lParam */
771 WORD len
= *(WORD
*) lParam
;
772 lstrcpynWtoA( (LPSTR
)*ptr
, (LPWSTR
)lParam
, len
);
773 HeapFree( GetProcessHeap(), 0, ptr
);
780 /**********************************************************************
781 * WINPROC_MapMsg32WTo32A
783 * Map a message from Unicode to Ansi.
784 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
786 INT
WINPROC_MapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM
*plparam
)
791 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
792 wParam
+ sizeof(LPARAM
) );
794 *ptr
++ = *plparam
; /* Store previous lParam */
795 *plparam
= (LPARAM
)ptr
;
800 case WM_WININICHANGE
:
803 case CB_FINDSTRINGEXACT
:
804 case CB_SELECTSTRING
:
808 case LB_SELECTSTRING
:
810 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
811 return (*plparam
? 1 : -1);
816 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
819 *cs
= *(CREATESTRUCTA
*)*plparam
;
820 if (HIWORD(cs
->lpszName
))
821 cs
->lpszName
= HEAP_strdupWtoA( GetProcessHeap(), 0,
822 (LPCWSTR
)cs
->lpszName
);
823 if (HIWORD(cs
->lpszClass
))
824 cs
->lpszClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
825 (LPCWSTR
)cs
->lpszClass
);
826 *plparam
= (LPARAM
)cs
;
831 MDICREATESTRUCTA
*cs
=
832 (MDICREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
834 *cs
= *(MDICREATESTRUCTA
*)*plparam
;
835 if (HIWORD(cs
->szTitle
))
836 cs
->szTitle
= HEAP_strdupWtoA( GetProcessHeap(), 0,
837 (LPCWSTR
)cs
->szTitle
);
838 if (HIWORD(cs
->szClass
))
839 cs
->szClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
840 (LPCWSTR
)cs
->szClass
);
841 *plparam
= (LPARAM
)cs
;
847 case LB_INSERTSTRING
:
848 if ( WINPROC_TestLBForStr( hwnd
))
849 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
850 return (*plparam
? 1 : -1);
852 case LB_GETTEXT
: /* fixme: fixed sized buffer */
853 { if ( WINPROC_TestLBForStr( hwnd
))
854 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
856 *ptr
++ = *plparam
; /* Store previous lParam */
857 *plparam
= (LPARAM
)ptr
;
864 case CB_INSERTSTRING
:
865 if ( WINPROC_TestCBForStr( hwnd
))
866 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
867 return (*plparam
? 1 : -1);
869 case CB_GETLBTEXT
: /* fixme: fixed sized buffer */
870 { if ( WINPROC_TestCBForStr( hwnd
))
871 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
873 *ptr
++ = *plparam
; /* Store previous lParam */
874 *plparam
= (LPARAM
)ptr
;
881 { WORD len
= (WORD
)*plparam
;
882 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(CHAR
) );
884 *ptr
++ = *plparam
; /* Store previous lParam */
885 *((WORD
*) ptr
) = len
; /* Store the length */
886 *plparam
= (LPARAM
)ptr
;
890 case WM_ASKCBFORMATNAME
:
891 case WM_DEVMODECHANGE
:
892 case WM_PAINTCLIPBOARD
:
893 case WM_SIZECLIPBOARD
:
894 case EM_SETPASSWORDCHAR
:
895 FIXME_(msg
)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg
),msg
);
897 default: /* No translation needed */
903 /**********************************************************************
904 * WINPROC_UnmapMsg32WTo32A
906 * Unmap a message that was mapped from Unicode to Ansi.
908 void WINPROC_UnmapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
914 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
915 lstrcpynAtoW( (LPWSTR
)*ptr
, (LPSTR
)lParam
, wParam
);
916 HeapFree( GetProcessHeap(), 0, ptr
);
921 case WM_WININICHANGE
:
924 case CB_FINDSTRINGEXACT
:
925 case CB_SELECTSTRING
:
929 case LB_SELECTSTRING
:
931 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
937 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
938 if (HIWORD(cs
->lpszName
))
939 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszName
);
940 if (HIWORD(cs
->lpszClass
))
941 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszClass
);
942 HeapFree( GetProcessHeap(), 0, cs
);
948 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
949 if (HIWORD(cs
->szTitle
))
950 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
951 if (HIWORD(cs
->szClass
))
952 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
953 HeapFree( GetProcessHeap(), 0, cs
);
959 case LB_INSERTSTRING
:
960 if ( WINPROC_TestLBForStr( hwnd
))
961 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
965 { if ( WINPROC_TestLBForStr( hwnd
))
966 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
967 lstrcpyAtoW( (LPWSTR
)*ptr
, (LPSTR
)(lParam
) );
968 HeapFree( GetProcessHeap(), 0, ptr
);
975 case CB_INSERTSTRING
:
976 if ( WINPROC_TestCBForStr( hwnd
))
977 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
981 { if ( WINPROC_TestCBForStr( hwnd
))
982 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
983 lstrcpyAtoW( (LPWSTR
)*ptr
, (LPSTR
)(lParam
) );
984 HeapFree( GetProcessHeap(), 0, ptr
);
991 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lparam */
992 WORD len
= *(WORD
*)ptr
;
993 lstrcpynAtoW( (LPWSTR
) *ptr
, (LPSTR
)lParam
, len
);
994 HeapFree( GetProcessHeap(), 0, ptr
);
1001 /**********************************************************************
1002 * WINPROC_MapMsg16To32A
1004 * Map a message from 16- to 32-bit Ansi.
1005 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1007 INT
WINPROC_MapMsg16To32A( UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1008 WPARAM
*pwparam32
, LPARAM
*plparam
)
1010 *pmsg32
= (UINT
)msg16
;
1011 *pwparam32
= (WPARAM
)wParam16
;
1018 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1019 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
1023 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1024 *plparam
= (LPARAM
)(HWND
)HIWORD(*plparam
);
1027 if ( HIWORD(*plparam
) > CTLCOLOR_STATIC
) return -1;
1028 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
1029 *pwparam32
= (WPARAM
)(HDC
)wParam16
;
1030 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
1032 case WM_COMPAREITEM
:
1034 COMPAREITEMSTRUCT16
* cis16
= (COMPAREITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1035 COMPAREITEMSTRUCT
*cis
= (COMPAREITEMSTRUCT
*)
1036 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis
));
1037 if (!cis
) return -1;
1038 cis
->CtlType
= cis16
->CtlType
;
1039 cis
->CtlID
= cis16
->CtlID
;
1040 cis
->hwndItem
= cis16
->hwndItem
;
1041 cis
->itemID1
= cis16
->itemID1
;
1042 cis
->itemData1
= cis16
->itemData1
;
1043 cis
->itemID2
= cis16
->itemID2
;
1044 cis
->itemData2
= cis16
->itemData2
;
1045 cis
->dwLocaleId
= 0; /* FIXME */
1046 *plparam
= (LPARAM
)cis
;
1051 DELETEITEMSTRUCT16
* dis16
= (DELETEITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1052 DELETEITEMSTRUCT
*dis
= (DELETEITEMSTRUCT
*)
1053 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis
));
1054 if (!dis
) return -1;
1055 dis
->CtlType
= dis16
->CtlType
;
1056 dis
->CtlID
= dis16
->CtlID
;
1057 dis
->hwndItem
= dis16
->hwndItem
;
1058 dis
->itemData
= dis16
->itemData
;
1059 *plparam
= (LPARAM
)dis
;
1062 case WM_MEASUREITEM
:
1064 MEASUREITEMSTRUCT16
* mis16
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1065 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)
1066 HeapAlloc(GetProcessHeap(), 0,
1067 sizeof(*mis
) + sizeof(LPARAM
));
1068 if (!mis
) return -1;
1069 mis
->CtlType
= mis16
->CtlType
;
1070 mis
->CtlID
= mis16
->CtlID
;
1071 mis
->itemID
= mis16
->itemID
;
1072 mis
->itemWidth
= mis16
->itemWidth
;
1073 mis
->itemHeight
= mis16
->itemHeight
;
1074 mis
->itemData
= mis16
->itemData
;
1075 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1076 *plparam
= (LPARAM
)mis
;
1081 DRAWITEMSTRUCT16
* dis16
= (DRAWITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1082 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)HeapAlloc(GetProcessHeap(), 0,
1084 if (!dis
) return -1;
1085 dis
->CtlType
= dis16
->CtlType
;
1086 dis
->CtlID
= dis16
->CtlID
;
1087 dis
->itemID
= dis16
->itemID
;
1088 dis
->itemAction
= dis16
->itemAction
;
1089 dis
->itemState
= dis16
->itemState
;
1090 dis
->hwndItem
= dis16
->hwndItem
;
1091 dis
->hDC
= dis16
->hDC
;
1092 dis
->itemData
= dis16
->itemData
;
1093 CONV_RECT16TO32( &dis16
->rcItem
, &dis
->rcItem
);
1094 *plparam
= (LPARAM
)dis
;
1097 case WM_GETMINMAXINFO
:
1099 MINMAXINFO
*mmi
= (MINMAXINFO
*)HeapAlloc( GetProcessHeap(), 0,
1100 sizeof(*mmi
) + sizeof(LPARAM
));
1101 if (!mmi
) return -1;
1102 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16
*)PTR_SEG_TO_LIN(*plparam
),
1104 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1105 *plparam
= (LPARAM
)mmi
;
1110 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
1114 MDICREATESTRUCT16
*cs16
=
1115 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1116 MDICREATESTRUCTA
*cs
=
1117 (MDICREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
1118 sizeof(*cs
) + sizeof(LPARAM
) );
1120 STRUCT32_MDICREATESTRUCT16to32A( cs16
, cs
);
1121 cs
->szTitle
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->szTitle
);
1122 cs
->szClass
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->szClass
);
1123 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1124 *plparam
= (LPARAM
)cs
;
1127 case WM_MDIGETACTIVE
:
1128 *plparam
= (LPARAM
)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL
) );
1129 *(BOOL
*)(*plparam
) = 0;
1133 *pmsg32
=WM_MDIREFRESHMENU
;
1134 *pwparam32
= (WPARAM
)(HMENU
)LOWORD(*plparam
);
1135 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1138 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1139 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1142 if((LOWORD(*plparam
) & MF_POPUP
) && (LOWORD(*plparam
) != 0xFFFF))
1144 HMENU hmenu
=(HMENU
)HIWORD(*plparam
);
1145 UINT Pos
=MENU_FindSubMenu( &hmenu
, wParam16
);
1146 if(Pos
==0xFFFF) Pos
=0; /* NO_SELECTED_ITEM */
1147 *pwparam32
= MAKEWPARAM( Pos
, LOWORD(*plparam
) );
1149 else *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1150 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1152 case WM_MDIACTIVATE
:
1155 *pwparam32
= (WPARAM
)(HWND
)HIWORD(*plparam
);
1156 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
1158 else /* message sent to MDI client */
1159 *pwparam32
= wParam16
;
1163 NCCALCSIZE_PARAMS16
*nc16
;
1164 NCCALCSIZE_PARAMS
*nc
;
1166 nc
= (NCCALCSIZE_PARAMS
*)HeapAlloc( GetProcessHeap(), 0,
1167 sizeof(*nc
) + sizeof(LPARAM
) );
1169 nc16
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(*plparam
);
1170 CONV_RECT16TO32( &nc16
->rgrc
[0], &nc
->rgrc
[0] );
1173 nc
->lppos
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1174 sizeof(*nc
->lppos
) );
1175 CONV_RECT16TO32( &nc16
->rgrc
[1], &nc
->rgrc
[1] );
1176 CONV_RECT16TO32( &nc16
->rgrc
[2], &nc
->rgrc
[2] );
1177 if (nc
->lppos
) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc16
->lppos
), nc
->lppos
);
1179 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1180 *plparam
= (LPARAM
)nc
;
1186 CREATESTRUCT16
*cs16
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1187 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
1188 sizeof(*cs
) + sizeof(LPARAM
) );
1190 STRUCT32_CREATESTRUCT16to32A( cs16
, cs
);
1191 cs
->lpszName
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->lpszName
);
1192 cs
->lpszClass
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->lpszClass
);
1193 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1194 *plparam
= (LPARAM
)cs
;
1197 case WM_PARENTNOTIFY
:
1198 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
1200 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1201 *plparam
= (LPARAM
)(HWND
)LOWORD(*plparam
);
1204 case WM_WINDOWPOSCHANGING
:
1205 case WM_WINDOWPOSCHANGED
:
1207 WINDOWPOS
*wp
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1208 sizeof(*wp
) + sizeof(LPARAM
) );
1210 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(*plparam
),
1212 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1213 *plparam
= (LPARAM
)wp
;
1219 LPMSG16 msg16
= (LPMSG16
)PTR_SEG_TO_LIN(*plparam
);
1220 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1222 if (!msg32
) return -1;
1223 msg32
->hwnd
= msg16
->hwnd
;
1224 msg32
->lParam
= msg16
->lParam
;
1225 msg32
->time
= msg16
->time
;
1226 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1227 /* this is right, right? */
1228 if (WINPROC_MapMsg16To32A(msg16
->message
,msg16
->wParam
,
1229 &msg32
->message
,&msg32
->wParam
,
1230 &msg32
->lParam
)<0) {
1231 HeapFree( GetProcessHeap(), 0, msg32
);
1234 *plparam
= (LPARAM
)msg32
;
1239 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
1241 case WM_ACTIVATEAPP
:
1243 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1244 a 32bit window. Might be superflous with 32bit interprocess
1247 HTASK16 htask
= (HTASK16
) *plparam
;
1248 DWORD idThread
= (DWORD
)((TDB
*)GlobalLock16(htask
))->teb
->tid
;
1249 *plparam
= (LPARAM
) idThread
;
1252 case WM_ASKCBFORMATNAME
:
1253 case WM_DEVMODECHANGE
:
1254 case WM_PAINTCLIPBOARD
:
1255 case WM_SIZECLIPBOARD
:
1256 case WM_WININICHANGE
:
1257 FIXME_(msg
)("message %04x needs translation\n",msg16
);
1260 default: /* No translation needed */
1266 /**********************************************************************
1267 * WINPROC_UnmapMsg16To32A
1269 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1271 LRESULT
WINPROC_UnmapMsg16To32A( HWND16 hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1276 case WM_COMPAREITEM
:
1279 HeapFree( GetProcessHeap(), 0, (LPVOID
)lParam
);
1281 case WM_MEASUREITEM
:
1283 MEASUREITEMSTRUCT16
*mis16
;
1284 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)lParam
;
1285 lParam
= *(LPARAM
*)(mis
+ 1);
1286 mis16
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
1287 mis16
->itemWidth
= (UINT16
)mis
->itemWidth
;
1288 mis16
->itemHeight
= (UINT16
)mis
->itemHeight
;
1289 HeapFree( GetProcessHeap(), 0, mis
);
1292 case WM_GETMINMAXINFO
:
1294 MINMAXINFO
*mmi
= (MINMAXINFO
*)lParam
;
1295 lParam
= *(LPARAM
*)(mmi
+ 1);
1296 STRUCT32_MINMAXINFO32to16( mmi
,
1297 (MINMAXINFO16
*)PTR_SEG_TO_LIN(lParam
));
1298 HeapFree( GetProcessHeap(), 0, mmi
);
1303 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1304 lParam
= *(LPARAM
*)(cs
+ 1);
1305 STRUCT32_MDICREATESTRUCT32Ato16( cs
,
1306 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1307 HeapFree( GetProcessHeap(), 0, cs
);
1310 case WM_MDIGETACTIVE
:
1311 result
= MAKELONG( LOWORD(result
), (BOOL16
)(*(BOOL
*)lParam
) );
1312 HeapFree( GetProcessHeap(), 0, (BOOL
*)lParam
);
1316 NCCALCSIZE_PARAMS16
*nc16
;
1317 NCCALCSIZE_PARAMS
*nc
= (NCCALCSIZE_PARAMS
*)lParam
;
1318 lParam
= *(LPARAM
*)(nc
+ 1);
1319 nc16
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(lParam
);
1320 CONV_RECT32TO16( &nc
->rgrc
[0], &nc16
->rgrc
[0] );
1323 CONV_RECT32TO16( &nc
->rgrc
[1], &nc16
->rgrc
[1] );
1324 CONV_RECT32TO16( &nc
->rgrc
[2], &nc16
->rgrc
[2] );
1327 STRUCT32_WINDOWPOS32to16( nc
->lppos
,
1328 (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc16
->lppos
));
1329 HeapFree( GetProcessHeap(), 0, nc
->lppos
);
1332 HeapFree( GetProcessHeap(), 0, nc
);
1338 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1339 lParam
= *(LPARAM
*)(cs
+ 1);
1340 STRUCT32_CREATESTRUCT32Ato16( cs
,
1341 (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1342 HeapFree( GetProcessHeap(), 0, cs
);
1345 case WM_WINDOWPOSCHANGING
:
1346 case WM_WINDOWPOSCHANGED
:
1348 WINDOWPOS
*wp
= (WINDOWPOS
*)lParam
;
1349 lParam
= *(LPARAM
*)(wp
+ 1);
1350 STRUCT32_WINDOWPOS32to16(wp
,(WINDOWPOS16
*)PTR_SEG_TO_LIN(lParam
));
1351 HeapFree( GetProcessHeap(), 0, wp
);
1357 LPMSG msg32
= (LPMSG
)lParam
;
1359 WINPROC_UnmapMsg16To32A( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1361 HeapFree( GetProcessHeap(), 0, msg32
);
1369 /**********************************************************************
1370 * WINPROC_MapMsg16To32W
1372 * Map a message from 16- to 32-bit Unicode.
1373 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1375 INT
WINPROC_MapMsg16To32W( HWND16 hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1376 WPARAM
*pwparam32
, LPARAM
*plparam
)
1382 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
1383 return WINPROC_MapMsg32ATo32W( hwnd
, *pmsg32
, *pwparam32
, plparam
);
1387 CREATESTRUCT16
*cs16
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1388 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1389 sizeof(*cs
) + sizeof(LPARAM
) );
1391 STRUCT32_CREATESTRUCT16to32A( cs16
, (CREATESTRUCTA
*)cs
);
1392 cs
->lpszName
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->lpszName
);
1393 cs
->lpszClass
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->lpszClass
);
1394 if (HIWORD(cs
->lpszName
))
1395 cs
->lpszName
= HEAP_strdupAtoW( GetProcessHeap(), 0,
1396 (LPCSTR
)cs
->lpszName
);
1397 if (HIWORD(cs
->lpszClass
))
1398 cs
->lpszClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
1399 (LPCSTR
)cs
->lpszClass
);
1400 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1401 *plparam
= (LPARAM
)cs
;
1406 MDICREATESTRUCT16
*cs16
=
1407 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
1408 MDICREATESTRUCTW
*cs
=
1409 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1410 sizeof(*cs
) + sizeof(LPARAM
) );
1412 STRUCT32_MDICREATESTRUCT16to32A( cs16
, (MDICREATESTRUCTA
*)cs
);
1413 cs
->szTitle
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->szTitle
);
1414 cs
->szClass
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->szClass
);
1415 if (HIWORD(cs
->szTitle
))
1416 cs
->szTitle
= HEAP_strdupAtoW( GetProcessHeap(), 0,
1417 (LPCSTR
)cs
->szTitle
);
1418 if (HIWORD(cs
->szClass
))
1419 cs
->szClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
1420 (LPCSTR
)cs
->szClass
);
1421 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1422 *plparam
= (LPARAM
)cs
;
1428 LPMSG16 msg16
= (LPMSG16
)PTR_SEG_TO_LIN(*plparam
);
1429 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1431 if (!msg32
) return -1;
1432 msg32
->hwnd
= msg16
->hwnd
;
1433 msg32
->lParam
= msg16
->lParam
;
1434 msg32
->time
= msg16
->time
;
1435 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1436 /* this is right, right? */
1437 if (WINPROC_MapMsg16To32W(hwnd
, msg16
->message
,msg16
->wParam
,
1438 &msg32
->message
,&msg32
->wParam
,
1439 &msg32
->lParam
)<0) {
1440 HeapFree( GetProcessHeap(), 0, msg32
);
1443 *plparam
= (LPARAM
)msg32
;
1447 default: /* No Unicode translation needed */
1448 return WINPROC_MapMsg16To32A( msg16
, wParam16
, pmsg32
,
1449 pwparam32
, plparam
);
1454 /**********************************************************************
1455 * WINPROC_UnmapMsg16To32W
1457 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1459 LRESULT
WINPROC_UnmapMsg16To32W( HWND16 hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1466 WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
);
1471 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)lParam
;
1472 lParam
= *(LPARAM
*)(cs
+ 1);
1473 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs
,
1474 (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1475 if (HIWORD(cs
->lpszName
))
1476 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszName
);
1477 if (HIWORD(cs
->lpszClass
))
1478 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszClass
);
1479 HeapFree( GetProcessHeap(), 0, cs
);
1484 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
1485 lParam
= *(LPARAM
*)(cs
+ 1);
1486 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs
,
1487 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
1488 if (HIWORD(cs
->szTitle
))
1489 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
1490 if (HIWORD(cs
->szClass
))
1491 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
1492 HeapFree( GetProcessHeap(), 0, cs
);
1498 LPMSG msg32
= (LPMSG
)lParam
;
1500 WINPROC_UnmapMsg16To32W( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1502 HeapFree( GetProcessHeap(), 0, msg32
);
1506 return WINPROC_UnmapMsg16To32A( hwnd
, msg
, wParam
, lParam
, result
);
1512 /**********************************************************************
1513 * WINPROC_MapMsg32ATo16
1515 * Map a message from 32-bit Ansi to 16-bit.
1516 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1518 INT
WINPROC_MapMsg32ATo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
1519 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
1522 *pmsg16
= (UINT16
)msg32
;
1523 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1531 *pmsg16
= (UINT16
)msg32
+ (BM_GETCHECK16
- BM_GETCHECK
);
1540 case EM_SCROLLCARET
:
1543 case EM_GETLINECOUNT
:
1555 case EM_LINEFROMCHAR
:
1556 case EM_SETTABSTOPS
:
1557 case EM_SETPASSWORDCHAR
:
1558 case EM_EMPTYUNDOBUFFER
:
1559 case EM_GETFIRSTVISIBLELINE
:
1560 case EM_SETREADONLY
:
1561 case EM_SETWORDBREAKPROC
:
1562 case EM_GETWORDBREAKPROC
:
1563 case EM_GETPASSWORDCHAR
:
1564 *pmsg16
= (UINT16
)msg32
+ (EM_GETSEL16
- EM_GETSEL
);
1569 case LB_DELETESTRING
:
1570 case LB_GETANCHORINDEX
:
1571 case LB_GETCARETINDEX
:
1574 case LB_GETHORIZONTALEXTENT
:
1575 case LB_GETITEMDATA
:
1576 case LB_GETITEMHEIGHT
:
1578 case LB_GETSELCOUNT
:
1580 case LB_GETTOPINDEX
:
1581 case LB_RESETCONTENT
:
1582 case LB_SELITEMRANGE
:
1583 case LB_SELITEMRANGEEX
:
1584 case LB_SETANCHORINDEX
:
1585 case LB_SETCARETINDEX
:
1586 case LB_SETCOLUMNWIDTH
:
1588 case LB_SETHORIZONTALEXTENT
:
1589 case LB_SETITEMDATA
:
1590 case LB_SETITEMHEIGHT
:
1592 case LB_SETTOPINDEX
:
1593 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1595 case CB_DELETESTRING
:
1597 case CB_GETLBTEXTLEN
:
1599 case CB_RESETCONTENT
:
1603 case CB_SHOWDROPDOWN
:
1604 case CB_SETITEMDATA
:
1605 case CB_SETITEMHEIGHT
:
1606 case CB_GETITEMHEIGHT
:
1607 case CB_SETEXTENDEDUI
:
1608 case CB_GETEXTENDEDUI
:
1609 case CB_GETDROPPEDSTATE
:
1610 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1613 *pmsg16
= CB_GETEDITSEL16
;
1618 case LB_FINDSTRINGEXACT
:
1619 case LB_INSERTSTRING
:
1620 case LB_SELECTSTRING
:
1624 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
1625 if (!str
) return -1;
1626 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1628 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1633 case CB_FINDSTRINGEXACT
:
1634 case CB_INSERTSTRING
:
1635 case CB_SELECTSTRING
:
1638 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
1639 if (!str
) return -1;
1640 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1642 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1645 case LB_GETITEMRECT
:
1648 rect
= (RECT16
*)SEGPTR_ALLOC( sizeof(RECT16
) + sizeof(LPARAM
) );
1649 if (!rect
) return -1;
1650 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1651 *plparam
= (LPARAM
)SEGPTR_GET(rect
);
1653 *pmsg16
= LB_GETITEMRECT16
;
1655 case LB_GETSELITEMS
:
1658 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1659 if (!(items
= SEGPTR_ALLOC( *pwparam16
* sizeof(INT16
)
1660 + sizeof(LPARAM
)))) return -1;
1661 *((LPARAM
*)items
)++ = *plparam
; /* Store the previous lParam */
1662 *plparam
= (LPARAM
)SEGPTR_GET(items
);
1664 *pmsg16
= LB_GETSELITEMS16
;
1666 case LB_SETTABSTOPS
:
1671 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1672 if (!(stops
= SEGPTR_ALLOC( *pwparam16
* sizeof(INT16
)
1673 + sizeof(LPARAM
)))) return -1;
1674 for (i
= 0; i
< *pwparam16
; i
++) stops
[i
] = *((LPINT
)*plparam
+i
);
1675 *plparam
= (LPARAM
)SEGPTR_GET(stops
);
1678 *pmsg16
= LB_SETTABSTOPS16
;
1681 case CB_GETDROPPEDCONTROLRECT
:
1684 rect
= (RECT16
*)SEGPTR_ALLOC( sizeof(RECT16
) + sizeof(LPARAM
) );
1685 if (!rect
) return -1;
1686 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1687 *plparam
= (LPARAM
)SEGPTR_GET(rect
);
1689 *pmsg16
= CB_GETDROPPEDCONTROLRECT16
;
1693 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1694 *pmsg16
= LB_GETTEXT16
;
1698 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1699 *pmsg16
= CB_GETLBTEXT16
;
1704 *plparam
= MAKELONG( (INT16
)(INT
)wParam32
, (INT16
)*plparam
);
1705 *pmsg16
= EM_SETSEL16
;
1712 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
1716 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
1718 case WM_CTLCOLORMSGBOX
:
1719 case WM_CTLCOLOREDIT
:
1720 case WM_CTLCOLORLISTBOX
:
1721 case WM_CTLCOLORBTN
:
1722 case WM_CTLCOLORDLG
:
1723 case WM_CTLCOLORSCROLLBAR
:
1724 case WM_CTLCOLORSTATIC
:
1725 *pmsg16
= WM_CTLCOLOR
;
1726 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
1727 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
1729 case WM_COMPAREITEM
:
1731 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)*plparam
;
1732 COMPAREITEMSTRUCT16
*cis
= SEGPTR_NEW(COMPAREITEMSTRUCT16
);
1733 if (!cis
) return -1;
1734 cis
->CtlType
= (UINT16
)cis32
->CtlType
;
1735 cis
->CtlID
= (UINT16
)cis32
->CtlID
;
1736 cis
->hwndItem
= (HWND16
)cis32
->hwndItem
;
1737 cis
->itemID1
= (UINT16
)cis32
->itemID1
;
1738 cis
->itemData1
= cis32
->itemData1
;
1739 cis
->itemID2
= (UINT16
)cis32
->itemID2
;
1740 cis
->itemData2
= cis32
->itemData2
;
1741 *plparam
= (LPARAM
)SEGPTR_GET(cis
);
1746 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)*plparam
;
1747 DELETEITEMSTRUCT16
*dis
= SEGPTR_NEW(DELETEITEMSTRUCT16
);
1748 if (!dis
) return -1;
1749 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1750 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1751 dis
->itemID
= (UINT16
)dis32
->itemID
;
1752 dis
->hwndItem
= (HWND16
)dis32
->hwndItem
;
1753 dis
->itemData
= dis32
->itemData
;
1754 *plparam
= (LPARAM
)SEGPTR_GET(dis
);
1759 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)*plparam
;
1760 DRAWITEMSTRUCT16
*dis
= SEGPTR_NEW(DRAWITEMSTRUCT16
);
1761 if (!dis
) return -1;
1762 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1763 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1764 dis
->itemID
= (UINT16
)dis32
->itemID
;
1765 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
1766 dis
->itemState
= (UINT16
)dis32
->itemState
;
1767 dis
->hwndItem
= (HWND16
)dis32
->hwndItem
;
1768 dis
->hDC
= (HDC16
)dis32
->hDC
;
1769 dis
->itemData
= dis32
->itemData
;
1770 CONV_RECT32TO16( &dis32
->rcItem
, &dis
->rcItem
);
1771 *plparam
= (LPARAM
)SEGPTR_GET(dis
);
1774 case WM_MEASUREITEM
:
1776 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)*plparam
;
1777 MEASUREITEMSTRUCT16
*mis
= (MEASUREITEMSTRUCT16
*)
1778 SEGPTR_ALLOC(sizeof(*mis
)+sizeof(LPARAM
));
1779 if (!mis
) return -1;
1780 mis
->CtlType
= (UINT16
)mis32
->CtlType
;
1781 mis
->CtlID
= (UINT16
)mis32
->CtlID
;
1782 mis
->itemID
= (UINT16
)mis32
->itemID
;
1783 mis
->itemWidth
= (UINT16
)mis32
->itemWidth
;
1784 mis
->itemHeight
= (UINT16
)mis32
->itemHeight
;
1785 mis
->itemData
= mis32
->itemData
;
1786 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1787 *plparam
= (LPARAM
)SEGPTR_GET(mis
);
1790 case WM_GETMINMAXINFO
:
1792 MINMAXINFO16
*mmi
= (MINMAXINFO16
*)SEGPTR_ALLOC( sizeof(*mmi
) +
1794 if (!mmi
) return -1;
1795 STRUCT32_MINMAXINFO32to16( (MINMAXINFO
*)*plparam
, mmi
);
1796 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1797 *plparam
= (LPARAM
)SEGPTR_GET(mmi
);
1803 *pwparam16
= (WPARAM16
)min( wParam32
, 0xff80 ); /* Must be < 64K */
1804 if (!(str
= SEGPTR_ALLOC(*pwparam16
+ sizeof(LPARAM
)))) return -1;
1805 *((LPARAM
*)str
)++ = *plparam
; /* Store the previous lParam */
1806 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1811 MDICREATESTRUCT16
*cs
;
1812 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)*plparam
;
1815 if (!(cs
= SEGPTR_NEW(MDICREATESTRUCT16
))) return -1;
1816 STRUCT32_MDICREATESTRUCT32Ato16( cs32
, cs
);
1817 name
= SEGPTR_STRDUP( cs32
->szTitle
);
1818 cls
= SEGPTR_STRDUP( cs32
->szClass
);
1819 cs
->szTitle
= SEGPTR_GET(name
);
1820 cs
->szClass
= SEGPTR_GET(cls
);
1821 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
1824 case WM_MDIGETACTIVE
:
1827 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
1828 (HMENU16
)LOWORD(*plparam
) );
1829 *pwparam16
= (*plparam
== 0);
1832 if(HIWORD(wParam32
) & MF_POPUP
)
1835 if (((UINT
)HIWORD(wParam32
) != 0xFFFF) || (*plparam
))
1837 if((hmenu
= GetSubMenu((HMENU16
)*plparam
, *pwparam16
)))
1843 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
1845 case WM_MDIACTIVATE
:
1847 WND
*tempWnd
= WIN_FindWndPtr(hwnd
);
1848 if( WIDGETS_IsControl(tempWnd
, BIC32_MDICLIENT
) )
1850 *pwparam16
= (HWND
)wParam32
;
1855 *pwparam16
= ((HWND
)*plparam
== hwnd
);
1856 *plparam
= MAKELPARAM( (HWND16
)LOWORD(*plparam
),
1857 (HWND16
)LOWORD(wParam32
) );
1859 WIN_ReleaseWndPtr(tempWnd
);
1864 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)*plparam
;
1865 NCCALCSIZE_PARAMS16
*nc
= (NCCALCSIZE_PARAMS16
*)SEGPTR_ALLOC( sizeof(*nc
) + sizeof(LPARAM
) );
1868 CONV_RECT32TO16( &nc32
->rgrc
[0], &nc
->rgrc
[0] );
1872 CONV_RECT32TO16( &nc32
->rgrc
[1], &nc
->rgrc
[1] );
1873 CONV_RECT32TO16( &nc32
->rgrc
[2], &nc
->rgrc
[2] );
1874 if (!(wp
= SEGPTR_NEW(WINDOWPOS16
)))
1879 STRUCT32_WINDOWPOS32to16( nc32
->lppos
, wp
);
1880 nc
->lppos
= SEGPTR_GET(wp
);
1882 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1883 *plparam
= (LPARAM
)SEGPTR_GET(nc
);
1890 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)*plparam
;
1893 if (!(cs
= SEGPTR_NEW(CREATESTRUCT16
))) return -1;
1894 STRUCT32_CREATESTRUCT32Ato16( cs32
, cs
);
1895 name
= SEGPTR_STRDUP( cs32
->lpszName
);
1896 cls
= SEGPTR_STRDUP( cs32
->lpszClass
);
1897 cs
->lpszName
= SEGPTR_GET(name
);
1898 cs
->lpszClass
= SEGPTR_GET(cls
);
1899 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
1902 case WM_PARENTNOTIFY
:
1903 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
1904 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
1905 /* else nothing to do */
1908 *plparam
= MapLS( (NMHDR
*)*plparam
); /* NMHDR is already 32-bit */
1912 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
1913 if (!str
) return -1;
1914 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1917 case WM_WINDOWPOSCHANGING
:
1918 case WM_WINDOWPOSCHANGED
:
1920 WINDOWPOS16
*wp
= (WINDOWPOS16
*)SEGPTR_ALLOC( sizeof(*wp
) +
1923 STRUCT32_WINDOWPOS32to16( (WINDOWPOS
*)*plparam
, wp
);
1924 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1925 *plparam
= (LPARAM
)SEGPTR_GET(wp
);
1930 LPMSG msg32
= (LPMSG
) *plparam
;
1931 LPMSG16 msg16
= (LPMSG16
) SEGPTR_NEW( MSG16
);
1933 if (!msg16
) return -1;
1934 msg16
->hwnd
= msg32
->hwnd
;
1935 msg16
->lParam
= msg32
->lParam
;
1936 msg16
->time
= msg32
->time
;
1937 CONV_POINT32TO16(&msg32
->pt
,&msg16
->pt
);
1938 /* this is right, right? */
1939 if (WINPROC_MapMsg32ATo16(msg32
->hwnd
,msg32
->message
,msg32
->wParam
,
1940 &msg16
->message
,&msg16
->wParam
, &msg16
->lParam
)<0) {
1941 SEGPTR_FREE( msg16
);
1944 *plparam
= (LPARAM
)SEGPTR_GET(msg16
);
1949 case WM_ACTIVATEAPP
:
1951 *plparam
= (LPARAM
)THREAD_IdToTEB((DWORD
) *plparam
)->htask16
;
1954 case WM_ASKCBFORMATNAME
:
1955 case WM_DEVMODECHANGE
:
1956 case WM_PAINTCLIPBOARD
:
1957 case WM_SIZECLIPBOARD
:
1958 case WM_WININICHANGE
:
1959 FIXME_(msg
)("message %04x needs translation\n", msg32
);
1961 case WM_SIZING
: /* should not be send to 16-bit apps */
1963 default: /* No translation needed */
1969 /**********************************************************************
1970 * WINPROC_UnmapMsg32ATo16
1972 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1974 void WINPROC_UnmapMsg32ATo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1983 case LB_FINDSTRINGEXACT
:
1984 case LB_INSERTSTRING
:
1985 case LB_SELECTSTRING
:
1986 case LB_SETTABSTOPS
:
1989 case CB_FINDSTRINGEXACT
:
1990 case CB_INSERTSTRING
:
1991 case CB_SELECTSTRING
:
1993 case WM_COMPAREITEM
:
1997 SEGPTR_FREE( PTR_SEG_TO_LIN(p16
->lParam
) );
2000 case CB_GETDROPPEDCONTROLRECT
:
2001 case LB_GETITEMRECT
:
2003 RECT16
*rect
= (RECT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2004 p16
->lParam
= *(LPARAM
*)(rect
+ 1);
2005 CONV_RECT16TO32( rect
, (RECT
*)(p16
->lParam
));
2006 SEGPTR_FREE( rect
);
2009 case LB_GETSELITEMS
:
2012 LPINT16 items
= (LPINT16
)PTR_SEG_TO_LIN(lParam
);
2013 p16
->lParam
= *((LPARAM
*)items
- 1);
2014 for (i
= 0; i
< p16
->wParam
; i
++) *((LPINT
)(p16
->lParam
) + i
) = items
[i
];
2015 SEGPTR_FREE( (LPARAM
*)items
- 1 );
2021 *((LPUINT
)(wParam
)) = LOWORD(p16
->lResult
);
2023 *((LPUINT
)(lParam
)) = HIWORD(p16
->lResult
); /* FIXME: substract 1? */
2028 UnMapLS( (SEGPTR
)(p16
->lParam
) );
2031 case WM_MEASUREITEM
:
2033 MEASUREITEMSTRUCT16
*mis
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2034 MEASUREITEMSTRUCT
*mis32
= *(MEASUREITEMSTRUCT
**)(mis
+ 1);
2035 mis32
->itemWidth
= mis
->itemWidth
;
2036 mis32
->itemHeight
= mis
->itemHeight
;
2040 case WM_GETMINMAXINFO
:
2042 MINMAXINFO16
*mmi
= (MINMAXINFO16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2043 p16
->lParam
= *(LPARAM
*)(mmi
+ 1);
2044 STRUCT32_MINMAXINFO16to32( mmi
, (MINMAXINFO
*)(p16
->lParam
) );
2050 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(p16
->lParam
);
2051 p16
->lParam
= *((LPARAM
*)str
- 1);
2052 lstrcpynA( (LPSTR
)(p16
->lParam
), str
, p16
->wParam
);
2053 SEGPTR_FREE( (LPARAM
*)str
- 1 );
2058 MDICREATESTRUCT16
*cs
= (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2059 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->szTitle
) );
2060 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->szClass
) );
2064 case WM_MDIGETACTIVE
:
2065 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(p16
->lResult
);
2066 p16
->lResult
= (HWND
)LOWORD(p16
->lResult
);
2070 NCCALCSIZE_PARAMS
*nc32
;
2071 NCCALCSIZE_PARAMS16
*nc
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2072 p16
->lParam
= *(LPARAM
*)(nc
+ 1);
2073 nc32
= (NCCALCSIZE_PARAMS
*)(p16
->lParam
);
2074 CONV_RECT16TO32( &nc
->rgrc
[0], &nc32
->rgrc
[0] );
2077 CONV_RECT16TO32( &nc
->rgrc
[1], &nc32
->rgrc
[1] );
2078 CONV_RECT16TO32( &nc
->rgrc
[2], &nc32
->rgrc
[2] );
2079 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc
->lppos
),
2081 SEGPTR_FREE( PTR_SEG_TO_LIN(nc
->lppos
) );
2089 CREATESTRUCT16
*cs
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2090 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->lpszName
) );
2091 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->lpszClass
) );
2095 case WM_WINDOWPOSCHANGING
:
2096 case WM_WINDOWPOSCHANGED
:
2098 WINDOWPOS16
*wp
= (WINDOWPOS16
*)PTR_SEG_TO_LIN(p16
->lParam
);
2099 p16
->lParam
= *(LPARAM
*)(wp
+ 1);
2100 STRUCT32_WINDOWPOS16to32( wp
, (WINDOWPOS
*)p16
->lParam
);
2105 UnMapLS(p16
->lParam
);
2110 LPMSG16 msg16
= (LPMSG16
)PTR_SEG_TO_LIN(p16
->lParam
);
2112 msgp16
.wParam
=msg16
->wParam
;
2113 msgp16
.lParam
=msg16
->lParam
;
2114 WINPROC_UnmapMsg32ATo16(((LPMSG
)lParam
)->hwnd
, ((LPMSG
)lParam
)->message
,
2115 ((LPMSG
)lParam
)->wParam
, ((LPMSG
)lParam
)->lParam
,
2124 /**********************************************************************
2125 * WINPROC_MapMsg32WTo16
2127 * Map a message from 32-bit Unicode to 16-bit.
2128 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2130 INT
WINPROC_MapMsg32WTo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
2131 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
2138 case LB_FINDSTRINGEXACT
:
2139 case LB_INSERTSTRING
:
2140 case LB_SELECTSTRING
:
2144 LPSTR str
= SEGPTR_STRDUP_WtoA( (LPWSTR
)*plparam
);
2145 if (!str
) return -1;
2146 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
2147 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2149 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2154 case CB_FINDSTRINGEXACT
:
2155 case CB_INSERTSTRING
:
2156 case CB_SELECTSTRING
:
2159 LPSTR str
= SEGPTR_STRDUP_WtoA( (LPWSTR
)*plparam
);
2160 if (!str
) return -1;
2161 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
2162 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2164 *pmsg16
= (UINT16
)msg32
+ (CB_ADDSTRING16
- CB_ADDSTRING
);
2171 CREATESTRUCTW
*cs32
= (CREATESTRUCTW
*)*plparam
;
2174 if (!(cs
= SEGPTR_NEW(CREATESTRUCT16
))) return -1;
2175 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs32
, cs
);
2176 name
= SEGPTR_STRDUP_WtoA( cs32
->lpszName
);
2177 cls
= SEGPTR_STRDUP_WtoA( cs32
->lpszClass
);
2178 cs
->lpszName
= SEGPTR_GET(name
);
2179 cs
->lpszClass
= SEGPTR_GET(cls
);
2180 *pmsg16
= (UINT16
)msg32
;
2181 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
2182 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
2187 MDICREATESTRUCT16
*cs
;
2188 MDICREATESTRUCTW
*cs32
= (MDICREATESTRUCTW
*)*plparam
;
2191 if (!(cs
= SEGPTR_NEW(MDICREATESTRUCT16
))) return -1;
2192 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs32
, cs
);
2193 name
= SEGPTR_STRDUP_WtoA( cs32
->szTitle
);
2194 cls
= SEGPTR_STRDUP_WtoA( cs32
->szClass
);
2195 cs
->szTitle
= SEGPTR_GET(name
);
2196 cs
->szClass
= SEGPTR_GET(cls
);
2197 *pmsg16
= (UINT16
)msg32
;
2198 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
2199 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
2204 LPSTR str
= SEGPTR_STRDUP_WtoA( (LPWSTR
)*plparam
);
2205 if (!str
) return -1;
2206 *pmsg16
= (UINT16
)msg32
;
2207 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
2208 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2213 if ( WINPROC_TestLBForStr( hwnd
))
2215 LPSTR str
= (LPSTR
) SEGPTR_ALLOC( 256 ); /* fixme: fixed sized buffer */
2216 if (!str
) return -1;
2217 *pmsg16
= (msg32
== LB_GETTEXT
)? LB_GETTEXT16
: CB_GETLBTEXT16
;
2218 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
2219 *plparam
= (LPARAM
)SEGPTR_GET(str
);
2222 default: /* No Unicode translation needed (?) */
2223 return WINPROC_MapMsg32ATo16( hwnd
, msg32
, wParam32
, pmsg16
,
2224 pwparam16
, plparam
);
2229 /**********************************************************************
2230 * WINPROC_UnmapMsg32WTo16
2232 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2234 void WINPROC_UnmapMsg32WTo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2241 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(p16
->lParam
);
2242 p16
->lParam
= *((LPARAM
*)str
- 1);
2243 lstrcpyAtoW( (LPWSTR
)(p16
->lParam
), str
);
2244 SEGPTR_FREE( (LPARAM
*)str
- 1 );
2249 if ( WINPROC_TestLBForStr( hwnd
))
2251 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(p16
->lParam
);
2252 lstrcpyAtoW( (LPWSTR
)lParam
, str
);
2253 SEGPTR_FREE( (LPARAM
*) str
);
2257 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, p16
);
2263 /**********************************************************************
2264 * WINPROC_CallProc32ATo32W
2266 * Call a window procedure, translating args from Ansi to Unicode.
2268 static LRESULT
WINPROC_CallProc32ATo32W( WNDPROC func
, HWND hwnd
,
2269 UINT msg
, WPARAM wParam
,
2274 if (WINPROC_MapMsg32ATo32W( hwnd
, msg
, wParam
, &lParam
) == -1) return 0;
2275 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2276 WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
);
2281 /**********************************************************************
2282 * WINPROC_CallProc32WTo32A
2284 * Call a window procedure, translating args from Unicode to Ansi.
2286 static LRESULT
WINPROC_CallProc32WTo32A( WNDPROC func
, HWND hwnd
,
2287 UINT msg
, WPARAM wParam
,
2292 if (WINPROC_MapMsg32WTo32A( hwnd
, msg
, wParam
, &lParam
) == -1) return 0;
2293 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2294 WINPROC_UnmapMsg32WTo32A( hwnd
, msg
, wParam
, lParam
);
2299 /**********************************************************************
2300 * WINPROC_CallProc16To32A
2302 * Call a 32-bit window procedure, translating the 16-bit args.
2304 static LRESULT
WINPROC_CallProc16To32A( WNDPROC func
, HWND16 hwnd
,
2305 UINT16 msg
, WPARAM16 wParam
,
2312 if (WINPROC_MapMsg16To32A( msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2314 result
= WINPROC_CallWndProc( func
, hwnd
, msg32
, wParam32
, lParam
);
2315 return WINPROC_UnmapMsg16To32A( hwnd
, msg32
, wParam32
, lParam
, result
);
2318 /**********************************************************************
2319 * WINPROC_Thunk16To32A
2321 static LRESULT WINAPI
WINPROC_Thunk16To32A( WNDPROC func
, LPBYTE args
)
2323 HWND16 hwnd
= *(HWND16
*)( args
+8 );
2324 UINT16 msg
= *(HWND16
*)( args
+6 );
2325 WPARAM16 wParam
= *(HWND16
*)( args
+4 );
2326 LPARAM lParam
= *(LPARAM
*)( args
+0 );
2328 return WINPROC_CallProc16To32A( func
, hwnd
, msg
, wParam
, lParam
);
2332 /**********************************************************************
2333 * WINPROC_CallProc16To32W
2335 * Call a 32-bit window procedure, translating the 16-bit args.
2337 static LRESULT
WINPROC_CallProc16To32W( WNDPROC func
, HWND16 hwnd
,
2338 UINT16 msg
, WPARAM16 wParam
,
2345 if (WINPROC_MapMsg16To32W( hwnd
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2348 result
= WINPROC_CallWndProc( func
, hwnd
, msg32
, wParam32
, lParam
);
2350 return WINPROC_UnmapMsg16To32W( hwnd
, msg32
, wParam32
, lParam
, result
);
2353 /**********************************************************************
2354 * WINPROC_Thunk16To32W
2356 static LRESULT WINAPI
WINPROC_Thunk16To32W( WNDPROC func
, LPBYTE args
)
2358 HWND16 hwnd
= *(HWND16
*)( args
+8 );
2359 UINT16 msg
= *(HWND16
*)( args
+6 );
2360 WPARAM16 wParam
= *(HWND16
*)( args
+4 );
2361 LPARAM lParam
= *(LPARAM
*)( args
+0 );
2363 return WINPROC_CallProc16To32W( func
, hwnd
, msg
, wParam
, lParam
);
2366 /**********************************************************************
2367 * WINPROC_CallProc32ATo16
2369 * Call a 16-bit window procedure, translating the 32-bit args.
2371 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
2372 UINT msg
, WPARAM wParam
,
2378 mp16
.lParam
= lParam
;
2379 if (WINPROC_MapMsg32ATo16( hwnd
, msg
, wParam
,
2380 &msg16
, &mp16
.wParam
, &mp16
.lParam
) == -1)
2382 mp16
.lResult
= WINPROC_CallWndProc16( func
, hwnd
, msg16
,
2383 mp16
.wParam
, mp16
.lParam
);
2384 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2385 return mp16
.lResult
;
2389 /**********************************************************************
2390 * WINPROC_CallProc32WTo16
2392 * Call a 16-bit window procedure, translating the 32-bit args.
2394 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
2395 UINT msg
, WPARAM wParam
,
2401 mp16
.lParam
= lParam
;
2402 if (WINPROC_MapMsg32WTo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
,
2403 &mp16
.lParam
) == -1)
2405 mp16
.lResult
= WINPROC_CallWndProc16( func
, hwnd
, msg16
,
2406 mp16
.wParam
, mp16
.lParam
);
2407 WINPROC_UnmapMsg32WTo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2408 return mp16
.lResult
;
2412 /**********************************************************************
2413 * CallWindowProc16 (USER.122)
2415 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
2416 WPARAM16 wParam
, LPARAM lParam
)
2418 WINDOWPROC
*proc
= WINPROC_GetPtr( func
);
2421 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2424 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_16
);
2425 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2431 if (!proc
->thunk
.t_from32
.proc
) return 0;
2432 return WINPROC_CallWndProc16( proc
->thunk
.t_from32
.proc
,
2433 hwnd
, msg
, wParam
, lParam
);
2435 if (!proc
->thunk
.t_from16
.proc
) return 0;
2436 return WINPROC_CallProc16To32A( proc
->thunk
.t_from16
.proc
,
2437 hwnd
, msg
, wParam
, lParam
);
2439 if (!proc
->thunk
.t_from16
.proc
) return 0;
2440 return WINPROC_CallProc16To32W( proc
->thunk
.t_from16
.proc
,
2441 hwnd
, msg
, wParam
, lParam
);
2443 WARN_(relay
)("Invalid proc %p\n", proc
);
2449 /**********************************************************************
2450 * CallWindowProcA (USER32.18)
2452 * The CallWindowProc() function invokes the windows procedure _func_,
2453 * with _hwnd_ as the target window, the message specified by _msg_, and
2454 * the message parameters _wParam_ and _lParam_.
2456 * Some kinds of argument conversion may be done, I'm not sure what.
2458 * CallWindowProc() may be used for windows subclassing. Use
2459 * SetWindowLong() to set a new windows procedure for windows of the
2460 * subclass, and handle subclassed messages in the new windows
2461 * procedure. The new windows procedure may then use CallWindowProc()
2462 * with _func_ set to the parent class's windows procedure to dispatch
2463 * the message to the superclass.
2467 * The return value is message dependent.
2473 LRESULT WINAPI
CallWindowProcA(
2474 WNDPROC func
, /* window procedure */
2475 HWND hwnd
, /* target window */
2476 UINT msg
, /* message */
2477 WPARAM wParam
, /* message dependent parameter */
2478 LPARAM lParam
/* message dependent parameter */
2480 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2482 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2485 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32A
);
2486 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2492 if (!proc
->thunk
.t_from32
.proc
) return 0;
2493 return WINPROC_CallProc32ATo16( proc
->thunk
.t_from32
.proc
,
2494 hwnd
, msg
, wParam
, lParam
);
2496 if (!proc
->thunk
.t_from16
.proc
) return 0;
2497 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2498 hwnd
, msg
, wParam
, lParam
);
2500 if (!proc
->thunk
.t_from16
.proc
) return 0;
2501 return WINPROC_CallProc32ATo32W( proc
->thunk
.t_from16
.proc
,
2502 hwnd
, msg
, wParam
, lParam
);
2504 WARN_(relay
)("Invalid proc %p\n", proc
);
2510 /**********************************************************************
2511 * CallWindowProcW (USER32.19)
2513 LRESULT WINAPI
CallWindowProcW( WNDPROC func
, HWND hwnd
, UINT msg
,
2514 WPARAM wParam
, LPARAM lParam
)
2516 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2518 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2521 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32W
);
2522 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2528 if (!proc
->thunk
.t_from32
.proc
) return 0;
2529 return WINPROC_CallProc32WTo16( proc
->thunk
.t_from32
.proc
,
2530 hwnd
, msg
, wParam
, lParam
);
2532 if (!proc
->thunk
.t_from16
.proc
) return 0;
2533 return WINPROC_CallProc32WTo32A( proc
->thunk
.t_from16
.proc
,
2534 hwnd
, msg
, wParam
, lParam
);
2536 if (!proc
->thunk
.t_from16
.proc
) return 0;
2537 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2538 hwnd
, msg
, wParam
, lParam
);
2540 WARN_(relay
)("Invalid proc %p\n", proc
);