2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/port.h"
31 #include "wine/winbase16.h"
32 #include "wine/winuser16.h"
33 #include "stackframe.h"
34 #include "selectors.h"
40 #include "wine/debug.h"
46 WINE_DECLARE_DEBUG_CHANNEL(msg
);
47 WINE_DECLARE_DEBUG_CHANNEL(relay
);
48 WINE_DECLARE_DEBUG_CHANNEL(win
);
52 /* Window procedure 16-to-32-bit thunk */
55 BYTE popl_eax
; /* popl %eax (return address) */
56 BYTE pushl_func
; /* pushl $proc */
58 BYTE pushl_eax
; /* pushl %eax */
59 BYTE ljmp
; /* ljmp relay*/
60 DWORD relay_offset
; /* __wine_call_wndproc_32A/W */
62 } WINPROC_THUNK_FROM16
;
64 /* Window procedure 32-to-16-bit thunk */
67 BYTE popl_eax
; /* popl %eax (return address) */
68 BYTE pushl_func
; /* pushl $proc */
70 BYTE pushl_eax
; /* pushl %eax */
71 BYTE jmp
; /* jmp relay (relative jump)*/
72 void (*relay
)(); /* WINPROC_CallProc32ATo16() */
73 } WINPROC_THUNK_FROM32
;
75 /* Simple jmp to call 32-bit procedure directly */
78 BYTE jmp
; /* jmp proc (relative jump) */
85 WINPROC_THUNK_FROM16 t_from16
;
86 WINPROC_THUNK_FROM32 t_from32
;
89 typedef struct tagWINDOWPROC
91 WINPROC_THUNK thunk
; /* Thunk */
92 WINPROC_JUMP jmp
; /* Jump */
93 struct tagWINDOWPROC
*next
; /* Next window proc */
94 UINT magic
; /* Magic number */
95 WINDOWPROCTYPE type
; /* Function type */
96 WINDOWPROCUSER user
; /* Function user */
99 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
101 #define WINPROC_THUNKPROC(pproc) \
102 (((pproc)->type == WIN_PROC_16) ? \
103 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
104 (WNDPROC16)((pproc)->thunk.t_from16.proc))
106 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
107 UINT msg
, WPARAM wParam
,
109 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
110 UINT msg
, WPARAM wParam
,
113 static HANDLE WinProcHeap
;
114 static WORD WinProcSel
;
117 /**********************************************************************
120 BOOL
WINPROC_Init(void)
122 WinProcHeap
= HeapCreate( 0, 0x10000, 0x10000 );
123 WinProcSel
= SELECTOR_AllocBlock( (void *)WinProcHeap
, 0x10000,
124 WINE_LDT_FLAGS_CODE
| WINE_LDT_FLAGS_32BIT
);
125 if (!WinProcHeap
|| !WinProcSel
)
127 WARN_(relay
)("Unable to create winproc heap\n" );
135 /* Some window procedures modify register they shouldn't, or are not
136 * properly declared stdcall; so we need a small assembly wrapper to
138 extern LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
139 WPARAM wParam
, LPARAM lParam
);
140 __ASM_GLOBAL_FUNC( WINPROC_wrapper
,
150 "movl 8(%ebp),%eax\n\t"
152 "leal -12(%ebp),%esp\n\t"
159 static inline LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
160 WPARAM wParam
, LPARAM lParam
)
162 return proc( hwnd
, msg
, wParam
, lParam
);
164 #endif /* __i386__ */
166 /**********************************************************************
167 * WINPROC_CallWndProc32
169 * Call a 32-bit WndProc.
171 static LRESULT
WINPROC_CallWndProc( WNDPROC proc
, HWND hwnd
, UINT msg
,
172 WPARAM wParam
, LPARAM lParam
)
177 hwnd
= WIN_GetFullHandle( hwnd
);
179 DPRINTF( "%04lx:Call window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
180 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
181 /* To avoid any deadlocks, all the locks on the windows structures
182 must be suspended before the control is passed to the application */
183 iWndsLocks
= WIN_SuspendWndsLock();
184 retvalue
= WINPROC_wrapper( proc
, hwnd
, msg
, wParam
, lParam
);
185 WIN_RestoreWndsLock(iWndsLocks
);
188 DPRINTF( "%04lx:Ret window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
189 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
, retvalue
);
193 /***********************************************************************
194 * WINPROC_CallWndProc16
196 * Call a 16-bit window procedure
198 static LRESULT WINAPI
WINPROC_CallWndProc16( WNDPROC16 proc
, HWND16 hwnd
,
199 UINT16 msg
, WPARAM16 wParam
,
206 TEB
*teb
= NtCurrentTeb();
209 /* Window procedures want ax = hInstance, ds = es = ss */
211 memset(&context
, '\0', sizeof(context
));
212 context
.SegDs
= context
.SegEs
= SELECTOROF(teb
->cur_stack
);
213 if (!(context
.Eax
= GetWindowWord( HWND_32(hwnd
), GWL_HINSTANCE
))) context
.Eax
= context
.SegDs
;
214 context
.SegCs
= SELECTOROF(proc
);
215 context
.Eip
= OFFSETOF(proc
);
216 context
.Ebp
= OFFSETOF(teb
->cur_stack
)
217 + (WORD
)&((STACK16FRAME
*)0)->bp
;
221 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
222 work if structures passed in lParam are placed in the stack/data
223 segment. Programmers easily make the mistake of converting lParam
224 to a near rather than a far pointer, since Windows apparently
225 allows this. We copy the structures to the 16 bit stack; this is
226 ugly but makes these programs work. */
231 offset
= sizeof(CREATESTRUCT16
); break;
233 offset
= sizeof(DRAWITEMSTRUCT16
); break;
235 offset
= sizeof(COMPAREITEMSTRUCT16
); break;
239 void *s
= MapSL(lParam
);
240 lParam
= stack16_push( offset
);
241 memcpy( MapSL(lParam
), s
, offset
);
245 iWndsLocks
= WIN_SuspendWndsLock();
247 args
= (WORD
*)THREAD_STACK16(teb
) - 5;
248 args
[0] = LOWORD(lParam
);
249 args
[1] = HIWORD(lParam
);
254 wine_call_to_16_regs_short( &context
, 5 * sizeof(WORD
) );
255 ret
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
256 if (offset
) stack16_pop( offset
);
258 WIN_RestoreWndsLock(iWndsLocks
);
264 /**********************************************************************
267 * Return a pointer to the win proc.
269 static WINDOWPROC
*WINPROC_GetPtr( WNDPROC handle
)
274 /* ptr cannot be < 64K */
275 if (!HIWORD(handle
)) return NULL
;
277 /* Check for a linear pointer */
279 ptr
= (BYTE
*)handle
;
280 /* First check if it is the jmp address */
281 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->jmp
);
282 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
284 /* Now it must be the thunk address */
285 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
286 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
289 /* Check for a segmented pointer */
291 if (!IsBadReadPtr16( (SEGPTR
)handle
, sizeof(proc
->thunk
) ))
293 ptr
= MapSL( (SEGPTR
)handle
);
294 /* It must be the thunk address */
295 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
296 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
304 /**********************************************************************
305 * WINPROC_AllocWinProc
307 * Allocate a new window procedure.
309 static WINDOWPROC
*WINPROC_AllocWinProc( WNDPROC func
, WINDOWPROCTYPE type
,
310 WINDOWPROCUSER user
)
312 static FARPROC16 relay_32A
, relay_32W
;
314 WINDOWPROC
*proc
, *oldproc
;
316 /* Allocate a window procedure */
318 if (!(proc
= HeapAlloc( WinProcHeap
, 0, sizeof(WINDOWPROC
) ))) return 0;
320 /* Check if the function is already a win proc */
322 if ((oldproc
= WINPROC_GetPtr( func
)))
331 proc
->thunk
.t_from32
.popl_eax
= 0x58; /* popl %eax */
332 proc
->thunk
.t_from32
.pushl_func
= 0x68; /* pushl $proc */
333 proc
->thunk
.t_from32
.proc
= (WNDPROC16
)func
;
334 proc
->thunk
.t_from32
.pushl_eax
= 0x50; /* pushl %eax */
335 proc
->thunk
.t_from32
.jmp
= 0xe9; /* jmp relay*/
336 proc
->thunk
.t_from32
.relay
= /* relative jump */
337 (void(*)())((DWORD
)WINPROC_CallProc32ATo16
-
338 (DWORD
)(&proc
->thunk
.t_from32
.relay
+ 1));
341 if (!relay_32A
) relay_32A
= GetProcAddress16( GetModuleHandle16("user"),
342 "__wine_call_wndproc_32A" );
343 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
344 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
345 proc
->thunk
.t_from16
.proc
= func
;
346 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
347 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
348 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32A
);
349 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32A
);
350 proc
->jmp
.jmp
= 0xe9;
351 /* Fixup relative jump */
352 proc
->jmp
.proc
= (WNDPROC
)((DWORD
)func
- (DWORD
)(&proc
->jmp
.proc
+ 1));
355 if (!relay_32W
) relay_32W
= GetProcAddress16( GetModuleHandle16("user"),
356 "__wine_call_wndproc_32W" );
357 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
358 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
359 proc
->thunk
.t_from16
.proc
= func
;
360 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
361 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
362 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32W
);
363 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32W
);
364 proc
->jmp
.jmp
= 0xe9;
365 /* Fixup relative jump */
366 proc
->jmp
.proc
= (WNDPROC
)((char *)func
- (char *)(&proc
->jmp
.proc
+ 1));
369 /* Should not happen */
372 proc
->magic
= WINPROC_MAGIC
;
377 TRACE_(win
)("(%p,%d): returning %p\n", func
, type
, proc
);
382 /**********************************************************************
385 * Get a window procedure pointer that can be passed to the Windows program.
387 WNDPROC16
WINPROC_GetProc( WNDPROC proc
, WINDOWPROCTYPE type
)
389 WINDOWPROC
*ptr
= (WINDOWPROC
*)proc
;
391 if (!proc
) return NULL
;
392 if (type
== WIN_PROC_16
) /* We want a 16:16 address */
394 if (ptr
->type
== WIN_PROC_16
)
395 return ptr
->thunk
.t_from32
.proc
;
397 return (WNDPROC16
)MAKESEGPTR( WinProcSel
, (char *)&ptr
->thunk
- (char *)WinProcHeap
);
399 else /* We want a 32-bit address */
401 if (ptr
->type
== WIN_PROC_16
)
402 return (WNDPROC16
)&ptr
->thunk
;
403 else if (type
!= ptr
->type
)
404 /* Have to return the jmp address if types don't match */
405 return (WNDPROC16
)&ptr
->jmp
;
407 /* Some Win16 programs want to get back the proc they set */
408 return (WNDPROC16
)ptr
->thunk
.t_from16
.proc
;
413 /**********************************************************************
416 * Set the window procedure for a window or class. There are
417 * three tree classes of winproc callbacks:
419 * 1) class -> wp - not subclassed
420 * class -> wp -> wp -> wp -> wp - SetClassLong()
422 * 2) window -' / - not subclassed
423 * window -> wp -> wp ' - SetWindowLong()
425 * 3) timer -> wp - SetTimer()
427 * Initially, winproc of the window points to the current winproc
428 * thunk of its class. Subclassing prepends a new thunk to the
429 * window winproc chain at the head of the list. Thus, window thunk
430 * list includes class thunks and the latter are preserved when the
431 * window is destroyed.
434 BOOL
WINPROC_SetProc( WNDPROC
*pFirst
, WNDPROC func
,
435 WINDOWPROCTYPE type
, WINDOWPROCUSER user
)
437 BOOL bRecycle
= FALSE
;
438 WINDOWPROC
*proc
, **ppPrev
;
440 /* Check if function is already in the list */
442 ppPrev
= (WINDOWPROC
**)pFirst
;
443 proc
= WINPROC_GetPtr( func
);
450 if ((*ppPrev
)->user
!= user
)
452 /* terminal thunk is being restored */
454 WINPROC_FreeProc( *pFirst
, (*ppPrev
)->user
);
455 *(WINDOWPROC
**)pFirst
= *ppPrev
;
464 if (((*ppPrev
)->type
== type
) &&
465 (func
== (WNDPROC
)WINPROC_THUNKPROC(*ppPrev
)))
467 if((*ppPrev
)->user
== user
)
473 WINPROC_FreeProc( (WNDPROC
)*ppPrev
, user
);
480 /* WPF_CLASS thunk terminates window thunk list */
481 if ((*ppPrev
)->user
!= user
) break;
482 ppPrev
= &(*ppPrev
)->next
;
487 /* Extract this thunk from the list */
489 *ppPrev
= proc
->next
;
491 else /* Allocate a new one */
493 if (proc
) /* Was already a win proc */
496 func
= (WNDPROC
)WINPROC_THUNKPROC(proc
);
498 proc
= WINPROC_AllocWinProc( func
, type
, user
);
499 if (!proc
) return FALSE
;
502 /* Add the win proc at the head of the list */
504 TRACE_(win
)("(%08x,%08x,%d): res=%08x\n",
505 (UINT
)*pFirst
, (UINT
)func
, type
, (UINT
)proc
);
506 proc
->next
= *(WINDOWPROC
**)pFirst
;
507 *(WINDOWPROC
**)pFirst
= proc
;
512 /**********************************************************************
515 * Free a list of win procs.
517 void WINPROC_FreeProc( WNDPROC proc
, WINDOWPROCUSER user
)
519 WINDOWPROC
*ptr
= (WINDOWPROC
*)proc
;
522 WINDOWPROC
*next
= ptr
->next
;
523 if (ptr
->user
!= user
) break;
524 TRACE_(win
)("freeing %p (%d)\n", ptr
, user
);
525 HeapFree( WinProcHeap
, 0, ptr
);
531 /**********************************************************************
532 * WINPROC_GetProcType
534 * Return the window procedure type.
536 WINDOWPROCTYPE
WINPROC_GetProcType( WNDPROC proc
)
539 (((WINDOWPROC
*)proc
)->magic
!= WINPROC_MAGIC
))
540 return WIN_PROC_INVALID
;
541 return ((WINDOWPROC
*)proc
)->type
;
543 /**********************************************************************
544 * WINPROC_TestCBForStr
546 * Return TRUE if the lparam is a string
548 inline static BOOL
WINPROC_TestCBForStr( HWND hwnd
)
550 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
551 return (!(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) || (style
& CBS_HASSTRINGS
));
553 /**********************************************************************
554 * WINPROC_TestLBForStr
556 * Return TRUE if the lparam is a string
558 inline static BOOL
WINPROC_TestLBForStr( HWND hwnd
)
560 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
561 return (!(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) || (style
& LBS_HASSTRINGS
));
564 /**********************************************************************
565 * WINPROC_MapMsg32ATo32W
567 * Map a message from Ansi to Unicode.
568 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
571 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
572 * the first four bytes are the handle of the icon
573 * when the WM_SETTEXT message has been used to set the icon
575 INT
WINPROC_MapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
580 case WM_ASKCBFORMATNAME
:
582 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
583 *pwparam
* sizeof(WCHAR
) + sizeof(LPARAM
) );
585 *ptr
++ = *plparam
; /* Store previous lParam */
586 *plparam
= (LPARAM
)ptr
;
589 /* lparam is string (0-terminated) */
591 case WM_WININICHANGE
:
592 case WM_DEVMODECHANGE
:
598 UNICODE_STRING usBuffer
;
599 if(!*plparam
) return 0;
600 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)*plparam
);
601 *plparam
= (LPARAM
)usBuffer
.Buffer
;
602 return (*plparam
? 1 : -1);
604 case WM_GETTEXTLENGTH
:
605 case CB_GETLBTEXTLEN
:
607 return 1; /* need to map result */
611 UNICODE_STRING usBuffer
;
613 { CREATESTRUCTW cs
; /* new structure */
614 LPCWSTR lpszName
; /* allocated Name */
615 LPCWSTR lpszClass
; /* allocated Class */
618 struct s
*xs
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct s
));
620 xs
->cs
= *(CREATESTRUCTW
*)*plparam
;
621 if (HIWORD(xs
->cs
.lpszName
))
623 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)xs
->cs
.lpszName
);
624 xs
->lpszName
= xs
->cs
.lpszName
= usBuffer
.Buffer
;
626 if (HIWORD(xs
->cs
.lpszClass
))
628 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)xs
->cs
.lpszClass
);
629 xs
->lpszClass
= xs
->cs
.lpszClass
= usBuffer
.Buffer
;
631 *plparam
= (LPARAM
)xs
;
636 MDICREATESTRUCTW
*cs
=
637 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
639 *cs
= *(MDICREATESTRUCTW
*)*plparam
;
640 if (HIWORD(cs
->szClass
))
642 UNICODE_STRING usBuffer
;
643 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)cs
->szClass
);
644 cs
->szClass
= usBuffer
.Buffer
;
646 if (HIWORD(cs
->szTitle
))
648 UNICODE_STRING usBuffer
;
649 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)cs
->szTitle
);
650 cs
->szTitle
= usBuffer
.Buffer
;
652 *plparam
= (LPARAM
)cs
;
658 case LB_INSERTSTRING
:
660 case LB_FINDSTRINGEXACT
:
661 case LB_SELECTSTRING
:
662 if(!*plparam
) return 0;
663 if ( WINPROC_TestLBForStr( hwnd
))
665 UNICODE_STRING usBuffer
;
666 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)*plparam
);
667 *plparam
= (LPARAM
)usBuffer
.Buffer
;
669 return (*plparam
? 1 : -1);
671 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
672 { if ( WINPROC_TestLBForStr( hwnd
))
673 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
675 *ptr
++ = *plparam
; /* Store previous lParam */
676 *plparam
= (LPARAM
)ptr
;
683 case CB_INSERTSTRING
:
684 case CB_FINDSTRINGEXACT
:
686 case CB_SELECTSTRING
:
687 if(!*plparam
) return 0;
688 if ( WINPROC_TestCBForStr( hwnd
))
690 UNICODE_STRING usBuffer
;
691 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)*plparam
);
692 *plparam
= (LPARAM
)usBuffer
.Buffer
;
694 return (*plparam
? 1 : -1);
696 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
697 { if ( WINPROC_TestCBForStr( hwnd
))
698 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
700 *ptr
++ = *plparam
; /* Store previous lParam */
701 *plparam
= (LPARAM
)ptr
;
708 { WORD len
= (WORD
)*plparam
;
709 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(WCHAR
) );
711 *ptr
++ = *plparam
; /* Store previous lParam */
712 *((WORD
*) ptr
) = len
; /* Store the length */
713 *plparam
= (LPARAM
)ptr
;
723 case EM_SETPASSWORDCHAR
:
725 BYTE ch
= LOWORD(*pwparam
);
727 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wch
, 1);
728 *pwparam
= MAKEWPARAM( wch
, HIWORD(*pwparam
) );
732 case WM_PAINTCLIPBOARD
:
733 case WM_SIZECLIPBOARD
:
734 FIXME_(msg
)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg
, hwnd
), msg
);
736 default: /* No translation needed */
742 /**********************************************************************
743 * WINPROC_UnmapMsg32ATo32W
745 * Unmap a message that was mapped from Ansi to Unicode.
747 LRESULT
WINPROC_UnmapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
753 case WM_ASKCBFORMATNAME
:
755 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
756 if (wParam
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
757 (LPSTR
)*ptr
, wParam
, NULL
, NULL
))
758 ((LPSTR
)*ptr
)[wParam
-1] = 0;
759 HeapFree( GetProcessHeap(), 0, ptr
);
762 case WM_GETTEXTLENGTH
:
763 case CB_GETLBTEXTLEN
:
765 /* there may be one DBCS char for each Unicode char */
771 { CREATESTRUCTW cs
; /* new structure */
772 LPWSTR lpszName
; /* allocated Name */
773 LPWSTR lpszClass
; /* allocated Class */
775 struct s
*xs
= (struct s
*)lParam
;
776 if (xs
->lpszName
) HeapFree( GetProcessHeap(), 0, xs
->lpszName
);
777 if (xs
->lpszClass
) HeapFree( GetProcessHeap(), 0, xs
->lpszClass
);
778 HeapFree( GetProcessHeap(), 0, xs
);
784 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
785 if (HIWORD(cs
->szTitle
))
786 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
787 if (HIWORD(cs
->szClass
))
788 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
789 HeapFree( GetProcessHeap(), 0, cs
);
794 case WM_WININICHANGE
:
795 case WM_DEVMODECHANGE
:
800 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
805 case LB_INSERTSTRING
:
807 case LB_FINDSTRINGEXACT
:
808 case LB_SELECTSTRING
:
809 if ( WINPROC_TestLBForStr( hwnd
))
810 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
814 { if ( WINPROC_TestLBForStr( hwnd
))
815 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
816 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
817 HeapFree( GetProcessHeap(), 0, ptr
);
824 case CB_INSERTSTRING
:
826 case CB_FINDSTRINGEXACT
:
827 case CB_SELECTSTRING
:
828 if ( WINPROC_TestCBForStr( hwnd
))
829 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
833 { if ( WINPROC_TestCBForStr( hwnd
))
834 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
835 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
836 HeapFree( GetProcessHeap(), 0, ptr
);
843 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lParam */
844 WORD len
= *(WORD
*) lParam
;
845 if (len
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
846 (LPSTR
)*ptr
, len
, NULL
, NULL
))
847 ((LPSTR
)*ptr
)[len
-1] = 0;
848 HeapFree( GetProcessHeap(), 0, ptr
);
856 /**********************************************************************
857 * WINPROC_MapMsg32WTo32A
859 * Map a message from Unicode to Ansi.
860 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
862 INT
WINPROC_MapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
867 case WM_ASKCBFORMATNAME
:
869 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
870 *pwparam
+ sizeof(LPARAM
) );
872 *ptr
++ = *plparam
; /* Store previous lParam */
873 *plparam
= (LPARAM
)ptr
;
878 case WM_WININICHANGE
:
879 case WM_DEVMODECHANGE
:
884 if(!*plparam
) return 0;
885 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
886 return (*plparam
? 1 : -1);
891 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
894 *cs
= *(CREATESTRUCTA
*)*plparam
;
895 if (HIWORD(cs
->lpszName
))
896 cs
->lpszName
= HEAP_strdupWtoA( GetProcessHeap(), 0,
897 (LPCWSTR
)cs
->lpszName
);
898 if (HIWORD(cs
->lpszClass
))
899 cs
->lpszClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
900 (LPCWSTR
)cs
->lpszClass
);
901 *plparam
= (LPARAM
)cs
;
906 MDICREATESTRUCTA
*cs
=
907 (MDICREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
909 *cs
= *(MDICREATESTRUCTA
*)*plparam
;
910 if (HIWORD(cs
->szTitle
))
911 cs
->szTitle
= HEAP_strdupWtoA( GetProcessHeap(), 0,
912 (LPCWSTR
)cs
->szTitle
);
913 if (HIWORD(cs
->szClass
))
914 cs
->szClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
915 (LPCWSTR
)cs
->szClass
);
916 *plparam
= (LPARAM
)cs
;
922 case LB_INSERTSTRING
:
924 case LB_FINDSTRINGEXACT
:
925 case LB_SELECTSTRING
:
926 if(!*plparam
) return 0;
927 if ( WINPROC_TestLBForStr( hwnd
))
928 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
929 return (*plparam
? 1 : -1);
931 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
932 { if ( WINPROC_TestLBForStr( hwnd
))
933 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
935 *ptr
++ = *plparam
; /* Store previous lParam */
936 *plparam
= (LPARAM
)ptr
;
943 case CB_INSERTSTRING
:
945 case CB_FINDSTRINGEXACT
:
946 case CB_SELECTSTRING
:
947 if(!*plparam
) return 0;
948 if ( WINPROC_TestCBForStr( hwnd
))
949 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
950 return (*plparam
? 1 : -1);
952 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
953 { if ( WINPROC_TestCBForStr( hwnd
))
954 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
956 *ptr
++ = *plparam
; /* Store previous lParam */
957 *plparam
= (LPARAM
)ptr
;
964 { WORD len
= (WORD
)*plparam
;
965 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(CHAR
) );
967 *ptr
++ = *plparam
; /* Store previous lParam */
968 *((WORD
*) ptr
) = len
; /* Store the length */
969 *plparam
= (LPARAM
)ptr
;
979 case EM_SETPASSWORDCHAR
:
981 WCHAR wch
= LOWORD(*pwparam
);
983 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
984 *pwparam
= MAKEWPARAM( ch
, HIWORD(*pwparam
) );
988 case WM_PAINTCLIPBOARD
:
989 case WM_SIZECLIPBOARD
:
990 FIXME_(msg
)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg
, hwnd
),msg
);
992 default: /* No translation needed */
998 /**********************************************************************
999 * WINPROC_UnmapMsg32WTo32A
1001 * Unmap a message that was mapped from Unicode to Ansi.
1003 void WINPROC_UnmapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1008 case WM_ASKCBFORMATNAME
:
1010 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1013 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, wParam
))
1014 ((LPWSTR
)*ptr
)[wParam
-1] = 0;
1016 HeapFree( GetProcessHeap(), 0, ptr
);
1021 case WM_WININICHANGE
:
1022 case WM_DEVMODECHANGE
:
1027 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1033 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1034 if (HIWORD(cs
->lpszName
))
1035 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszName
);
1036 if (HIWORD(cs
->lpszClass
))
1037 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszClass
);
1038 HeapFree( GetProcessHeap(), 0, cs
);
1044 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1045 if (HIWORD(cs
->szTitle
))
1046 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
1047 if (HIWORD(cs
->szClass
))
1048 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
1049 HeapFree( GetProcessHeap(), 0, cs
);
1055 case LB_INSERTSTRING
:
1057 case LB_FINDSTRINGEXACT
:
1058 case LB_SELECTSTRING
:
1059 if ( WINPROC_TestLBForStr( hwnd
))
1060 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1064 if ( WINPROC_TestLBForStr( hwnd
))
1066 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1067 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1068 HeapFree( GetProcessHeap(), 0, ptr
);
1074 case CB_INSERTSTRING
:
1076 case CB_FINDSTRINGEXACT
:
1077 case CB_SELECTSTRING
:
1078 if ( WINPROC_TestCBForStr( hwnd
))
1079 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1083 if ( WINPROC_TestCBForStr( hwnd
))
1085 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1086 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1087 HeapFree( GetProcessHeap(), 0, ptr
);
1091 /* Multiline edit */
1093 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lparam */
1094 WORD len
= *(WORD
*)ptr
;
1097 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, len
))
1098 ((LPWSTR
)*ptr
)[len
-1] = 0;
1100 HeapFree( GetProcessHeap(), 0, ptr
);
1106 static UINT
convert_handle_16_to_32(HANDLE16 src
, unsigned int flags
)
1109 UINT sz
= GlobalSize16(src
);
1112 if (!(dst
= GlobalAlloc(flags
, sz
)))
1114 ptr16
= GlobalLock16(src
);
1115 ptr32
= GlobalLock(dst
);
1116 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr32
, ptr16
, sz
);
1117 GlobalUnlock16(src
);
1123 /**********************************************************************
1124 * WINPROC_MapMsg16To32A
1126 * Map a message from 16- to 32-bit Ansi.
1127 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1129 INT
WINPROC_MapMsg16To32A( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1130 WPARAM
*pwparam32
, LPARAM
*plparam
)
1132 *pmsg32
= (UINT
)msg16
;
1133 *pwparam32
= (WPARAM
)wParam16
;
1140 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1141 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1145 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1146 *plparam
= (LPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1149 if ( HIWORD(*plparam
) > CTLCOLOR_STATIC
) return -1;
1150 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
1151 *pwparam32
= (WPARAM
)HDC_32(wParam16
);
1152 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1154 case WM_COMPAREITEM
:
1156 COMPAREITEMSTRUCT16
* cis16
= MapSL(*plparam
);
1157 COMPAREITEMSTRUCT
*cis
= (COMPAREITEMSTRUCT
*)
1158 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis
));
1159 if (!cis
) return -1;
1160 cis
->CtlType
= cis16
->CtlType
;
1161 cis
->CtlID
= cis16
->CtlID
;
1162 cis
->hwndItem
= WIN_Handle32( cis16
->hwndItem
);
1163 cis
->itemID1
= cis16
->itemID1
;
1164 cis
->itemData1
= cis16
->itemData1
;
1165 cis
->itemID2
= cis16
->itemID2
;
1166 cis
->itemData2
= cis16
->itemData2
;
1167 cis
->dwLocaleId
= 0; /* FIXME */
1168 *plparam
= (LPARAM
)cis
;
1173 DELETEITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1174 DELETEITEMSTRUCT
*dis
= (DELETEITEMSTRUCT
*)
1175 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis
));
1176 if (!dis
) return -1;
1177 dis
->CtlType
= dis16
->CtlType
;
1178 dis
->CtlID
= dis16
->CtlID
;
1179 dis
->hwndItem
= WIN_Handle32( dis16
->hwndItem
);
1180 dis
->itemData
= dis16
->itemData
;
1181 *plparam
= (LPARAM
)dis
;
1184 case WM_MEASUREITEM
:
1186 MEASUREITEMSTRUCT16
* mis16
= MapSL(*plparam
);
1187 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)
1188 HeapAlloc(GetProcessHeap(), 0,
1189 sizeof(*mis
) + sizeof(LPARAM
));
1190 if (!mis
) return -1;
1191 mis
->CtlType
= mis16
->CtlType
;
1192 mis
->CtlID
= mis16
->CtlID
;
1193 mis
->itemID
= mis16
->itemID
;
1194 mis
->itemWidth
= mis16
->itemWidth
;
1195 mis
->itemHeight
= mis16
->itemHeight
;
1196 mis
->itemData
= mis16
->itemData
;
1197 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1198 *plparam
= (LPARAM
)mis
;
1203 DRAWITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1204 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)HeapAlloc(GetProcessHeap(), 0,
1206 if (!dis
) return -1;
1207 dis
->CtlType
= dis16
->CtlType
;
1208 dis
->CtlID
= dis16
->CtlID
;
1209 dis
->itemID
= dis16
->itemID
;
1210 dis
->itemAction
= dis16
->itemAction
;
1211 dis
->itemState
= dis16
->itemState
;
1212 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND
)HMENU_32(dis16
->hwndItem
)
1213 : WIN_Handle32( dis16
->hwndItem
);
1214 dis
->hDC
= HDC_32(dis16
->hDC
);
1215 dis
->itemData
= dis16
->itemData
;
1216 CONV_RECT16TO32( &dis16
->rcItem
, &dis
->rcItem
);
1217 *plparam
= (LPARAM
)dis
;
1220 case WM_GETMINMAXINFO
:
1222 MINMAXINFO
*mmi
= (MINMAXINFO
*)HeapAlloc( GetProcessHeap(), 0,
1223 sizeof(*mmi
) + sizeof(LPARAM
));
1224 if (!mmi
) return -1;
1225 STRUCT32_MINMAXINFO16to32( MapSL(*plparam
), mmi
);
1226 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1227 *plparam
= (LPARAM
)mmi
;
1232 case WM_WININICHANGE
:
1233 case WM_DEVMODECHANGE
:
1234 case WM_ASKCBFORMATNAME
:
1235 *plparam
= (LPARAM
)MapSL(*plparam
);
1239 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1240 MDICREATESTRUCTA
*cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) + sizeof(LPARAM
) );
1242 STRUCT32_MDICREATESTRUCT16to32A( cs16
, cs
);
1243 cs
->szTitle
= MapSL(cs16
->szTitle
);
1244 cs
->szClass
= MapSL(cs16
->szClass
);
1245 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1246 *plparam
= (LPARAM
)cs
;
1249 case WM_MDIGETACTIVE
:
1250 *plparam
= (LPARAM
)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL
) );
1251 *(BOOL
*)(*plparam
) = 0;
1255 *pmsg32
=WM_MDIREFRESHMENU
;
1256 *pwparam32
= (WPARAM
)HMENU_32(LOWORD(*plparam
));
1257 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1260 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1261 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1264 if((LOWORD(*plparam
) & MF_POPUP
) && (LOWORD(*plparam
) != 0xFFFF))
1266 HMENU hmenu
=HMENU_32(HIWORD(*plparam
));
1267 UINT Pos
=MENU_FindSubMenu( &hmenu
, HMENU_32(wParam16
));
1268 if(Pos
==0xFFFF) Pos
=0; /* NO_SELECTED_ITEM */
1269 *pwparam32
= MAKEWPARAM( Pos
, LOWORD(*plparam
) );
1271 else *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1272 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1274 case WM_MDIACTIVATE
:
1277 *pwparam32
= (WPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1278 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1280 else /* message sent to MDI client */
1281 *pwparam32
= wParam16
;
1285 NCCALCSIZE_PARAMS16
*nc16
;
1286 NCCALCSIZE_PARAMS
*nc
;
1288 nc
= (NCCALCSIZE_PARAMS
*)HeapAlloc( GetProcessHeap(), 0,
1289 sizeof(*nc
) + sizeof(LPARAM
) );
1291 nc16
= MapSL(*plparam
);
1292 CONV_RECT16TO32( &nc16
->rgrc
[0], &nc
->rgrc
[0] );
1295 nc
->lppos
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1296 sizeof(*nc
->lppos
) );
1297 CONV_RECT16TO32( &nc16
->rgrc
[1], &nc
->rgrc
[1] );
1298 CONV_RECT16TO32( &nc16
->rgrc
[2], &nc
->rgrc
[2] );
1299 if (nc
->lppos
) STRUCT32_WINDOWPOS16to32( MapSL(nc16
->lppos
), nc
->lppos
);
1301 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1302 *plparam
= (LPARAM
)nc
;
1308 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1309 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
1310 sizeof(*cs
) + sizeof(LPARAM
) );
1312 STRUCT32_CREATESTRUCT16to32A( cs16
, cs
);
1313 cs
->lpszName
= MapSL(cs16
->lpszName
);
1314 cs
->lpszClass
= MapSL(cs16
->lpszClass
);
1315 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1316 *plparam
= (LPARAM
)cs
;
1319 case WM_PARENTNOTIFY
:
1320 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
1322 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1323 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1326 case WM_WINDOWPOSCHANGING
:
1327 case WM_WINDOWPOSCHANGED
:
1329 WINDOWPOS
*wp
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1330 sizeof(*wp
) + sizeof(LPARAM
) );
1332 STRUCT32_WINDOWPOS16to32( MapSL(*plparam
), wp
);
1333 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1334 *plparam
= (LPARAM
)wp
;
1340 LPMSG16 msg16
= MapSL(*plparam
);
1341 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1343 if (!msg32
) return -1;
1344 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1345 msg32
->lParam
= msg16
->lParam
;
1346 msg32
->time
= msg16
->time
;
1347 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1348 /* this is right, right? */
1349 if (WINPROC_MapMsg16To32A( msg32
->hwnd
, msg16
->message
,msg16
->wParam
,
1350 &msg32
->message
,&msg32
->wParam
,
1351 &msg32
->lParam
)<0) {
1352 HeapFree( GetProcessHeap(), 0, msg32
);
1355 *plparam
= (LPARAM
)msg32
;
1360 *plparam
= (LPARAM
)MapSL(*plparam
);
1362 case WM_ACTIVATEAPP
:
1363 /* We need this when SetActiveWindow sends a Sendmessage16() to
1364 * a 32bit window. Might be superflous with 32bit interprocess
1365 * message queues. */
1366 if (*plparam
) *plparam
= HTASK_32( *plparam
);
1370 MDINEXTMENU
*next
= HeapAlloc( GetProcessHeap(), 0, sizeof(*next
) );
1371 if (!next
) return -1;
1372 next
->hmenuIn
= (HMENU
)*plparam
;
1373 next
->hmenuNext
= 0;
1375 *plparam
= (LPARAM
)next
;
1378 case WM_PAINTCLIPBOARD
:
1379 case WM_SIZECLIPBOARD
:
1380 FIXME_(msg
)("message %04x needs translation\n",msg16
);
1382 case WM_DDE_INITIATE
:
1383 case WM_DDE_TERMINATE
:
1384 case WM_DDE_UNADVISE
:
1385 case WM_DDE_REQUEST
:
1386 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1396 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1397 lo16
= LOWORD(*plparam
);
1398 hi
= HIWORD(*plparam
);
1399 if (lo16
&& !(lo32
= convert_handle_16_to_32(lo16
, GMEM_DDESHARE
)))
1401 *plparam
= PackDDElParam(msg16
, lo32
, hi
);
1403 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1410 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1412 lo
= LOWORD(*plparam
);
1413 hi
= HIWORD(*plparam
);
1415 if (GlobalGetAtomNameA(hi
, buf
, 2) > 0) flag
|= 1;
1416 if (GlobalSize16(hi
) != 0) flag
|= 2;
1422 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1427 break; /* atom, nothing to do */
1429 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
1432 hi
= convert_handle_16_to_32(hi
, GMEM_DDESHARE
);
1435 *plparam
= PackDDElParam(WM_DDE_ACK
, lo
, hi
);
1437 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1438 case WM_DDE_EXECUTE
:
1439 *plparam
= convert_handle_16_to_32(*plparam
, GMEM_DDESHARE
);
1440 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1441 default: /* No translation needed */
1447 /**********************************************************************
1448 * WINPROC_UnmapMsg16To32A
1450 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1452 LRESULT
WINPROC_UnmapMsg16To32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1457 case WM_COMPAREITEM
:
1460 HeapFree( GetProcessHeap(), 0, (LPVOID
)lParam
);
1462 case WM_MEASUREITEM
:
1464 MEASUREITEMSTRUCT16
*mis16
;
1465 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)lParam
;
1466 lParam
= *(LPARAM
*)(mis
+ 1);
1467 mis16
= MapSL(lParam
);
1468 mis16
->itemWidth
= (UINT16
)mis
->itemWidth
;
1469 mis16
->itemHeight
= (UINT16
)mis
->itemHeight
;
1470 HeapFree( GetProcessHeap(), 0, mis
);
1473 case WM_GETMINMAXINFO
:
1475 MINMAXINFO
*mmi
= (MINMAXINFO
*)lParam
;
1476 lParam
= *(LPARAM
*)(mmi
+ 1);
1477 STRUCT32_MINMAXINFO32to16( mmi
, MapSL(lParam
));
1478 HeapFree( GetProcessHeap(), 0, mmi
);
1483 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1484 lParam
= *(LPARAM
*)(cs
+ 1);
1485 STRUCT32_MDICREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1486 HeapFree( GetProcessHeap(), 0, cs
);
1489 case WM_MDIGETACTIVE
:
1490 result
= MAKELONG( LOWORD(result
), (BOOL16
)(*(BOOL
*)lParam
) );
1491 HeapFree( GetProcessHeap(), 0, (BOOL
*)lParam
);
1495 NCCALCSIZE_PARAMS16
*nc16
;
1496 NCCALCSIZE_PARAMS
*nc
= (NCCALCSIZE_PARAMS
*)lParam
;
1497 lParam
= *(LPARAM
*)(nc
+ 1);
1498 nc16
= MapSL(lParam
);
1499 CONV_RECT32TO16( &nc
->rgrc
[0], &nc16
->rgrc
[0] );
1502 CONV_RECT32TO16( &nc
->rgrc
[1], &nc16
->rgrc
[1] );
1503 CONV_RECT32TO16( &nc
->rgrc
[2], &nc16
->rgrc
[2] );
1506 STRUCT32_WINDOWPOS32to16( nc
->lppos
, MapSL(nc16
->lppos
));
1507 HeapFree( GetProcessHeap(), 0, nc
->lppos
);
1510 HeapFree( GetProcessHeap(), 0, nc
);
1516 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1517 lParam
= *(LPARAM
*)(cs
+ 1);
1518 STRUCT32_CREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1519 HeapFree( GetProcessHeap(), 0, cs
);
1522 case WM_WINDOWPOSCHANGING
:
1523 case WM_WINDOWPOSCHANGED
:
1525 WINDOWPOS
*wp
= (WINDOWPOS
*)lParam
;
1526 lParam
= *(LPARAM
*)(wp
+ 1);
1527 STRUCT32_WINDOWPOS32to16(wp
, MapSL(lParam
));
1528 HeapFree( GetProcessHeap(), 0, wp
);
1534 LPMSG msg32
= (LPMSG
)lParam
;
1536 WINPROC_UnmapMsg16To32A( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1538 HeapFree( GetProcessHeap(), 0, msg32
);
1543 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1544 result
= MAKELONG( HMENU_16(next
->hmenuNext
), HWND_16(next
->hwndNext
) );
1545 HeapFree( GetProcessHeap(), 0, next
);
1553 /**********************************************************************
1554 * WINPROC_MapMsg16To32W
1556 * Map a message from 16- to 32-bit Unicode.
1557 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1559 INT
WINPROC_MapMsg16To32W( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1560 WPARAM
*pwparam32
, LPARAM
*plparam
)
1565 *pmsg32
=(UINT
)msg16
;
1566 *pwparam32
= (WPARAM
)wParam16
;
1571 case WM_WININICHANGE
:
1572 case WM_DEVMODECHANGE
:
1573 case WM_ASKCBFORMATNAME
:
1574 *plparam
= (LPARAM
)MapSL(*plparam
);
1575 return WINPROC_MapMsg32ATo32W( hwnd
, *pmsg32
, pwparam32
, plparam
);
1576 case WM_GETTEXTLENGTH
:
1577 case CB_GETLBTEXTLEN
:
1579 return 1; /* need to map result */
1583 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1584 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1585 sizeof(*cs
) + sizeof(LPARAM
) );
1587 STRUCT32_CREATESTRUCT16to32A( cs16
, (CREATESTRUCTA
*)cs
);
1588 cs
->lpszName
= map_str_16_to_32W(cs16
->lpszName
);
1589 cs
->lpszClass
= map_str_16_to_32W(cs16
->lpszClass
);
1590 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1591 *plparam
= (LPARAM
)cs
;
1596 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1597 MDICREATESTRUCTW
*cs
=
1598 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1599 sizeof(*cs
) + sizeof(LPARAM
) );
1601 STRUCT32_MDICREATESTRUCT16to32A( cs16
, (MDICREATESTRUCTA
*)cs
);
1602 cs
->szTitle
= map_str_16_to_32W(cs16
->szTitle
);
1603 cs
->szClass
= map_str_16_to_32W(cs16
->szClass
);
1604 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1605 *plparam
= (LPARAM
)cs
;
1611 LPMSG16 msg16
= MapSL(*plparam
);
1612 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1614 if (!msg32
) return -1;
1615 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1616 msg32
->lParam
= msg16
->lParam
;
1617 msg32
->time
= msg16
->time
;
1618 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1619 /* this is right, right? */
1620 if (WINPROC_MapMsg16To32W(hwnd
, msg16
->message
,msg16
->wParam
,
1621 &msg32
->message
,&msg32
->wParam
,
1622 &msg32
->lParam
)<0) {
1623 HeapFree( GetProcessHeap(), 0, msg32
);
1626 *plparam
= (LPARAM
)msg32
;
1633 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1634 *pwparam32
= MAKEWPARAM( wch
, HIWORD(*plparam
) );
1635 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1639 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1640 *pwparam32
= MAKEWPARAM( wch
, LOWORD(*plparam
) );
1641 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1646 case WM_SYSDEADCHAR
:
1648 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1652 default: /* No Unicode translation needed */
1653 return WINPROC_MapMsg16To32A( hwnd
, msg16
, wParam16
, pmsg32
,
1654 pwparam32
, plparam
);
1659 /**********************************************************************
1660 * WINPROC_UnmapMsg16To32W
1662 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1664 LRESULT
WINPROC_UnmapMsg16To32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1671 case WM_GETTEXTLENGTH
:
1672 case CB_GETLBTEXTLEN
:
1674 case WM_ASKCBFORMATNAME
:
1675 return WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
1679 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)lParam
;
1680 lParam
= *(LPARAM
*)(cs
+ 1);
1681 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs
, MapSL(lParam
) );
1682 unmap_str_16_to_32W( cs
->lpszName
);
1683 unmap_str_16_to_32W( cs
->lpszClass
);
1684 HeapFree( GetProcessHeap(), 0, cs
);
1689 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
1690 lParam
= *(LPARAM
*)(cs
+ 1);
1691 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs
, MapSL(lParam
) );
1692 unmap_str_16_to_32W( cs
->szTitle
);
1693 unmap_str_16_to_32W( cs
->szClass
);
1694 HeapFree( GetProcessHeap(), 0, cs
);
1700 LPMSG msg32
= (LPMSG
)lParam
;
1702 WINPROC_UnmapMsg16To32W( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1704 HeapFree( GetProcessHeap(), 0, msg32
);
1708 return WINPROC_UnmapMsg16To32A( hwnd
, msg
, wParam
, lParam
, result
);
1713 static HANDLE16
convert_handle_32_to_16(UINT src
, unsigned int flags
)
1716 UINT sz
= GlobalSize((HANDLE
)src
);
1719 if (!(dst
= GlobalAlloc16(flags
, sz
)))
1721 ptr32
= GlobalLock((HANDLE
)src
);
1722 ptr16
= GlobalLock16(dst
);
1723 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr16
, ptr32
, sz
);
1724 GlobalUnlock((HANDLE
)src
);
1725 GlobalUnlock16(dst
);
1731 /**********************************************************************
1732 * WINPROC_MapMsg32ATo16
1734 * Map a message from 32-bit Ansi to 16-bit.
1735 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1737 INT
WINPROC_MapMsg32ATo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
1738 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
1741 *pmsg16
= (UINT16
)msg32
;
1742 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1750 *pmsg16
= (UINT16
)msg32
+ (BM_GETCHECK16
- BM_GETCHECK
);
1759 case EM_SCROLLCARET
:
1762 case EM_GETLINECOUNT
:
1774 case EM_LINEFROMCHAR
:
1775 case EM_SETTABSTOPS
:
1776 case EM_SETPASSWORDCHAR
:
1777 case EM_EMPTYUNDOBUFFER
:
1778 case EM_GETFIRSTVISIBLELINE
:
1779 case EM_SETREADONLY
:
1780 case EM_SETWORDBREAKPROC
:
1781 case EM_GETWORDBREAKPROC
:
1782 case EM_GETPASSWORDCHAR
:
1783 *pmsg16
= (UINT16
)msg32
+ (EM_GETSEL16
- EM_GETSEL
);
1788 case LB_DELETESTRING
:
1789 case LB_GETANCHORINDEX
:
1790 case LB_GETCARETINDEX
:
1793 case LB_GETHORIZONTALEXTENT
:
1794 case LB_GETITEMDATA
:
1795 case LB_GETITEMHEIGHT
:
1797 case LB_GETSELCOUNT
:
1799 case LB_GETTOPINDEX
:
1800 case LB_RESETCONTENT
:
1801 case LB_SELITEMRANGE
:
1802 case LB_SELITEMRANGEEX
:
1803 case LB_SETANCHORINDEX
:
1804 case LB_SETCARETINDEX
:
1805 case LB_SETCOLUMNWIDTH
:
1807 case LB_SETHORIZONTALEXTENT
:
1808 case LB_SETITEMDATA
:
1809 case LB_SETITEMHEIGHT
:
1811 case LB_SETTOPINDEX
:
1812 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1814 case CB_DELETESTRING
:
1816 case CB_GETLBTEXTLEN
:
1818 case CB_RESETCONTENT
:
1822 case CB_SHOWDROPDOWN
:
1823 case CB_SETITEMDATA
:
1824 case CB_SETITEMHEIGHT
:
1825 case CB_GETITEMHEIGHT
:
1826 case CB_SETEXTENDEDUI
:
1827 case CB_GETEXTENDEDUI
:
1828 case CB_GETDROPPEDSTATE
:
1829 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1832 *pmsg16
= CB_GETEDITSEL16
;
1837 case LB_FINDSTRINGEXACT
:
1838 case LB_INSERTSTRING
:
1839 case LB_SELECTSTRING
:
1842 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1843 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1848 case CB_FINDSTRINGEXACT
:
1849 case CB_INSERTSTRING
:
1850 case CB_SELECTSTRING
:
1852 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1853 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1856 case LB_GETITEMRECT
:
1858 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1859 if (!rect
) return -1;
1860 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1861 *plparam
= MapLS( rect
);
1863 *pmsg16
= LB_GETITEMRECT16
;
1865 case LB_GETSELITEMS
:
1868 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1869 if (!(items
= HeapAlloc( GetProcessHeap(), 0,
1870 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1871 *((LPARAM
*)items
)++ = *plparam
; /* Store the previous lParam */
1872 *plparam
= MapLS( items
);
1874 *pmsg16
= LB_GETSELITEMS16
;
1876 case LB_SETTABSTOPS
:
1881 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1882 if (!(stops
= HeapAlloc( GetProcessHeap(), 0,
1883 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1884 for (i
= 0; i
< *pwparam16
; i
++) stops
[i
] = *((LPINT
)*plparam
+i
);
1885 *plparam
= MapLS( stops
);
1888 *pmsg16
= LB_SETTABSTOPS16
;
1891 case CB_GETDROPPEDCONTROLRECT
:
1893 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1894 if (!rect
) return -1;
1895 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1896 *plparam
= (LPARAM
)MapLS(rect
);
1898 *pmsg16
= CB_GETDROPPEDCONTROLRECT16
;
1902 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1903 *pmsg16
= LB_GETTEXT16
;
1907 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1908 *pmsg16
= CB_GETLBTEXT16
;
1913 *plparam
= MAKELONG( (INT16
)(INT
)wParam32
, (INT16
)*plparam
);
1914 *pmsg16
= EM_SETSEL16
;
1921 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
1925 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
1927 case WM_CTLCOLORMSGBOX
:
1928 case WM_CTLCOLOREDIT
:
1929 case WM_CTLCOLORLISTBOX
:
1930 case WM_CTLCOLORBTN
:
1931 case WM_CTLCOLORDLG
:
1932 case WM_CTLCOLORSCROLLBAR
:
1933 case WM_CTLCOLORSTATIC
:
1934 *pmsg16
= WM_CTLCOLOR
;
1935 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
1936 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
1938 case WM_COMPAREITEM
:
1940 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)*plparam
;
1941 COMPAREITEMSTRUCT16
*cis
= HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16
));
1942 if (!cis
) return -1;
1943 cis
->CtlType
= (UINT16
)cis32
->CtlType
;
1944 cis
->CtlID
= (UINT16
)cis32
->CtlID
;
1945 cis
->hwndItem
= HWND_16( cis32
->hwndItem
);
1946 cis
->itemID1
= (UINT16
)cis32
->itemID1
;
1947 cis
->itemData1
= cis32
->itemData1
;
1948 cis
->itemID2
= (UINT16
)cis32
->itemID2
;
1949 cis
->itemData2
= cis32
->itemData2
;
1950 *plparam
= MapLS( cis
);
1955 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)*plparam
;
1956 DELETEITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16
) );
1957 if (!dis
) return -1;
1958 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1959 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1960 dis
->itemID
= (UINT16
)dis32
->itemID
;
1961 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
1962 : HWND_16( dis32
->hwndItem
);
1963 dis
->itemData
= dis32
->itemData
;
1964 *plparam
= MapLS( dis
);
1969 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)*plparam
;
1970 DRAWITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16
) );
1971 if (!dis
) return -1;
1972 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1973 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1974 dis
->itemID
= (UINT16
)dis32
->itemID
;
1975 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
1976 dis
->itemState
= (UINT16
)dis32
->itemState
;
1977 dis
->hwndItem
= HWND_16( dis32
->hwndItem
);
1978 dis
->hDC
= HDC_16(dis32
->hDC
);
1979 dis
->itemData
= dis32
->itemData
;
1980 CONV_RECT32TO16( &dis32
->rcItem
, &dis
->rcItem
);
1981 *plparam
= MapLS( dis
);
1984 case WM_MEASUREITEM
:
1986 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)*plparam
;
1987 MEASUREITEMSTRUCT16
*mis
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mis
)+sizeof(LPARAM
));
1988 if (!mis
) return -1;
1989 mis
->CtlType
= (UINT16
)mis32
->CtlType
;
1990 mis
->CtlID
= (UINT16
)mis32
->CtlID
;
1991 mis
->itemID
= (UINT16
)mis32
->itemID
;
1992 mis
->itemWidth
= (UINT16
)mis32
->itemWidth
;
1993 mis
->itemHeight
= (UINT16
)mis32
->itemHeight
;
1994 mis
->itemData
= mis32
->itemData
;
1995 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1996 *plparam
= MapLS( mis
);
1999 case WM_GETMINMAXINFO
:
2001 MINMAXINFO16
*mmi
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi
) + sizeof(LPARAM
) );
2002 if (!mmi
) return -1;
2003 STRUCT32_MINMAXINFO32to16( (MINMAXINFO
*)*plparam
, mmi
);
2004 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
2005 *plparam
= MapLS( mmi
);
2009 case WM_ASKCBFORMATNAME
:
2012 *pwparam16
= (WPARAM16
)min( wParam32
, 0xff80 ); /* Must be < 64K */
2013 if (!(str
= HeapAlloc( GetProcessHeap(), 0, *pwparam16
+ sizeof(LPARAM
)))) return -1;
2014 *((LPARAM
*)str
)++ = *plparam
; /* Store the previous lParam */
2015 *plparam
= MapLS( str
);
2020 MDICREATESTRUCT16
*cs
;
2021 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)*plparam
;
2023 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2024 STRUCT32_MDICREATESTRUCT32Ato16( cs32
, cs
);
2025 cs
->szTitle
= MapLS( cs32
->szTitle
);
2026 cs
->szClass
= MapLS( cs32
->szClass
);
2027 *plparam
= MapLS( cs
);
2030 case WM_MDIGETACTIVE
:
2033 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
2034 (HMENU16
)LOWORD(*plparam
) );
2035 *pwparam16
= (*plparam
== 0);
2038 if(HIWORD(wParam32
) & MF_POPUP
)
2041 if (((UINT
)HIWORD(wParam32
) != 0xFFFF) || (*plparam
))
2043 if((hmenu
= GetSubMenu((HMENU
)*plparam
, *pwparam16
)))
2044 *pwparam16
=HMENU_16(hmenu
);
2049 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2051 case WM_MDIACTIVATE
:
2052 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2054 *pwparam16
= ((HWND
)*plparam
== hwnd
);
2055 *plparam
= MAKELPARAM( (HWND16
)LOWORD(*plparam
),
2056 (HWND16
)LOWORD(wParam32
) );
2060 *pwparam16
= HWND_16( (HWND
)wParam32
);
2066 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)*plparam
;
2067 NCCALCSIZE_PARAMS16
*nc
= HeapAlloc( GetProcessHeap(), 0, sizeof(*nc
) + sizeof(LPARAM
));
2070 CONV_RECT32TO16( &nc32
->rgrc
[0], &nc
->rgrc
[0] );
2074 CONV_RECT32TO16( &nc32
->rgrc
[1], &nc
->rgrc
[1] );
2075 CONV_RECT32TO16( &nc32
->rgrc
[2], &nc
->rgrc
[2] );
2076 if (!(wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16
) )))
2078 HeapFree( GetProcessHeap(), 0, nc
);
2081 STRUCT32_WINDOWPOS32to16( nc32
->lppos
, wp
);
2082 nc
->lppos
= MapLS( wp
);
2084 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
2085 *plparam
= MapLS( nc
);
2092 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)*plparam
;
2094 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2095 STRUCT32_CREATESTRUCT32Ato16( cs32
, cs
);
2096 cs
->lpszName
= MapLS( cs32
->lpszName
);
2097 cs
->lpszClass
= MapLS( cs32
->lpszClass
);
2098 *plparam
= MapLS( cs
);
2101 case WM_PARENTNOTIFY
:
2102 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
2103 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
2104 /* else nothing to do */
2107 *plparam
= MapLS( (NMHDR
*)*plparam
); /* NMHDR is already 32-bit */
2110 case WM_WININICHANGE
:
2111 case WM_DEVMODECHANGE
:
2112 *plparam
= MapLS( (LPSTR
)*plparam
);
2114 case WM_WINDOWPOSCHANGING
:
2115 case WM_WINDOWPOSCHANGED
:
2117 WINDOWPOS16
*wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(*wp
) + sizeof(LPARAM
) );
2119 STRUCT32_WINDOWPOS32to16( (WINDOWPOS
*)*plparam
, wp
);
2120 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
2121 *plparam
= MapLS( wp
);
2126 LPMSG msg32
= (LPMSG
) *plparam
;
2127 LPMSG16 msg16
= HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16
) );
2129 if (!msg16
) return -1;
2130 msg16
->hwnd
= HWND_16( msg32
->hwnd
);
2131 msg16
->lParam
= msg32
->lParam
;
2132 msg16
->time
= msg32
->time
;
2133 CONV_POINT32TO16(&msg32
->pt
,&msg16
->pt
);
2134 /* this is right, right? */
2135 if (WINPROC_MapMsg32ATo16(msg32
->hwnd
,msg32
->message
,msg32
->wParam
,
2136 &msg16
->message
,&msg16
->wParam
, &msg16
->lParam
)<0)
2138 HeapFree( GetProcessHeap(), 0, msg16
);
2141 *plparam
= MapLS( msg16
);
2146 case WM_ACTIVATEAPP
:
2147 if (*plparam
) *plparam
= HTASK_16( (HANDLE
)*plparam
);
2151 MDINEXTMENU
*next
= (MDINEXTMENU
*)*plparam
;
2152 *plparam
= (LPARAM
)next
->hmenuIn
;
2155 case WM_PAINTCLIPBOARD
:
2156 case WM_SIZECLIPBOARD
:
2157 FIXME_(msg
)("message %04x needs translation\n", msg32
);
2159 /* following messages should not be sent to 16-bit apps */
2162 case WM_CAPTURECHANGED
:
2163 case WM_STYLECHANGING
:
2164 case WM_STYLECHANGED
:
2166 case WM_DDE_INITIATE
:
2167 case WM_DDE_TERMINATE
:
2168 case WM_DDE_UNADVISE
:
2169 case WM_DDE_REQUEST
:
2170 *pwparam16
= HWND_16((HWND
)wParam32
);
2179 *pwparam16
= HWND_16((HWND
)wParam32
);
2180 UnpackDDElParam(msg32
, *plparam
, &lo32
, &hi
);
2181 if (lo32
&& !(lo16
= convert_handle_32_to_16(lo32
, GMEM_DDESHARE
)))
2183 *plparam
= MAKELPARAM(lo16
, hi
);
2185 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2192 *pwparam16
= HWND_16((HWND
)wParam32
);
2194 UnpackDDElParam(msg32
, *plparam
, &lo
, &hi
);
2196 if (GlobalGetAtomNameA((ATOM
)hi
, buf
, sizeof(buf
)) > 0) flag
|= 1;
2197 if (GlobalSize((HANDLE
)hi
) != 0) flag
|= 2;
2203 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
2208 break; /* atom, nothing to do */
2210 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
2213 hi
= convert_handle_32_to_16(hi
, GMEM_DDESHARE
);
2216 *plparam
= MAKELPARAM(lo
, hi
);
2218 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2219 case WM_DDE_EXECUTE
:
2220 *plparam
= convert_handle_32_to_16(*plparam
, GMEM_DDESHARE
);
2221 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2222 default: /* No translation needed */
2228 /**********************************************************************
2229 * WINPROC_UnmapMsg32ATo16
2231 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2233 void WINPROC_UnmapMsg32ATo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2242 case LB_FINDSTRINGEXACT
:
2243 case LB_INSERTSTRING
:
2244 case LB_SELECTSTRING
:
2248 case CB_FINDSTRINGEXACT
:
2249 case CB_INSERTSTRING
:
2250 case CB_SELECTSTRING
:
2254 case WM_WININICHANGE
:
2255 case WM_DEVMODECHANGE
:
2256 UnMapLS( (SEGPTR
)p16
->lParam
);
2258 case LB_SETTABSTOPS
:
2259 case WM_COMPAREITEM
:
2263 void *ptr
= MapSL( p16
->lParam
);
2264 UnMapLS( p16
->lParam
);
2265 HeapFree( GetProcessHeap(), 0, ptr
);
2268 case CB_GETDROPPEDCONTROLRECT
:
2269 case LB_GETITEMRECT
:
2271 RECT16
*rect
= MapSL(p16
->lParam
);
2272 UnMapLS( p16
->lParam
);
2273 p16
->lParam
= *(LPARAM
*)(rect
+ 1);
2274 CONV_RECT16TO32( rect
, (RECT
*)(p16
->lParam
));
2275 HeapFree( GetProcessHeap(), 0, rect
);
2278 case LB_GETSELITEMS
:
2281 LPINT16 items
= MapSL(p16
->lParam
);
2282 UnMapLS( p16
->lParam
);
2283 p16
->lParam
= *((LPARAM
*)items
- 1);
2284 for (i
= 0; i
< p16
->wParam
; i
++) *((LPINT
)(p16
->lParam
) + i
) = items
[i
];
2285 HeapFree( GetProcessHeap(), 0, (LPARAM
*)items
- 1 );
2291 *((PUINT
)(wParam
)) = LOWORD(p16
->lResult
);
2293 *((PUINT
)(lParam
)) = HIWORD(p16
->lResult
); /* FIXME: substract 1? */
2296 case WM_MEASUREITEM
:
2298 MEASUREITEMSTRUCT16
*mis
= MapSL(p16
->lParam
);
2299 MEASUREITEMSTRUCT
*mis32
= *(MEASUREITEMSTRUCT
**)(mis
+ 1);
2300 mis32
->itemWidth
= mis
->itemWidth
;
2301 mis32
->itemHeight
= mis
->itemHeight
;
2302 UnMapLS( p16
->lParam
);
2303 HeapFree( GetProcessHeap(), 0, mis
);
2306 case WM_GETMINMAXINFO
:
2308 MINMAXINFO16
*mmi
= MapSL(p16
->lParam
);
2309 UnMapLS( p16
->lParam
);
2310 p16
->lParam
= *(LPARAM
*)(mmi
+ 1);
2311 STRUCT32_MINMAXINFO16to32( mmi
, (MINMAXINFO
*)(p16
->lParam
) );
2312 HeapFree( GetProcessHeap(), 0, mmi
);
2316 case WM_ASKCBFORMATNAME
:
2318 LPSTR str
= MapSL(p16
->lParam
);
2319 UnMapLS( p16
->lParam
);
2320 p16
->lParam
= *((LPARAM
*)str
- 1);
2321 lstrcpynA( (LPSTR
)(p16
->lParam
), str
, p16
->wParam
);
2322 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2327 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2328 UnMapLS( cs
->szTitle
);
2329 UnMapLS( cs
->szClass
);
2330 UnMapLS( p16
->lParam
);
2331 HeapFree( GetProcessHeap(), 0, cs
);
2334 case WM_MDIGETACTIVE
:
2335 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(p16
->lResult
);
2336 p16
->lResult
= (LRESULT
)WIN_Handle32( LOWORD(p16
->lResult
) );
2340 NCCALCSIZE_PARAMS
*nc32
;
2341 NCCALCSIZE_PARAMS16
*nc
= MapSL(p16
->lParam
);
2342 UnMapLS( p16
->lParam
);
2343 p16
->lParam
= *(LPARAM
*)(nc
+ 1);
2344 nc32
= (NCCALCSIZE_PARAMS
*)(p16
->lParam
);
2345 CONV_RECT16TO32( &nc
->rgrc
[0], &nc32
->rgrc
[0] );
2348 WINDOWPOS16
*pos
= MapSL(nc
->lppos
);
2349 UnMapLS( nc
->lppos
);
2350 CONV_RECT16TO32( &nc
->rgrc
[1], &nc32
->rgrc
[1] );
2351 CONV_RECT16TO32( &nc
->rgrc
[2], &nc32
->rgrc
[2] );
2352 STRUCT32_WINDOWPOS16to32( pos
, nc32
->lppos
);
2353 HeapFree( GetProcessHeap(), 0, pos
);
2355 HeapFree( GetProcessHeap(), 0, nc
);
2361 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2362 UnMapLS( p16
->lParam
);
2363 UnMapLS( cs
->lpszName
);
2364 UnMapLS( cs
->lpszClass
);
2365 HeapFree( GetProcessHeap(), 0, cs
);
2368 case WM_WINDOWPOSCHANGING
:
2369 case WM_WINDOWPOSCHANGED
:
2371 WINDOWPOS16
*wp
= MapSL(p16
->lParam
);
2372 UnMapLS( p16
->lParam
);
2373 p16
->lParam
= *(LPARAM
*)(wp
+ 1);
2374 STRUCT32_WINDOWPOS16to32( wp
, (WINDOWPOS
*)p16
->lParam
);
2375 HeapFree( GetProcessHeap(), 0, wp
);
2379 UnMapLS(p16
->lParam
);
2384 LPMSG16 msg16
= MapSL(p16
->lParam
);
2386 UnMapLS( p16
->lParam
);
2387 msgp16
.wParam
=msg16
->wParam
;
2388 msgp16
.lParam
=msg16
->lParam
;
2389 WINPROC_UnmapMsg32ATo16(((LPMSG
)lParam
)->hwnd
, ((LPMSG
)lParam
)->message
,
2390 ((LPMSG
)lParam
)->wParam
, ((LPMSG
)lParam
)->lParam
,
2392 HeapFree( GetProcessHeap(), 0, msg16
);
2397 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
2398 next
->hmenuNext
= HMENU_32( LOWORD(p16
->lResult
) );
2399 next
->hwndNext
= WIN_Handle32( HIWORD(p16
->lResult
) );
2407 /**********************************************************************
2408 * WINPROC_MapMsg32WTo16
2410 * Map a message from 32-bit Unicode to 16-bit.
2411 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2413 INT
WINPROC_MapMsg32WTo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
2414 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
2420 *pmsg16
= LOWORD(msg32
);
2421 *pwparam16
= LOWORD(wParam32
);
2426 case LB_FINDSTRINGEXACT
:
2427 case LB_INSERTSTRING
:
2428 case LB_SELECTSTRING
:
2431 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2432 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2437 case CB_FINDSTRINGEXACT
:
2438 case CB_INSERTSTRING
:
2439 case CB_SELECTSTRING
:
2441 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2442 *pmsg16
= (UINT16
)msg32
+ (CB_ADDSTRING16
- CB_ADDSTRING
);
2449 CREATESTRUCTW
*cs32
= (CREATESTRUCTW
*)*plparam
;
2451 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2452 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs32
, cs
);
2453 cs
->lpszName
= map_str_32W_to_16( cs32
->lpszName
);
2454 cs
->lpszClass
= map_str_32W_to_16( cs32
->lpszClass
);
2455 *plparam
= MapLS(cs
);
2460 MDICREATESTRUCT16
*cs
;
2461 MDICREATESTRUCTW
*cs32
= (MDICREATESTRUCTW
*)*plparam
;
2463 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2464 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs32
, cs
);
2465 cs
->szTitle
= map_str_32W_to_16( cs32
->szTitle
);
2466 cs
->szClass
= map_str_32W_to_16( cs32
->szClass
);
2467 *plparam
= MapLS(cs
);
2471 case WM_WININICHANGE
:
2472 case WM_DEVMODECHANGE
:
2473 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2477 if ( WINPROC_TestLBForStr( hwnd
))
2479 LPSTR str
= HeapAlloc( GetProcessHeap(), 0, 256 ); /* FIXME: fixed sized buffer */
2480 if (!str
) return -1;
2481 *pmsg16
= (msg32
== LB_GETTEXT
)? LB_GETTEXT16
: CB_GETLBTEXT16
;
2482 *plparam
= (LPARAM
)MapLS(str
);
2487 wch
= LOWORD(wParam32
);
2488 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2490 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
2493 wch
= LOWORD(wParam32
);
2494 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2496 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2501 case WM_SYSDEADCHAR
:
2503 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2507 default: /* No Unicode translation needed (?) */
2508 return WINPROC_MapMsg32ATo16( hwnd
, msg32
, wParam32
, pmsg16
,
2509 pwparam16
, plparam
);
2514 /**********************************************************************
2515 * WINPROC_UnmapMsg32WTo16
2517 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2519 void WINPROC_UnmapMsg32WTo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2526 case LB_FINDSTRINGEXACT
:
2527 case LB_INSERTSTRING
:
2528 case LB_SELECTSTRING
:
2533 case CB_FINDSTRINGEXACT
:
2534 case CB_INSERTSTRING
:
2535 case CB_SELECTSTRING
:
2538 case WM_WININICHANGE
:
2539 case WM_DEVMODECHANGE
:
2540 unmap_str_32W_to_16( p16
->lParam
);
2545 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2546 UnMapLS( p16
->lParam
);
2547 unmap_str_32W_to_16( cs
->lpszName
);
2548 unmap_str_32W_to_16( cs
->lpszClass
);
2549 HeapFree( GetProcessHeap(), 0, cs
);
2554 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2555 UnMapLS( p16
->lParam
);
2556 unmap_str_32W_to_16( cs
->szTitle
);
2557 unmap_str_32W_to_16( cs
->szClass
);
2558 HeapFree( GetProcessHeap(), 0, cs
);
2562 case WM_ASKCBFORMATNAME
:
2564 LPSTR str
= MapSL(p16
->lParam
);
2565 UnMapLS( p16
->lParam
);
2566 p16
->lParam
= *((LPARAM
*)str
- 1);
2567 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)p16
->lParam
, 0x7fffffff );
2568 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2573 if ( WINPROC_TestLBForStr( hwnd
))
2575 LPSTR str
= MapSL(p16
->lParam
);
2576 UnMapLS( p16
->lParam
);
2577 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)lParam
, 0x7fffffff );
2578 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
);
2582 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, p16
);
2588 /**********************************************************************
2589 * WINPROC_CallProc32ATo32W
2591 * Call a window procedure, translating args from Ansi to Unicode.
2593 static LRESULT
WINPROC_CallProc32ATo32W( WNDPROC func
, HWND hwnd
,
2594 UINT msg
, WPARAM wParam
,
2600 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2601 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2603 if( (unmap
= WINPROC_MapMsg32ATo32W( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
2604 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2605 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2608 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2609 if (unmap
) result
= WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
2614 /**********************************************************************
2615 * WINPROC_CallProc32WTo32A
2617 * Call a window procedure, translating args from Unicode to Ansi.
2619 static LRESULT
WINPROC_CallProc32WTo32A( WNDPROC func
, HWND hwnd
,
2620 UINT msg
, WPARAM wParam
,
2626 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2627 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2629 if ((unmap
= WINPROC_MapMsg32WTo32A( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
2630 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2631 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2634 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2635 if( unmap
) WINPROC_UnmapMsg32WTo32A( hwnd
, msg
, wParam
, lParam
);
2640 /**********************************************************************
2641 * __wine_call_wndproc_32A (USER.1010)
2643 LRESULT WINAPI
__wine_call_wndproc_32A( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
2649 HWND hwnd32
= WIN_Handle32( hwnd
);
2651 if (WINPROC_MapMsg16To32A( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2653 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
2654 return WINPROC_UnmapMsg16To32A( hwnd32
, msg32
, wParam32
, lParam
, result
);
2658 /**********************************************************************
2659 * __wine_call_wndproc_32W (USER.1011)
2661 LRESULT WINAPI
__wine_call_wndproc_32W( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
2667 HWND hwnd32
= WIN_Handle32( hwnd
);
2669 if (WINPROC_MapMsg16To32W( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2671 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
2672 return WINPROC_UnmapMsg16To32W( hwnd32
, msg32
, wParam32
, lParam
, result
);
2676 /**********************************************************************
2677 * WINPROC_CallProc32ATo16
2679 * Call a 16-bit window procedure, translating the 32-bit args.
2681 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
2682 UINT msg
, WPARAM wParam
,
2688 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2689 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2691 mp16
.lParam
= lParam
;
2692 if (WINPROC_MapMsg32ATo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
, &mp16
.lParam
) == -1)
2694 mp16
.lResult
= WINPROC_CallWndProc16( func
, HWND_16(hwnd
), msg16
,
2695 mp16
.wParam
, mp16
.lParam
);
2696 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2697 return mp16
.lResult
;
2701 /**********************************************************************
2702 * WINPROC_CallProc32WTo16
2704 * Call a 16-bit window procedure, translating the 32-bit args.
2706 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
2707 UINT msg
, WPARAM wParam
,
2713 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2714 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2716 mp16
.lParam
= lParam
;
2717 if (WINPROC_MapMsg32WTo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
,
2718 &mp16
.lParam
) == -1)
2720 mp16
.lResult
= WINPROC_CallWndProc16( func
, HWND_16(hwnd
), msg16
,
2721 mp16
.wParam
, mp16
.lParam
);
2722 WINPROC_UnmapMsg32WTo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2723 return mp16
.lResult
;
2727 /**********************************************************************
2728 * CallWindowProc (USER.122)
2730 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
2731 WPARAM16 wParam
, LPARAM lParam
)
2735 if (!func
) return 0;
2737 if (!(proc
= WINPROC_GetPtr( (WNDPROC
)func
)))
2738 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2741 func
= WINPROC_GetProc( (WNDPROC
)proc
, WIN_PROC_16
);
2742 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2748 if (!proc
->thunk
.t_from32
.proc
) return 0;
2749 return WINPROC_CallWndProc16( proc
->thunk
.t_from32
.proc
,
2750 hwnd
, msg
, wParam
, lParam
);
2752 if (!proc
->thunk
.t_from16
.proc
) return 0;
2753 return __wine_call_wndproc_32A( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
2755 if (!proc
->thunk
.t_from16
.proc
) return 0;
2756 return __wine_call_wndproc_32W( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
2758 WARN_(relay
)("Invalid proc %p\n", proc
);
2764 /**********************************************************************
2765 * CallWindowProcA (USER32.@)
2767 * The CallWindowProc() function invokes the windows procedure _func_,
2768 * with _hwnd_ as the target window, the message specified by _msg_, and
2769 * the message parameters _wParam_ and _lParam_.
2771 * Some kinds of argument conversion may be done, I'm not sure what.
2773 * CallWindowProc() may be used for windows subclassing. Use
2774 * SetWindowLong() to set a new windows procedure for windows of the
2775 * subclass, and handle subclassed messages in the new windows
2776 * procedure. The new windows procedure may then use CallWindowProc()
2777 * with _func_ set to the parent class's windows procedure to dispatch
2778 * the message to the superclass.
2782 * The return value is message dependent.
2788 LRESULT WINAPI
CallWindowProcA(
2789 WNDPROC func
, /* [in] window procedure */
2790 HWND hwnd
, /* [in] target window */
2791 UINT msg
, /* [in] message */
2792 WPARAM wParam
, /* [in] message dependent parameter */
2793 LPARAM lParam
/* [in] message dependent parameter */
2795 WINDOWPROC
*proc
= WINPROC_GetPtr( func
);
2797 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2800 func
= WINPROC_GetProc( (WNDPROC
)proc
, WIN_PROC_32A
);
2801 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2807 if (!proc
->thunk
.t_from32
.proc
) return 0;
2808 return WINPROC_CallProc32ATo16( proc
->thunk
.t_from32
.proc
,
2809 hwnd
, msg
, wParam
, lParam
);
2811 if (!proc
->thunk
.t_from16
.proc
) return 0;
2812 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2813 hwnd
, msg
, wParam
, lParam
);
2815 if (!proc
->thunk
.t_from16
.proc
) return 0;
2816 return WINPROC_CallProc32ATo32W( proc
->thunk
.t_from16
.proc
,
2817 hwnd
, msg
, wParam
, lParam
);
2819 WARN_(relay
)("Invalid proc %p\n", proc
);
2825 /**********************************************************************
2826 * CallWindowProcW (USER32.@)
2828 LRESULT WINAPI
CallWindowProcW( WNDPROC func
, HWND hwnd
, UINT msg
,
2829 WPARAM wParam
, LPARAM lParam
)
2831 WINDOWPROC
*proc
= WINPROC_GetPtr( func
);
2833 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2836 func
= WINPROC_GetProc( (WNDPROC
)proc
, WIN_PROC_32W
);
2837 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2843 if (!proc
->thunk
.t_from32
.proc
) return 0;
2844 return WINPROC_CallProc32WTo16( proc
->thunk
.t_from32
.proc
,
2845 hwnd
, msg
, wParam
, lParam
);
2847 if (!proc
->thunk
.t_from16
.proc
) return 0;
2848 return WINPROC_CallProc32WTo32A( proc
->thunk
.t_from16
.proc
,
2849 hwnd
, msg
, wParam
, lParam
);
2851 if (!proc
->thunk
.t_from16
.proc
) return 0;
2852 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2853 hwnd
, msg
, wParam
, lParam
);
2855 WARN_(relay
)("Invalid proc %p\n", proc
);