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"
45 WINE_DECLARE_DEBUG_CHANNEL(msg
);
46 WINE_DECLARE_DEBUG_CHANNEL(relay
);
47 WINE_DECLARE_DEBUG_CHANNEL(win
);
51 /* Window procedure 16-to-32-bit thunk */
54 BYTE popl_eax
; /* popl %eax (return address) */
55 BYTE pushl_func
; /* pushl $proc */
57 BYTE pushl_eax
; /* pushl %eax */
58 BYTE ljmp
; /* ljmp relay*/
59 DWORD relay_offset
; /* __wine_call_wndproc_32A/W */
61 } WINPROC_THUNK_FROM16
;
63 /* Window procedure 32-to-16-bit thunk */
66 BYTE popl_eax
; /* popl %eax (return address) */
67 BYTE pushl_func
; /* pushl $proc */
69 BYTE pushl_eax
; /* pushl %eax */
70 BYTE jmp
; /* jmp relay (relative jump)*/
71 void (*relay
)(); /* WINPROC_CallProc32ATo16() */
72 } WINPROC_THUNK_FROM32
;
74 /* Simple jmp to call 32-bit procedure directly */
77 BYTE jmp
; /* jmp proc (relative jump) */
84 WINPROC_THUNK_FROM16 t_from16
;
85 WINPROC_THUNK_FROM32 t_from32
;
88 typedef struct tagWINDOWPROC
90 WINPROC_THUNK thunk
; /* Thunk */
91 WINPROC_JUMP jmp
; /* Jump */
92 struct tagWINDOWPROC
*next
; /* Next window proc */
93 UINT magic
; /* Magic number */
94 WINDOWPROCTYPE type
; /* Function type */
95 WINDOWPROCUSER user
; /* Function user */
98 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
100 #define WINPROC_THUNKPROC(pproc) \
101 (((pproc)->type == WIN_PROC_16) ? \
102 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
103 (WNDPROC16)((pproc)->thunk.t_from16.proc))
105 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
106 UINT msg
, WPARAM wParam
,
108 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
109 UINT msg
, WPARAM wParam
,
112 static HANDLE WinProcHeap
;
113 static WORD WinProcSel
;
116 /**********************************************************************
119 BOOL
WINPROC_Init(void)
121 WinProcHeap
= HeapCreate( 0, 0x10000, 0x10000 );
122 WinProcSel
= SELECTOR_AllocBlock( (void *)WinProcHeap
, 0x10000,
123 WINE_LDT_FLAGS_CODE
| WINE_LDT_FLAGS_32BIT
);
124 if (!WinProcHeap
|| !WinProcSel
)
126 WARN_(relay
)("Unable to create winproc heap\n" );
134 /* Some window procedures modify register they shouldn't, or are not
135 * properly declared stdcall; so we need a small assembly wrapper to
137 extern LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
138 WPARAM wParam
, LPARAM lParam
);
139 __ASM_GLOBAL_FUNC( WINPROC_wrapper
,
149 "movl 8(%ebp),%eax\n\t"
151 "leal -12(%ebp),%esp\n\t"
158 static inline LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
159 WPARAM wParam
, LPARAM lParam
)
161 return proc( hwnd
, msg
, wParam
, lParam
);
163 #endif /* __i386__ */
165 /**********************************************************************
166 * WINPROC_CallWndProc32
168 * Call a 32-bit WndProc.
170 static LRESULT
WINPROC_CallWndProc( WNDPROC proc
, HWND hwnd
, UINT msg
,
171 WPARAM wParam
, LPARAM lParam
)
176 hwnd
= WIN_GetFullHandle( hwnd
);
178 DPRINTF( "%08lx:Call window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
179 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
180 /* To avoid any deadlocks, all the locks on the windows structures
181 must be suspended before the control is passed to the application */
182 iWndsLocks
= WIN_SuspendWndsLock();
183 retvalue
= WINPROC_wrapper( proc
, hwnd
, msg
, wParam
, lParam
);
184 WIN_RestoreWndsLock(iWndsLocks
);
187 DPRINTF( "%08lx:Ret window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
188 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
, retvalue
);
192 /***********************************************************************
193 * WINPROC_CallWndProc16
195 * Call a 16-bit window procedure
197 static LRESULT WINAPI
WINPROC_CallWndProc16( WNDPROC16 proc
, HWND16 hwnd
,
198 UINT16 msg
, WPARAM16 wParam
,
205 TEB
*teb
= NtCurrentTeb();
208 /* Window procedures want ax = hInstance, ds = es = ss */
210 memset(&context
, '\0', sizeof(context
));
211 context
.SegDs
= context
.SegEs
= SELECTOROF(teb
->cur_stack
);
212 if (!(context
.Eax
= GetWindowWord16( hwnd
, GWL_HINSTANCE
))) context
.Eax
= context
.SegDs
;
213 context
.SegCs
= SELECTOROF(proc
);
214 context
.Eip
= OFFSETOF(proc
);
215 context
.Ebp
= OFFSETOF(teb
->cur_stack
)
216 + (WORD
)&((STACK16FRAME
*)0)->bp
;
220 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
221 work if structures passed in lParam are placed in the stack/data
222 segment. Programmers easily make the mistake of converting lParam
223 to a near rather than a far pointer, since Windows apparently
224 allows this. We copy the structures to the 16 bit stack; this is
225 ugly but makes these programs work. */
230 offset
= sizeof(CREATESTRUCT16
); break;
232 offset
= sizeof(DRAWITEMSTRUCT16
); break;
234 offset
= sizeof(COMPAREITEMSTRUCT16
); break;
238 void *s
= MapSL(lParam
);
239 lParam
= stack16_push( offset
);
240 memcpy( MapSL(lParam
), s
, offset
);
244 iWndsLocks
= WIN_SuspendWndsLock();
246 args
= (WORD
*)THREAD_STACK16(teb
) - 5;
247 args
[0] = LOWORD(lParam
);
248 args
[1] = HIWORD(lParam
);
253 wine_call_to_16_regs_short( &context
, 5 * sizeof(WORD
) );
254 ret
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
255 if (offset
) stack16_pop( offset
);
257 WIN_RestoreWndsLock(iWndsLocks
);
263 /**********************************************************************
266 * Return a pointer to the win proc.
268 static WINDOWPROC
*WINPROC_GetPtr( WNDPROC16 handle
)
273 /* ptr cannot be < 64K */
274 if (!HIWORD(handle
)) return NULL
;
276 /* Check for a linear pointer */
278 ptr
= (BYTE
*)handle
;
279 /* First check if it is the jmp address */
280 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->jmp
);
281 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
283 /* Now it must be the thunk address */
284 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
285 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
288 /* Check for a segmented pointer */
290 if (!IsBadReadPtr16( (SEGPTR
)handle
, sizeof(proc
->thunk
) ))
292 ptr
= MapSL( (SEGPTR
)handle
);
293 /* It must be the thunk address */
294 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
295 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
303 /**********************************************************************
304 * WINPROC_AllocWinProc
306 * Allocate a new window procedure.
308 static WINDOWPROC
*WINPROC_AllocWinProc( WNDPROC16 func
, WINDOWPROCTYPE type
,
309 WINDOWPROCUSER user
)
311 static FARPROC16 relay_32A
, relay_32W
;
313 WINDOWPROC
*proc
, *oldproc
;
315 /* Allocate a window procedure */
317 if (!(proc
= HeapAlloc( WinProcHeap
, 0, sizeof(WINDOWPROC
) ))) return 0;
319 /* Check if the function is already a win proc */
321 if ((oldproc
= WINPROC_GetPtr( func
)))
330 proc
->thunk
.t_from32
.popl_eax
= 0x58; /* popl %eax */
331 proc
->thunk
.t_from32
.pushl_func
= 0x68; /* pushl $proc */
332 proc
->thunk
.t_from32
.proc
= func
;
333 proc
->thunk
.t_from32
.pushl_eax
= 0x50; /* pushl %eax */
334 proc
->thunk
.t_from32
.jmp
= 0xe9; /* jmp relay*/
335 proc
->thunk
.t_from32
.relay
= /* relative jump */
336 (void(*)())((DWORD
)WINPROC_CallProc32ATo16
-
337 (DWORD
)(&proc
->thunk
.t_from32
.relay
+ 1));
340 if (!relay_32A
) relay_32A
= GetProcAddress16( GetModuleHandle16("user"),
341 "__wine_call_wndproc_32A" );
342 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
343 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
344 proc
->thunk
.t_from16
.proc
= (WNDPROC
)func
;
345 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
346 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
347 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32A
);
348 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32A
);
349 proc
->jmp
.jmp
= 0xe9;
350 /* Fixup relative jump */
351 proc
->jmp
.proc
= (WNDPROC
)((DWORD
)func
- (DWORD
)(&proc
->jmp
.proc
+ 1));
354 if (!relay_32W
) relay_32W
= GetProcAddress16( GetModuleHandle16("user"),
355 "__wine_call_wndproc_32W" );
356 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
357 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
358 proc
->thunk
.t_from16
.proc
= (WNDPROC
)func
;
359 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
360 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
361 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32W
);
362 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32W
);
363 proc
->jmp
.jmp
= 0xe9;
364 /* Fixup relative jump */
365 proc
->jmp
.proc
= (WNDPROC
)((DWORD
)func
- (DWORD
)(&proc
->jmp
.proc
+ 1));
368 /* Should not happen */
371 proc
->magic
= WINPROC_MAGIC
;
376 TRACE_(win
)("(%08x,%d): returning %08x\n",
377 (UINT
)func
, type
, (UINT
)proc
);
382 /**********************************************************************
385 * Get a window procedure pointer that can be passed to the Windows program.
387 WNDPROC16
WINPROC_GetProc( HWINDOWPROC 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( HWINDOWPROC
*pFirst
, WNDPROC16 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
== WINPROC_THUNKPROC(*ppPrev
)))
467 if((*ppPrev
)->user
== user
)
473 WINPROC_FreeProc( *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
= 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( HWINDOWPROC proc
, WINDOWPROCUSER user
)
521 WINDOWPROC
*next
= ((WINDOWPROC
*)proc
)->next
;
522 if (((WINDOWPROC
*)proc
)->user
!= user
) break;
523 TRACE_(win
)("freeing %08x (%d)\n", (UINT
)proc
, user
);
524 HeapFree( WinProcHeap
, 0, proc
);
530 /**********************************************************************
531 * WINPROC_GetProcType
533 * Return the window procedure type.
535 WINDOWPROCTYPE
WINPROC_GetProcType( HWINDOWPROC proc
)
538 (((WINDOWPROC
*)proc
)->magic
!= WINPROC_MAGIC
))
539 return WIN_PROC_INVALID
;
540 return ((WINDOWPROC
*)proc
)->type
;
542 /**********************************************************************
543 * WINPROC_TestCBForStr
545 * Return TRUE if the lparam is a string
547 inline static BOOL
WINPROC_TestCBForStr( HWND hwnd
)
549 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
550 return (!(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) || (style
& CBS_HASSTRINGS
));
552 /**********************************************************************
553 * WINPROC_TestLBForStr
555 * Return TRUE if the lparam is a string
557 inline static BOOL
WINPROC_TestLBForStr( HWND hwnd
)
559 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
560 return (!(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) || (style
& LBS_HASSTRINGS
));
563 /**********************************************************************
564 * WINPROC_MapMsg32ATo32W
566 * Map a message from Ansi to Unicode.
567 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
570 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
571 * the first four bytes are the handle of the icon
572 * when the WM_SETTEXT message has been used to set the icon
574 INT
WINPROC_MapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
579 case WM_ASKCBFORMATNAME
:
581 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
582 *pwparam
* sizeof(WCHAR
) + sizeof(LPARAM
) );
584 *ptr
++ = *plparam
; /* Store previous lParam */
585 *plparam
= (LPARAM
)ptr
;
588 /* lparam is string (0-terminated) */
590 case WM_WININICHANGE
:
591 case WM_DEVMODECHANGE
:
596 if(!*plparam
) return 0;
597 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
598 return (*plparam
? 1 : -1);
599 case WM_GETTEXTLENGTH
:
600 case CB_GETLBTEXTLEN
:
602 return 1; /* need to map result */
607 { CREATESTRUCTW cs
; /* new structure */
608 LPCWSTR lpszName
; /* allocated Name */
609 LPCWSTR lpszClass
; /* allocated Class */
612 struct s
*xs
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct s
));
614 xs
->cs
= *(CREATESTRUCTW
*)*plparam
;
615 if (HIWORD(xs
->cs
.lpszName
))
616 xs
->lpszName
= xs
->cs
.lpszName
= HEAP_strdupAtoW( GetProcessHeap(), 0,
617 (LPCSTR
)xs
->cs
.lpszName
);
618 if (HIWORD(xs
->cs
.lpszClass
))
619 xs
->lpszClass
= xs
->cs
.lpszClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
620 (LPCSTR
)xs
->cs
.lpszClass
);
621 *plparam
= (LPARAM
)xs
;
626 MDICREATESTRUCTW
*cs
=
627 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
629 *cs
= *(MDICREATESTRUCTW
*)*plparam
;
630 if (HIWORD(cs
->szClass
))
631 cs
->szClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
632 (LPCSTR
)cs
->szClass
);
633 if (HIWORD(cs
->szTitle
))
634 cs
->szTitle
= HEAP_strdupAtoW( GetProcessHeap(), 0,
635 (LPCSTR
)cs
->szTitle
);
636 *plparam
= (LPARAM
)cs
;
642 case LB_INSERTSTRING
:
644 case LB_FINDSTRINGEXACT
:
645 case LB_SELECTSTRING
:
646 if(!*plparam
) return 0;
647 if ( WINPROC_TestLBForStr( hwnd
))
648 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
649 return (*plparam
? 1 : -1);
651 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
652 { if ( WINPROC_TestLBForStr( hwnd
))
653 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
655 *ptr
++ = *plparam
; /* Store previous lParam */
656 *plparam
= (LPARAM
)ptr
;
663 case CB_INSERTSTRING
:
664 case CB_FINDSTRINGEXACT
:
666 case CB_SELECTSTRING
:
667 if(!*plparam
) return 0;
668 if ( WINPROC_TestCBForStr( hwnd
))
669 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
670 return (*plparam
? 1 : -1);
672 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
673 { if ( WINPROC_TestCBForStr( hwnd
))
674 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
676 *ptr
++ = *plparam
; /* Store previous lParam */
677 *plparam
= (LPARAM
)ptr
;
684 { WORD len
= (WORD
)*plparam
;
685 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(WCHAR
) );
687 *ptr
++ = *plparam
; /* Store previous lParam */
688 *((WORD
*) ptr
) = len
; /* Store the length */
689 *plparam
= (LPARAM
)ptr
;
699 case EM_SETPASSWORDCHAR
:
701 BYTE ch
= LOWORD(*pwparam
);
703 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wch
, 1);
704 *pwparam
= MAKEWPARAM( wch
, HIWORD(*pwparam
) );
708 case WM_PAINTCLIPBOARD
:
709 case WM_SIZECLIPBOARD
:
710 FIXME_(msg
)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg
, hwnd
), msg
);
712 default: /* No translation needed */
718 /**********************************************************************
719 * WINPROC_UnmapMsg32ATo32W
721 * Unmap a message that was mapped from Ansi to Unicode.
723 LRESULT
WINPROC_UnmapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
729 case WM_ASKCBFORMATNAME
:
731 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
732 if (wParam
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
733 (LPSTR
)*ptr
, wParam
, NULL
, NULL
))
734 ((LPSTR
)*ptr
)[wParam
-1] = 0;
735 HeapFree( GetProcessHeap(), 0, ptr
);
738 case WM_GETTEXTLENGTH
:
739 case CB_GETLBTEXTLEN
:
741 /* there may be one DBCS char for each Unicode char */
747 { CREATESTRUCTW cs
; /* new structure */
748 LPWSTR lpszName
; /* allocated Name */
749 LPWSTR lpszClass
; /* allocated Class */
751 struct s
*xs
= (struct s
*)lParam
;
752 if (xs
->lpszName
) HeapFree( GetProcessHeap(), 0, xs
->lpszName
);
753 if (xs
->lpszClass
) HeapFree( GetProcessHeap(), 0, xs
->lpszClass
);
754 HeapFree( GetProcessHeap(), 0, xs
);
760 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
761 if (HIWORD(cs
->szTitle
))
762 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
763 if (HIWORD(cs
->szClass
))
764 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
765 HeapFree( GetProcessHeap(), 0, cs
);
770 case WM_WININICHANGE
:
771 case WM_DEVMODECHANGE
:
776 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
781 case LB_INSERTSTRING
:
783 case LB_FINDSTRINGEXACT
:
784 case LB_SELECTSTRING
:
785 if ( WINPROC_TestLBForStr( hwnd
))
786 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
790 { if ( WINPROC_TestLBForStr( hwnd
))
791 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
792 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
793 HeapFree( GetProcessHeap(), 0, ptr
);
800 case CB_INSERTSTRING
:
802 case CB_FINDSTRINGEXACT
:
803 case CB_SELECTSTRING
:
804 if ( WINPROC_TestCBForStr( hwnd
))
805 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
809 { if ( WINPROC_TestCBForStr( hwnd
))
810 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
811 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
812 HeapFree( GetProcessHeap(), 0, ptr
);
819 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lParam */
820 WORD len
= *(WORD
*) lParam
;
821 if (len
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
822 (LPSTR
)*ptr
, len
, NULL
, NULL
))
823 ((LPSTR
)*ptr
)[len
-1] = 0;
824 HeapFree( GetProcessHeap(), 0, ptr
);
832 /**********************************************************************
833 * WINPROC_MapMsg32WTo32A
835 * Map a message from Unicode to Ansi.
836 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
838 INT
WINPROC_MapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
843 case WM_ASKCBFORMATNAME
:
845 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
846 *pwparam
+ sizeof(LPARAM
) );
848 *ptr
++ = *plparam
; /* Store previous lParam */
849 *plparam
= (LPARAM
)ptr
;
854 case WM_WININICHANGE
:
855 case WM_DEVMODECHANGE
:
860 if(!*plparam
) return 0;
861 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
862 return (*plparam
? 1 : -1);
867 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
870 *cs
= *(CREATESTRUCTA
*)*plparam
;
871 if (HIWORD(cs
->lpszName
))
872 cs
->lpszName
= HEAP_strdupWtoA( GetProcessHeap(), 0,
873 (LPCWSTR
)cs
->lpszName
);
874 if (HIWORD(cs
->lpszClass
))
875 cs
->lpszClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
876 (LPCWSTR
)cs
->lpszClass
);
877 *plparam
= (LPARAM
)cs
;
882 MDICREATESTRUCTA
*cs
=
883 (MDICREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
885 *cs
= *(MDICREATESTRUCTA
*)*plparam
;
886 if (HIWORD(cs
->szTitle
))
887 cs
->szTitle
= HEAP_strdupWtoA( GetProcessHeap(), 0,
888 (LPCWSTR
)cs
->szTitle
);
889 if (HIWORD(cs
->szClass
))
890 cs
->szClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
891 (LPCWSTR
)cs
->szClass
);
892 *plparam
= (LPARAM
)cs
;
898 case LB_INSERTSTRING
:
900 case LB_FINDSTRINGEXACT
:
901 case LB_SELECTSTRING
:
902 if(!*plparam
) return 0;
903 if ( WINPROC_TestLBForStr( hwnd
))
904 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
905 return (*plparam
? 1 : -1);
907 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
908 { if ( WINPROC_TestLBForStr( hwnd
))
909 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
911 *ptr
++ = *plparam
; /* Store previous lParam */
912 *plparam
= (LPARAM
)ptr
;
919 case CB_INSERTSTRING
:
921 case CB_FINDSTRINGEXACT
:
922 case CB_SELECTSTRING
:
923 if(!*plparam
) return 0;
924 if ( WINPROC_TestCBForStr( hwnd
))
925 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
926 return (*plparam
? 1 : -1);
928 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
929 { if ( WINPROC_TestCBForStr( hwnd
))
930 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
932 *ptr
++ = *plparam
; /* Store previous lParam */
933 *plparam
= (LPARAM
)ptr
;
940 { WORD len
= (WORD
)*plparam
;
941 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(CHAR
) );
943 *ptr
++ = *plparam
; /* Store previous lParam */
944 *((WORD
*) ptr
) = len
; /* Store the length */
945 *plparam
= (LPARAM
)ptr
;
955 case EM_SETPASSWORDCHAR
:
957 WCHAR wch
= LOWORD(*pwparam
);
959 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
960 *pwparam
= MAKEWPARAM( ch
, HIWORD(*pwparam
) );
964 case WM_PAINTCLIPBOARD
:
965 case WM_SIZECLIPBOARD
:
966 FIXME_(msg
)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg
, hwnd
),msg
);
968 default: /* No translation needed */
974 /**********************************************************************
975 * WINPROC_UnmapMsg32WTo32A
977 * Unmap a message that was mapped from Unicode to Ansi.
979 void WINPROC_UnmapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
984 case WM_ASKCBFORMATNAME
:
986 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
989 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, wParam
))
990 ((LPWSTR
)*ptr
)[wParam
-1] = 0;
992 HeapFree( GetProcessHeap(), 0, ptr
);
997 case WM_WININICHANGE
:
998 case WM_DEVMODECHANGE
:
1003 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1009 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1010 if (HIWORD(cs
->lpszName
))
1011 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszName
);
1012 if (HIWORD(cs
->lpszClass
))
1013 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszClass
);
1014 HeapFree( GetProcessHeap(), 0, cs
);
1020 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1021 if (HIWORD(cs
->szTitle
))
1022 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
1023 if (HIWORD(cs
->szClass
))
1024 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
1025 HeapFree( GetProcessHeap(), 0, cs
);
1031 case LB_INSERTSTRING
:
1033 case LB_FINDSTRINGEXACT
:
1034 case LB_SELECTSTRING
:
1035 if ( WINPROC_TestLBForStr( hwnd
))
1036 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1040 if ( WINPROC_TestLBForStr( hwnd
))
1042 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1043 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1044 HeapFree( GetProcessHeap(), 0, ptr
);
1050 case CB_INSERTSTRING
:
1052 case CB_FINDSTRINGEXACT
:
1053 case CB_SELECTSTRING
:
1054 if ( WINPROC_TestCBForStr( hwnd
))
1055 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1059 if ( WINPROC_TestCBForStr( hwnd
))
1061 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1062 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1063 HeapFree( GetProcessHeap(), 0, ptr
);
1067 /* Multiline edit */
1069 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lparam */
1070 WORD len
= *(WORD
*)ptr
;
1073 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, len
))
1074 ((LPWSTR
)*ptr
)[len
-1] = 0;
1076 HeapFree( GetProcessHeap(), 0, ptr
);
1082 static HANDLE
convert_handle_16_to_32(HANDLE16 src
, unsigned int flags
)
1085 UINT sz
= GlobalSize16(src
);
1088 if (!(dst
= GlobalAlloc(flags
, sz
)))
1090 ptr16
= GlobalLock16(src
);
1091 ptr32
= GlobalLock(dst
);
1092 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr32
, ptr16
, sz
);
1093 GlobalUnlock16(src
);
1099 /**********************************************************************
1100 * WINPROC_MapMsg16To32A
1102 * Map a message from 16- to 32-bit Ansi.
1103 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1105 INT
WINPROC_MapMsg16To32A( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1106 WPARAM
*pwparam32
, LPARAM
*plparam
)
1108 *pmsg32
= (UINT
)msg16
;
1109 *pwparam32
= (WPARAM
)wParam16
;
1116 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1117 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1121 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1122 *plparam
= (LPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1125 if ( HIWORD(*plparam
) > CTLCOLOR_STATIC
) return -1;
1126 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
1127 *pwparam32
= (WPARAM
)HDC_32(wParam16
);
1128 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1130 case WM_COMPAREITEM
:
1132 COMPAREITEMSTRUCT16
* cis16
= MapSL(*plparam
);
1133 COMPAREITEMSTRUCT
*cis
= (COMPAREITEMSTRUCT
*)
1134 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis
));
1135 if (!cis
) return -1;
1136 cis
->CtlType
= cis16
->CtlType
;
1137 cis
->CtlID
= cis16
->CtlID
;
1138 cis
->hwndItem
= WIN_Handle32( cis16
->hwndItem
);
1139 cis
->itemID1
= cis16
->itemID1
;
1140 cis
->itemData1
= cis16
->itemData1
;
1141 cis
->itemID2
= cis16
->itemID2
;
1142 cis
->itemData2
= cis16
->itemData2
;
1143 cis
->dwLocaleId
= 0; /* FIXME */
1144 *plparam
= (LPARAM
)cis
;
1149 DELETEITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1150 DELETEITEMSTRUCT
*dis
= (DELETEITEMSTRUCT
*)
1151 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis
));
1152 if (!dis
) return -1;
1153 dis
->CtlType
= dis16
->CtlType
;
1154 dis
->CtlID
= dis16
->CtlID
;
1155 dis
->hwndItem
= WIN_Handle32( dis16
->hwndItem
);
1156 dis
->itemData
= dis16
->itemData
;
1157 *plparam
= (LPARAM
)dis
;
1160 case WM_MEASUREITEM
:
1162 MEASUREITEMSTRUCT16
* mis16
= MapSL(*plparam
);
1163 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)
1164 HeapAlloc(GetProcessHeap(), 0,
1165 sizeof(*mis
) + sizeof(LPARAM
));
1166 if (!mis
) return -1;
1167 mis
->CtlType
= mis16
->CtlType
;
1168 mis
->CtlID
= mis16
->CtlID
;
1169 mis
->itemID
= mis16
->itemID
;
1170 mis
->itemWidth
= mis16
->itemWidth
;
1171 mis
->itemHeight
= mis16
->itemHeight
;
1172 mis
->itemData
= mis16
->itemData
;
1173 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1174 *plparam
= (LPARAM
)mis
;
1179 DRAWITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1180 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)HeapAlloc(GetProcessHeap(), 0,
1182 if (!dis
) return -1;
1183 dis
->CtlType
= dis16
->CtlType
;
1184 dis
->CtlID
= dis16
->CtlID
;
1185 dis
->itemID
= dis16
->itemID
;
1186 dis
->itemAction
= dis16
->itemAction
;
1187 dis
->itemState
= dis16
->itemState
;
1188 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND
)HMENU_32(dis16
->hwndItem
)
1189 : WIN_Handle32( dis16
->hwndItem
);
1190 dis
->hDC
= dis16
->hDC
;
1191 dis
->itemData
= dis16
->itemData
;
1192 CONV_RECT16TO32( &dis16
->rcItem
, &dis
->rcItem
);
1193 *plparam
= (LPARAM
)dis
;
1196 case WM_GETMINMAXINFO
:
1198 MINMAXINFO
*mmi
= (MINMAXINFO
*)HeapAlloc( GetProcessHeap(), 0,
1199 sizeof(*mmi
) + sizeof(LPARAM
));
1200 if (!mmi
) return -1;
1201 STRUCT32_MINMAXINFO16to32( MapSL(*plparam
), mmi
);
1202 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1203 *plparam
= (LPARAM
)mmi
;
1208 case WM_WININICHANGE
:
1209 case WM_DEVMODECHANGE
:
1210 case WM_ASKCBFORMATNAME
:
1211 *plparam
= (LPARAM
)MapSL(*plparam
);
1215 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1216 MDICREATESTRUCTA
*cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) + sizeof(LPARAM
) );
1218 STRUCT32_MDICREATESTRUCT16to32A( cs16
, cs
);
1219 cs
->szTitle
= MapSL(cs16
->szTitle
);
1220 cs
->szClass
= MapSL(cs16
->szClass
);
1221 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1222 *plparam
= (LPARAM
)cs
;
1225 case WM_MDIGETACTIVE
:
1226 *plparam
= (LPARAM
)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL
) );
1227 *(BOOL
*)(*plparam
) = 0;
1231 *pmsg32
=WM_MDIREFRESHMENU
;
1232 *pwparam32
= (WPARAM
)HMENU_32(LOWORD(*plparam
));
1233 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1236 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1237 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1240 if((LOWORD(*plparam
) & MF_POPUP
) && (LOWORD(*plparam
) != 0xFFFF))
1242 HMENU hmenu
=HMENU_32(HIWORD(*plparam
));
1243 UINT Pos
=MENU_FindSubMenu( &hmenu
, wParam16
);
1244 if(Pos
==0xFFFF) Pos
=0; /* NO_SELECTED_ITEM */
1245 *pwparam32
= MAKEWPARAM( Pos
, LOWORD(*plparam
) );
1247 else *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1248 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1250 case WM_MDIACTIVATE
:
1253 *pwparam32
= (WPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1254 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1256 else /* message sent to MDI client */
1257 *pwparam32
= wParam16
;
1261 NCCALCSIZE_PARAMS16
*nc16
;
1262 NCCALCSIZE_PARAMS
*nc
;
1264 nc
= (NCCALCSIZE_PARAMS
*)HeapAlloc( GetProcessHeap(), 0,
1265 sizeof(*nc
) + sizeof(LPARAM
) );
1267 nc16
= MapSL(*plparam
);
1268 CONV_RECT16TO32( &nc16
->rgrc
[0], &nc
->rgrc
[0] );
1271 nc
->lppos
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1272 sizeof(*nc
->lppos
) );
1273 CONV_RECT16TO32( &nc16
->rgrc
[1], &nc
->rgrc
[1] );
1274 CONV_RECT16TO32( &nc16
->rgrc
[2], &nc
->rgrc
[2] );
1275 if (nc
->lppos
) STRUCT32_WINDOWPOS16to32( MapSL(nc16
->lppos
), nc
->lppos
);
1277 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1278 *plparam
= (LPARAM
)nc
;
1284 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1285 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
1286 sizeof(*cs
) + sizeof(LPARAM
) );
1288 STRUCT32_CREATESTRUCT16to32A( cs16
, cs
);
1289 cs
->lpszName
= MapSL(cs16
->lpszName
);
1290 cs
->lpszClass
= MapSL(cs16
->lpszClass
);
1291 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1292 *plparam
= (LPARAM
)cs
;
1295 case WM_PARENTNOTIFY
:
1296 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
1298 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1299 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1302 case WM_WINDOWPOSCHANGING
:
1303 case WM_WINDOWPOSCHANGED
:
1305 WINDOWPOS
*wp
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1306 sizeof(*wp
) + sizeof(LPARAM
) );
1308 STRUCT32_WINDOWPOS16to32( MapSL(*plparam
), wp
);
1309 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1310 *plparam
= (LPARAM
)wp
;
1316 LPMSG16 msg16
= MapSL(*plparam
);
1317 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1319 if (!msg32
) return -1;
1320 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1321 msg32
->lParam
= msg16
->lParam
;
1322 msg32
->time
= msg16
->time
;
1323 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1324 /* this is right, right? */
1325 if (WINPROC_MapMsg16To32A( msg32
->hwnd
, msg16
->message
,msg16
->wParam
,
1326 &msg32
->message
,&msg32
->wParam
,
1327 &msg32
->lParam
)<0) {
1328 HeapFree( GetProcessHeap(), 0, msg32
);
1331 *plparam
= (LPARAM
)msg32
;
1336 *plparam
= (LPARAM
)MapSL(*plparam
);
1338 case WM_ACTIVATEAPP
:
1339 /* We need this when SetActiveWindow sends a Sendmessage16() to
1340 * a 32bit window. Might be superflous with 32bit interprocess
1341 * message queues. */
1342 if (*plparam
) *plparam
= HTASK_32( *plparam
);
1346 MDINEXTMENU
*next
= HeapAlloc( GetProcessHeap(), 0, sizeof(*next
) );
1347 if (!next
) return -1;
1348 next
->hmenuIn
= *plparam
;
1349 next
->hmenuNext
= 0;
1351 *plparam
= (LPARAM
)next
;
1354 case WM_PAINTCLIPBOARD
:
1355 case WM_SIZECLIPBOARD
:
1356 FIXME_(msg
)("message %04x needs translation\n",msg16
);
1358 case WM_DDE_INITIATE
:
1359 case WM_DDE_TERMINATE
:
1360 case WM_DDE_UNADVISE
:
1361 case WM_DDE_REQUEST
:
1362 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1372 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1373 lo16
= LOWORD(*plparam
);
1374 hi
= HIWORD(*plparam
);
1375 if (lo16
&& !(lo32
= convert_handle_16_to_32(lo16
, GMEM_DDESHARE
)))
1377 *plparam
= PackDDElParam(msg16
, lo32
, hi
);
1379 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1386 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1388 lo
= LOWORD(*plparam
);
1389 hi
= HIWORD(*plparam
);
1391 if (GlobalGetAtomNameA(hi
, buf
, 2) > 0) flag
|= 1;
1392 if (GlobalSize16(hi
) != 0) flag
|= 2;
1398 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1403 break; /* atom, nothing to do */
1405 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
1408 hi
= convert_handle_16_to_32(hi
, GMEM_DDESHARE
);
1411 *plparam
= PackDDElParam(WM_DDE_ACK
, lo
, hi
);
1413 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1414 case WM_DDE_EXECUTE
:
1415 *plparam
= convert_handle_16_to_32(*plparam
, GMEM_DDESHARE
);
1416 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1417 default: /* No translation needed */
1423 /**********************************************************************
1424 * WINPROC_UnmapMsg16To32A
1426 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1428 LRESULT
WINPROC_UnmapMsg16To32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1433 case WM_COMPAREITEM
:
1436 HeapFree( GetProcessHeap(), 0, (LPVOID
)lParam
);
1438 case WM_MEASUREITEM
:
1440 MEASUREITEMSTRUCT16
*mis16
;
1441 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)lParam
;
1442 lParam
= *(LPARAM
*)(mis
+ 1);
1443 mis16
= MapSL(lParam
);
1444 mis16
->itemWidth
= (UINT16
)mis
->itemWidth
;
1445 mis16
->itemHeight
= (UINT16
)mis
->itemHeight
;
1446 HeapFree( GetProcessHeap(), 0, mis
);
1449 case WM_GETMINMAXINFO
:
1451 MINMAXINFO
*mmi
= (MINMAXINFO
*)lParam
;
1452 lParam
= *(LPARAM
*)(mmi
+ 1);
1453 STRUCT32_MINMAXINFO32to16( mmi
, MapSL(lParam
));
1454 HeapFree( GetProcessHeap(), 0, mmi
);
1459 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1460 lParam
= *(LPARAM
*)(cs
+ 1);
1461 STRUCT32_MDICREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1462 HeapFree( GetProcessHeap(), 0, cs
);
1465 case WM_MDIGETACTIVE
:
1466 result
= MAKELONG( LOWORD(result
), (BOOL16
)(*(BOOL
*)lParam
) );
1467 HeapFree( GetProcessHeap(), 0, (BOOL
*)lParam
);
1471 NCCALCSIZE_PARAMS16
*nc16
;
1472 NCCALCSIZE_PARAMS
*nc
= (NCCALCSIZE_PARAMS
*)lParam
;
1473 lParam
= *(LPARAM
*)(nc
+ 1);
1474 nc16
= MapSL(lParam
);
1475 CONV_RECT32TO16( &nc
->rgrc
[0], &nc16
->rgrc
[0] );
1478 CONV_RECT32TO16( &nc
->rgrc
[1], &nc16
->rgrc
[1] );
1479 CONV_RECT32TO16( &nc
->rgrc
[2], &nc16
->rgrc
[2] );
1482 STRUCT32_WINDOWPOS32to16( nc
->lppos
, MapSL(nc16
->lppos
));
1483 HeapFree( GetProcessHeap(), 0, nc
->lppos
);
1486 HeapFree( GetProcessHeap(), 0, nc
);
1492 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1493 lParam
= *(LPARAM
*)(cs
+ 1);
1494 STRUCT32_CREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1495 HeapFree( GetProcessHeap(), 0, cs
);
1498 case WM_WINDOWPOSCHANGING
:
1499 case WM_WINDOWPOSCHANGED
:
1501 WINDOWPOS
*wp
= (WINDOWPOS
*)lParam
;
1502 lParam
= *(LPARAM
*)(wp
+ 1);
1503 STRUCT32_WINDOWPOS32to16(wp
, MapSL(lParam
));
1504 HeapFree( GetProcessHeap(), 0, wp
);
1510 LPMSG msg32
= (LPMSG
)lParam
;
1512 WINPROC_UnmapMsg16To32A( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1514 HeapFree( GetProcessHeap(), 0, msg32
);
1519 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1520 result
= MAKELONG( HMENU_16(next
->hmenuNext
), HWND_16(next
->hwndNext
) );
1521 HeapFree( GetProcessHeap(), 0, next
);
1529 /**********************************************************************
1530 * WINPROC_MapMsg16To32W
1532 * Map a message from 16- to 32-bit Unicode.
1533 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1535 INT
WINPROC_MapMsg16To32W( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1536 WPARAM
*pwparam32
, LPARAM
*plparam
)
1541 *pmsg32
=(UINT
)msg16
;
1542 *pwparam32
= (WPARAM
)wParam16
;
1547 case WM_WININICHANGE
:
1548 case WM_DEVMODECHANGE
:
1549 case WM_ASKCBFORMATNAME
:
1550 *plparam
= (LPARAM
)MapSL(*plparam
);
1551 return WINPROC_MapMsg32ATo32W( hwnd
, *pmsg32
, pwparam32
, plparam
);
1552 case WM_GETTEXTLENGTH
:
1553 case CB_GETLBTEXTLEN
:
1555 return 1; /* need to map result */
1559 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1560 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1561 sizeof(*cs
) + sizeof(LPARAM
) );
1563 STRUCT32_CREATESTRUCT16to32A( cs16
, (CREATESTRUCTA
*)cs
);
1564 cs
->lpszName
= map_str_16_to_32W(cs16
->lpszName
);
1565 cs
->lpszClass
= map_str_16_to_32W(cs16
->lpszClass
);
1566 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1567 *plparam
= (LPARAM
)cs
;
1572 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1573 MDICREATESTRUCTW
*cs
=
1574 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1575 sizeof(*cs
) + sizeof(LPARAM
) );
1577 STRUCT32_MDICREATESTRUCT16to32A( cs16
, (MDICREATESTRUCTA
*)cs
);
1578 cs
->szTitle
= map_str_16_to_32W(cs16
->szTitle
);
1579 cs
->szClass
= map_str_16_to_32W(cs16
->szClass
);
1580 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1581 *plparam
= (LPARAM
)cs
;
1587 LPMSG16 msg16
= MapSL(*plparam
);
1588 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1590 if (!msg32
) return -1;
1591 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1592 msg32
->lParam
= msg16
->lParam
;
1593 msg32
->time
= msg16
->time
;
1594 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1595 /* this is right, right? */
1596 if (WINPROC_MapMsg16To32W(hwnd
, msg16
->message
,msg16
->wParam
,
1597 &msg32
->message
,&msg32
->wParam
,
1598 &msg32
->lParam
)<0) {
1599 HeapFree( GetProcessHeap(), 0, msg32
);
1602 *plparam
= (LPARAM
)msg32
;
1609 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1610 *pwparam32
= MAKEWPARAM( wch
, HIWORD(*plparam
) );
1611 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1615 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1616 *pwparam32
= MAKEWPARAM( wch
, LOWORD(*plparam
) );
1617 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1622 case WM_SYSDEADCHAR
:
1624 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1628 default: /* No Unicode translation needed */
1629 return WINPROC_MapMsg16To32A( hwnd
, msg16
, wParam16
, pmsg32
,
1630 pwparam32
, plparam
);
1635 /**********************************************************************
1636 * WINPROC_UnmapMsg16To32W
1638 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1640 LRESULT
WINPROC_UnmapMsg16To32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1647 case WM_GETTEXTLENGTH
:
1648 case CB_GETLBTEXTLEN
:
1650 case WM_ASKCBFORMATNAME
:
1651 return WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
1655 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)lParam
;
1656 lParam
= *(LPARAM
*)(cs
+ 1);
1657 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs
, MapSL(lParam
) );
1658 unmap_str_16_to_32W( cs
->lpszName
);
1659 unmap_str_16_to_32W( cs
->lpszClass
);
1660 HeapFree( GetProcessHeap(), 0, cs
);
1665 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
1666 lParam
= *(LPARAM
*)(cs
+ 1);
1667 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs
, MapSL(lParam
) );
1668 unmap_str_16_to_32W( cs
->szTitle
);
1669 unmap_str_16_to_32W( cs
->szClass
);
1670 HeapFree( GetProcessHeap(), 0, cs
);
1676 LPMSG msg32
= (LPMSG
)lParam
;
1678 WINPROC_UnmapMsg16To32W( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1680 HeapFree( GetProcessHeap(), 0, msg32
);
1684 return WINPROC_UnmapMsg16To32A( hwnd
, msg
, wParam
, lParam
, result
);
1689 static HANDLE16
convert_handle_32_to_16(HANDLE src
, unsigned int flags
)
1692 UINT sz
= GlobalSize(src
);
1695 if (!(dst
= GlobalAlloc16(flags
, sz
)))
1697 ptr32
= GlobalLock(src
);
1698 ptr16
= GlobalLock16(dst
);
1699 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr16
, ptr32
, sz
);
1701 GlobalUnlock16(dst
);
1707 /**********************************************************************
1708 * WINPROC_MapMsg32ATo16
1710 * Map a message from 32-bit Ansi to 16-bit.
1711 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1713 INT
WINPROC_MapMsg32ATo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
1714 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
1717 *pmsg16
= (UINT16
)msg32
;
1718 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1726 *pmsg16
= (UINT16
)msg32
+ (BM_GETCHECK16
- BM_GETCHECK
);
1735 case EM_SCROLLCARET
:
1738 case EM_GETLINECOUNT
:
1750 case EM_LINEFROMCHAR
:
1751 case EM_SETTABSTOPS
:
1752 case EM_SETPASSWORDCHAR
:
1753 case EM_EMPTYUNDOBUFFER
:
1754 case EM_GETFIRSTVISIBLELINE
:
1755 case EM_SETREADONLY
:
1756 case EM_SETWORDBREAKPROC
:
1757 case EM_GETWORDBREAKPROC
:
1758 case EM_GETPASSWORDCHAR
:
1759 *pmsg16
= (UINT16
)msg32
+ (EM_GETSEL16
- EM_GETSEL
);
1764 case LB_DELETESTRING
:
1765 case LB_GETANCHORINDEX
:
1766 case LB_GETCARETINDEX
:
1769 case LB_GETHORIZONTALEXTENT
:
1770 case LB_GETITEMDATA
:
1771 case LB_GETITEMHEIGHT
:
1773 case LB_GETSELCOUNT
:
1775 case LB_GETTOPINDEX
:
1776 case LB_RESETCONTENT
:
1777 case LB_SELITEMRANGE
:
1778 case LB_SELITEMRANGEEX
:
1779 case LB_SETANCHORINDEX
:
1780 case LB_SETCARETINDEX
:
1781 case LB_SETCOLUMNWIDTH
:
1783 case LB_SETHORIZONTALEXTENT
:
1784 case LB_SETITEMDATA
:
1785 case LB_SETITEMHEIGHT
:
1787 case LB_SETTOPINDEX
:
1788 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1790 case CB_DELETESTRING
:
1792 case CB_GETLBTEXTLEN
:
1794 case CB_RESETCONTENT
:
1798 case CB_SHOWDROPDOWN
:
1799 case CB_SETITEMDATA
:
1800 case CB_SETITEMHEIGHT
:
1801 case CB_GETITEMHEIGHT
:
1802 case CB_SETEXTENDEDUI
:
1803 case CB_GETEXTENDEDUI
:
1804 case CB_GETDROPPEDSTATE
:
1805 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1808 *pmsg16
= CB_GETEDITSEL16
;
1813 case LB_FINDSTRINGEXACT
:
1814 case LB_INSERTSTRING
:
1815 case LB_SELECTSTRING
:
1818 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1819 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1824 case CB_FINDSTRINGEXACT
:
1825 case CB_INSERTSTRING
:
1826 case CB_SELECTSTRING
:
1828 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1829 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1832 case LB_GETITEMRECT
:
1834 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1835 if (!rect
) return -1;
1836 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1837 *plparam
= MapLS( rect
);
1839 *pmsg16
= LB_GETITEMRECT16
;
1841 case LB_GETSELITEMS
:
1844 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1845 if (!(items
= HeapAlloc( GetProcessHeap(), 0,
1846 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1847 *((LPARAM
*)items
)++ = *plparam
; /* Store the previous lParam */
1848 *plparam
= MapLS( items
);
1850 *pmsg16
= LB_GETSELITEMS16
;
1852 case LB_SETTABSTOPS
:
1857 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1858 if (!(stops
= HeapAlloc( GetProcessHeap(), 0,
1859 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1860 for (i
= 0; i
< *pwparam16
; i
++) stops
[i
] = *((LPINT
)*plparam
+i
);
1861 *plparam
= MapLS( stops
);
1864 *pmsg16
= LB_SETTABSTOPS16
;
1867 case CB_GETDROPPEDCONTROLRECT
:
1869 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1870 if (!rect
) return -1;
1871 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1872 *plparam
= (LPARAM
)MapLS(rect
);
1874 *pmsg16
= CB_GETDROPPEDCONTROLRECT16
;
1878 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1879 *pmsg16
= LB_GETTEXT16
;
1883 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1884 *pmsg16
= CB_GETLBTEXT16
;
1889 *plparam
= MAKELONG( (INT16
)(INT
)wParam32
, (INT16
)*plparam
);
1890 *pmsg16
= EM_SETSEL16
;
1897 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
1901 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
1903 case WM_CTLCOLORMSGBOX
:
1904 case WM_CTLCOLOREDIT
:
1905 case WM_CTLCOLORLISTBOX
:
1906 case WM_CTLCOLORBTN
:
1907 case WM_CTLCOLORDLG
:
1908 case WM_CTLCOLORSCROLLBAR
:
1909 case WM_CTLCOLORSTATIC
:
1910 *pmsg16
= WM_CTLCOLOR
;
1911 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
1912 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
1914 case WM_COMPAREITEM
:
1916 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)*plparam
;
1917 COMPAREITEMSTRUCT16
*cis
= HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16
));
1918 if (!cis
) return -1;
1919 cis
->CtlType
= (UINT16
)cis32
->CtlType
;
1920 cis
->CtlID
= (UINT16
)cis32
->CtlID
;
1921 cis
->hwndItem
= HWND_16( cis32
->hwndItem
);
1922 cis
->itemID1
= (UINT16
)cis32
->itemID1
;
1923 cis
->itemData1
= cis32
->itemData1
;
1924 cis
->itemID2
= (UINT16
)cis32
->itemID2
;
1925 cis
->itemData2
= cis32
->itemData2
;
1926 *plparam
= MapLS( cis
);
1931 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)*plparam
;
1932 DELETEITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16
) );
1933 if (!dis
) return -1;
1934 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1935 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1936 dis
->itemID
= (UINT16
)dis32
->itemID
;
1937 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
1938 : HWND_16( dis32
->hwndItem
);
1939 dis
->itemData
= dis32
->itemData
;
1940 *plparam
= MapLS( dis
);
1945 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)*plparam
;
1946 DRAWITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16
) );
1947 if (!dis
) return -1;
1948 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1949 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1950 dis
->itemID
= (UINT16
)dis32
->itemID
;
1951 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
1952 dis
->itemState
= (UINT16
)dis32
->itemState
;
1953 dis
->hwndItem
= HWND_16( dis32
->hwndItem
);
1954 dis
->hDC
= HDC_16(dis32
->hDC
);
1955 dis
->itemData
= dis32
->itemData
;
1956 CONV_RECT32TO16( &dis32
->rcItem
, &dis
->rcItem
);
1957 *plparam
= MapLS( dis
);
1960 case WM_MEASUREITEM
:
1962 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)*plparam
;
1963 MEASUREITEMSTRUCT16
*mis
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mis
)+sizeof(LPARAM
));
1964 if (!mis
) return -1;
1965 mis
->CtlType
= (UINT16
)mis32
->CtlType
;
1966 mis
->CtlID
= (UINT16
)mis32
->CtlID
;
1967 mis
->itemID
= (UINT16
)mis32
->itemID
;
1968 mis
->itemWidth
= (UINT16
)mis32
->itemWidth
;
1969 mis
->itemHeight
= (UINT16
)mis32
->itemHeight
;
1970 mis
->itemData
= mis32
->itemData
;
1971 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1972 *plparam
= MapLS( mis
);
1975 case WM_GETMINMAXINFO
:
1977 MINMAXINFO16
*mmi
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi
) + sizeof(LPARAM
) );
1978 if (!mmi
) return -1;
1979 STRUCT32_MINMAXINFO32to16( (MINMAXINFO
*)*plparam
, mmi
);
1980 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1981 *plparam
= MapLS( mmi
);
1985 case WM_ASKCBFORMATNAME
:
1988 *pwparam16
= (WPARAM16
)min( wParam32
, 0xff80 ); /* Must be < 64K */
1989 if (!(str
= HeapAlloc( GetProcessHeap(), 0, *pwparam16
+ sizeof(LPARAM
)))) return -1;
1990 *((LPARAM
*)str
)++ = *plparam
; /* Store the previous lParam */
1991 *plparam
= MapLS( str
);
1996 MDICREATESTRUCT16
*cs
;
1997 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)*plparam
;
1999 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2000 STRUCT32_MDICREATESTRUCT32Ato16( cs32
, cs
);
2001 cs
->szTitle
= MapLS( cs32
->szTitle
);
2002 cs
->szClass
= MapLS( cs32
->szClass
);
2003 *plparam
= MapLS( cs
);
2006 case WM_MDIGETACTIVE
:
2009 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
2010 (HMENU16
)LOWORD(*plparam
) );
2011 *pwparam16
= (*plparam
== 0);
2014 if(HIWORD(wParam32
) & MF_POPUP
)
2017 if (((UINT
)HIWORD(wParam32
) != 0xFFFF) || (*plparam
))
2019 if((hmenu
= GetSubMenu((HMENU16
)*plparam
, *pwparam16
)))
2025 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2027 case WM_MDIACTIVATE
:
2028 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2030 *pwparam16
= ((HWND
)*plparam
== hwnd
);
2031 *plparam
= MAKELPARAM( (HWND16
)LOWORD(*plparam
),
2032 (HWND16
)LOWORD(wParam32
) );
2036 *pwparam16
= HWND_16( (HWND
)wParam32
);
2042 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)*plparam
;
2043 NCCALCSIZE_PARAMS16
*nc
= HeapAlloc( GetProcessHeap(), 0, sizeof(*nc
) + sizeof(LPARAM
));
2046 CONV_RECT32TO16( &nc32
->rgrc
[0], &nc
->rgrc
[0] );
2050 CONV_RECT32TO16( &nc32
->rgrc
[1], &nc
->rgrc
[1] );
2051 CONV_RECT32TO16( &nc32
->rgrc
[2], &nc
->rgrc
[2] );
2052 if (!(wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16
) )))
2054 HeapFree( GetProcessHeap(), 0, nc
);
2057 STRUCT32_WINDOWPOS32to16( nc32
->lppos
, wp
);
2058 nc
->lppos
= MapLS( wp
);
2060 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
2061 *plparam
= MapLS( nc
);
2068 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)*plparam
;
2070 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2071 STRUCT32_CREATESTRUCT32Ato16( cs32
, cs
);
2072 cs
->lpszName
= MapLS( cs32
->lpszName
);
2073 cs
->lpszClass
= MapLS( cs32
->lpszClass
);
2074 *plparam
= MapLS( cs
);
2077 case WM_PARENTNOTIFY
:
2078 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
2079 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
2080 /* else nothing to do */
2083 *plparam
= MapLS( (NMHDR
*)*plparam
); /* NMHDR is already 32-bit */
2086 case WM_WININICHANGE
:
2087 case WM_DEVMODECHANGE
:
2088 *plparam
= MapLS( (LPSTR
)*plparam
);
2090 case WM_WINDOWPOSCHANGING
:
2091 case WM_WINDOWPOSCHANGED
:
2093 WINDOWPOS16
*wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(*wp
) + sizeof(LPARAM
) );
2095 STRUCT32_WINDOWPOS32to16( (WINDOWPOS
*)*plparam
, wp
);
2096 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
2097 *plparam
= MapLS( wp
);
2102 LPMSG msg32
= (LPMSG
) *plparam
;
2103 LPMSG16 msg16
= HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16
) );
2105 if (!msg16
) return -1;
2106 msg16
->hwnd
= HWND_16( msg32
->hwnd
);
2107 msg16
->lParam
= msg32
->lParam
;
2108 msg16
->time
= msg32
->time
;
2109 CONV_POINT32TO16(&msg32
->pt
,&msg16
->pt
);
2110 /* this is right, right? */
2111 if (WINPROC_MapMsg32ATo16(msg32
->hwnd
,msg32
->message
,msg32
->wParam
,
2112 &msg16
->message
,&msg16
->wParam
, &msg16
->lParam
)<0)
2114 HeapFree( GetProcessHeap(), 0, msg16
);
2117 *plparam
= MapLS( msg16
);
2122 case WM_ACTIVATEAPP
:
2123 if (*plparam
) *plparam
= HTASK_16( (HANDLE
)*plparam
);
2127 MDINEXTMENU
*next
= (MDINEXTMENU
*)*plparam
;
2128 *plparam
= next
->hmenuIn
;
2131 case WM_PAINTCLIPBOARD
:
2132 case WM_SIZECLIPBOARD
:
2133 FIXME_(msg
)("message %04x needs translation\n", msg32
);
2135 /* following messages should not be sent to 16-bit apps */
2138 case WM_CAPTURECHANGED
:
2139 case WM_STYLECHANGING
:
2140 case WM_STYLECHANGED
:
2142 case WM_DDE_INITIATE
:
2143 case WM_DDE_TERMINATE
:
2144 case WM_DDE_UNADVISE
:
2145 case WM_DDE_REQUEST
:
2146 *pwparam16
= HWND_16((HWND
)wParam32
);
2155 *pwparam16
= HWND_16((HWND
)wParam32
);
2156 UnpackDDElParam(msg32
, *plparam
, &lo32
, &hi
);
2157 if (lo32
&& !(lo16
= convert_handle_32_to_16(lo32
, GMEM_DDESHARE
)))
2159 *plparam
= MAKELPARAM(lo16
, hi
);
2161 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2168 *pwparam16
= HWND_16((HWND
)wParam32
);
2170 UnpackDDElParam(msg32
, *plparam
, &lo
, &hi
);
2172 if (GlobalGetAtomNameA((ATOM
)hi
, buf
, sizeof(buf
)) > 0) flag
|= 1;
2173 if (GlobalSize(hi
) != 0) flag
|= 2;
2179 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
2184 break; /* atom, nothing to do */
2186 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
2189 hi
= convert_handle_32_to_16(hi
, GMEM_DDESHARE
);
2192 *plparam
= MAKELPARAM(lo
, hi
);
2194 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2195 case WM_DDE_EXECUTE
:
2196 *plparam
= convert_handle_32_to_16(*plparam
, GMEM_DDESHARE
);
2197 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2198 default: /* No translation needed */
2204 /**********************************************************************
2205 * WINPROC_UnmapMsg32ATo16
2207 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2209 void WINPROC_UnmapMsg32ATo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2218 case LB_FINDSTRINGEXACT
:
2219 case LB_INSERTSTRING
:
2220 case LB_SELECTSTRING
:
2224 case CB_FINDSTRINGEXACT
:
2225 case CB_INSERTSTRING
:
2226 case CB_SELECTSTRING
:
2230 case WM_WININICHANGE
:
2231 case WM_DEVMODECHANGE
:
2232 UnMapLS( (SEGPTR
)p16
->lParam
);
2234 case LB_SETTABSTOPS
:
2235 case WM_COMPAREITEM
:
2239 void *ptr
= MapSL( p16
->lParam
);
2240 UnMapLS( p16
->lParam
);
2241 HeapFree( GetProcessHeap(), 0, ptr
);
2244 case CB_GETDROPPEDCONTROLRECT
:
2245 case LB_GETITEMRECT
:
2247 RECT16
*rect
= MapSL(p16
->lParam
);
2248 UnMapLS( p16
->lParam
);
2249 p16
->lParam
= *(LPARAM
*)(rect
+ 1);
2250 CONV_RECT16TO32( rect
, (RECT
*)(p16
->lParam
));
2251 HeapFree( GetProcessHeap(), 0, rect
);
2254 case LB_GETSELITEMS
:
2257 LPINT16 items
= MapSL(p16
->lParam
);
2258 UnMapLS( p16
->lParam
);
2259 p16
->lParam
= *((LPARAM
*)items
- 1);
2260 for (i
= 0; i
< p16
->wParam
; i
++) *((LPINT
)(p16
->lParam
) + i
) = items
[i
];
2261 HeapFree( GetProcessHeap(), 0, (LPARAM
*)items
- 1 );
2267 *((PUINT
)(wParam
)) = LOWORD(p16
->lResult
);
2269 *((PUINT
)(lParam
)) = HIWORD(p16
->lResult
); /* FIXME: substract 1? */
2272 case WM_MEASUREITEM
:
2274 MEASUREITEMSTRUCT16
*mis
= MapSL(p16
->lParam
);
2275 MEASUREITEMSTRUCT
*mis32
= *(MEASUREITEMSTRUCT
**)(mis
+ 1);
2276 mis32
->itemWidth
= mis
->itemWidth
;
2277 mis32
->itemHeight
= mis
->itemHeight
;
2278 UnMapLS( p16
->lParam
);
2279 HeapFree( GetProcessHeap(), 0, mis
);
2282 case WM_GETMINMAXINFO
:
2284 MINMAXINFO16
*mmi
= MapSL(p16
->lParam
);
2285 UnMapLS( p16
->lParam
);
2286 p16
->lParam
= *(LPARAM
*)(mmi
+ 1);
2287 STRUCT32_MINMAXINFO16to32( mmi
, (MINMAXINFO
*)(p16
->lParam
) );
2288 HeapFree( GetProcessHeap(), 0, mmi
);
2292 case WM_ASKCBFORMATNAME
:
2294 LPSTR str
= MapSL(p16
->lParam
);
2295 UnMapLS( p16
->lParam
);
2296 p16
->lParam
= *((LPARAM
*)str
- 1);
2297 lstrcpynA( (LPSTR
)(p16
->lParam
), str
, p16
->wParam
);
2298 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2303 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2304 UnMapLS( cs
->szTitle
);
2305 UnMapLS( cs
->szClass
);
2306 UnMapLS( p16
->lParam
);
2307 HeapFree( GetProcessHeap(), 0, cs
);
2310 case WM_MDIGETACTIVE
:
2311 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(p16
->lResult
);
2312 p16
->lResult
= (LRESULT
)WIN_Handle32( LOWORD(p16
->lResult
) );
2316 NCCALCSIZE_PARAMS
*nc32
;
2317 NCCALCSIZE_PARAMS16
*nc
= MapSL(p16
->lParam
);
2318 UnMapLS( p16
->lParam
);
2319 p16
->lParam
= *(LPARAM
*)(nc
+ 1);
2320 nc32
= (NCCALCSIZE_PARAMS
*)(p16
->lParam
);
2321 CONV_RECT16TO32( &nc
->rgrc
[0], &nc32
->rgrc
[0] );
2324 WINDOWPOS16
*pos
= MapSL(nc
->lppos
);
2325 UnMapLS( nc
->lppos
);
2326 CONV_RECT16TO32( &nc
->rgrc
[1], &nc32
->rgrc
[1] );
2327 CONV_RECT16TO32( &nc
->rgrc
[2], &nc32
->rgrc
[2] );
2328 STRUCT32_WINDOWPOS16to32( pos
, nc32
->lppos
);
2329 HeapFree( GetProcessHeap(), 0, pos
);
2331 HeapFree( GetProcessHeap(), 0, nc
);
2337 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2338 UnMapLS( p16
->lParam
);
2339 UnMapLS( cs
->lpszName
);
2340 UnMapLS( cs
->lpszClass
);
2341 HeapFree( GetProcessHeap(), 0, cs
);
2344 case WM_WINDOWPOSCHANGING
:
2345 case WM_WINDOWPOSCHANGED
:
2347 WINDOWPOS16
*wp
= MapSL(p16
->lParam
);
2348 UnMapLS( p16
->lParam
);
2349 p16
->lParam
= *(LPARAM
*)(wp
+ 1);
2350 STRUCT32_WINDOWPOS16to32( wp
, (WINDOWPOS
*)p16
->lParam
);
2351 HeapFree( GetProcessHeap(), 0, wp
);
2355 UnMapLS(p16
->lParam
);
2360 LPMSG16 msg16
= MapSL(p16
->lParam
);
2362 UnMapLS( p16
->lParam
);
2363 msgp16
.wParam
=msg16
->wParam
;
2364 msgp16
.lParam
=msg16
->lParam
;
2365 WINPROC_UnmapMsg32ATo16(((LPMSG
)lParam
)->hwnd
, ((LPMSG
)lParam
)->message
,
2366 ((LPMSG
)lParam
)->wParam
, ((LPMSG
)lParam
)->lParam
,
2368 HeapFree( GetProcessHeap(), 0, msg16
);
2373 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
2374 next
->hmenuNext
= LOWORD(p16
->lResult
);
2375 next
->hwndNext
= WIN_Handle32( HIWORD(p16
->lResult
) );
2383 /**********************************************************************
2384 * WINPROC_MapMsg32WTo16
2386 * Map a message from 32-bit Unicode to 16-bit.
2387 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2389 INT
WINPROC_MapMsg32WTo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
2390 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
2396 *pmsg16
= LOWORD(msg32
);
2397 *pwparam16
= LOWORD(wParam32
);
2402 case LB_FINDSTRINGEXACT
:
2403 case LB_INSERTSTRING
:
2404 case LB_SELECTSTRING
:
2407 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2408 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2413 case CB_FINDSTRINGEXACT
:
2414 case CB_INSERTSTRING
:
2415 case CB_SELECTSTRING
:
2417 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2418 *pmsg16
= (UINT16
)msg32
+ (CB_ADDSTRING16
- CB_ADDSTRING
);
2425 CREATESTRUCTW
*cs32
= (CREATESTRUCTW
*)*plparam
;
2427 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2428 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs32
, cs
);
2429 cs
->lpszName
= map_str_32W_to_16( cs32
->lpszName
);
2430 cs
->lpszClass
= map_str_32W_to_16( cs32
->lpszClass
);
2431 *plparam
= MapLS(cs
);
2436 MDICREATESTRUCT16
*cs
;
2437 MDICREATESTRUCTW
*cs32
= (MDICREATESTRUCTW
*)*plparam
;
2439 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2440 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs32
, cs
);
2441 cs
->szTitle
= map_str_32W_to_16( cs32
->szTitle
);
2442 cs
->szClass
= map_str_32W_to_16( cs32
->szClass
);
2443 *plparam
= MapLS(cs
);
2447 case WM_WININICHANGE
:
2448 case WM_DEVMODECHANGE
:
2449 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2453 if ( WINPROC_TestLBForStr( hwnd
))
2455 LPSTR str
= HeapAlloc( GetProcessHeap(), 0, 256 ); /* FIXME: fixed sized buffer */
2456 if (!str
) return -1;
2457 *pmsg16
= (msg32
== LB_GETTEXT
)? LB_GETTEXT16
: CB_GETLBTEXT16
;
2458 *plparam
= (LPARAM
)MapLS(str
);
2463 wch
= LOWORD(wParam32
);
2464 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2466 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
2469 wch
= LOWORD(wParam32
);
2470 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2472 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2477 case WM_SYSDEADCHAR
:
2479 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2483 default: /* No Unicode translation needed (?) */
2484 return WINPROC_MapMsg32ATo16( hwnd
, msg32
, wParam32
, pmsg16
,
2485 pwparam16
, plparam
);
2490 /**********************************************************************
2491 * WINPROC_UnmapMsg32WTo16
2493 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2495 void WINPROC_UnmapMsg32WTo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2502 case LB_FINDSTRINGEXACT
:
2503 case LB_INSERTSTRING
:
2504 case LB_SELECTSTRING
:
2509 case CB_FINDSTRINGEXACT
:
2510 case CB_INSERTSTRING
:
2511 case CB_SELECTSTRING
:
2514 case WM_WININICHANGE
:
2515 case WM_DEVMODECHANGE
:
2516 unmap_str_32W_to_16( p16
->lParam
);
2521 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2522 UnMapLS( p16
->lParam
);
2523 unmap_str_32W_to_16( cs
->lpszName
);
2524 unmap_str_32W_to_16( cs
->lpszClass
);
2525 HeapFree( GetProcessHeap(), 0, cs
);
2530 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2531 UnMapLS( p16
->lParam
);
2532 unmap_str_32W_to_16( cs
->szTitle
);
2533 unmap_str_32W_to_16( cs
->szClass
);
2534 HeapFree( GetProcessHeap(), 0, cs
);
2538 case WM_ASKCBFORMATNAME
:
2540 LPSTR str
= MapSL(p16
->lParam
);
2541 UnMapLS( p16
->lParam
);
2542 p16
->lParam
= *((LPARAM
*)str
- 1);
2543 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)p16
->lParam
, 0x7fffffff );
2544 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2549 if ( WINPROC_TestLBForStr( hwnd
))
2551 LPSTR str
= MapSL(p16
->lParam
);
2552 UnMapLS( p16
->lParam
);
2553 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)lParam
, 0x7fffffff );
2554 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
);
2558 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, p16
);
2564 /**********************************************************************
2565 * WINPROC_CallProc32ATo32W
2567 * Call a window procedure, translating args from Ansi to Unicode.
2569 static LRESULT
WINPROC_CallProc32ATo32W( WNDPROC func
, HWND hwnd
,
2570 UINT msg
, WPARAM wParam
,
2576 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2577 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2579 if( (unmap
= WINPROC_MapMsg32ATo32W( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
2580 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2581 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2584 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2585 if (unmap
) result
= WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
2590 /**********************************************************************
2591 * WINPROC_CallProc32WTo32A
2593 * Call a window procedure, translating args from Unicode to Ansi.
2595 static LRESULT
WINPROC_CallProc32WTo32A( WNDPROC func
, HWND hwnd
,
2596 UINT msg
, WPARAM wParam
,
2602 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2603 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2605 if ((unmap
= WINPROC_MapMsg32WTo32A( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
2606 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2607 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2610 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2611 if( unmap
) WINPROC_UnmapMsg32WTo32A( hwnd
, msg
, wParam
, lParam
);
2616 /**********************************************************************
2617 * __wine_call_wndproc_32A (USER.1010)
2619 LRESULT WINAPI
__wine_call_wndproc_32A( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
2625 HWND hwnd32
= WIN_Handle32( hwnd
);
2627 if (WINPROC_MapMsg16To32A( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2629 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
2630 return WINPROC_UnmapMsg16To32A( hwnd32
, msg32
, wParam32
, lParam
, result
);
2634 /**********************************************************************
2635 * __wine_call_wndproc_32W (USER.1011)
2637 LRESULT WINAPI
__wine_call_wndproc_32W( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
2643 HWND hwnd32
= WIN_Handle32( hwnd
);
2645 if (WINPROC_MapMsg16To32W( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2647 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
2648 return WINPROC_UnmapMsg16To32W( hwnd32
, msg32
, wParam32
, lParam
, result
);
2652 /**********************************************************************
2653 * WINPROC_CallProc32ATo16
2655 * Call a 16-bit window procedure, translating the 32-bit args.
2657 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
2658 UINT msg
, WPARAM wParam
,
2664 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2665 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2667 mp16
.lParam
= lParam
;
2668 if (WINPROC_MapMsg32ATo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
, &mp16
.lParam
) == -1)
2670 mp16
.lResult
= WINPROC_CallWndProc16( func
, HWND_16(hwnd
), msg16
,
2671 mp16
.wParam
, mp16
.lParam
);
2672 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2673 return mp16
.lResult
;
2677 /**********************************************************************
2678 * WINPROC_CallProc32WTo16
2680 * Call a 16-bit window procedure, translating the 32-bit args.
2682 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
2683 UINT msg
, WPARAM wParam
,
2689 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2690 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2692 mp16
.lParam
= lParam
;
2693 if (WINPROC_MapMsg32WTo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
,
2694 &mp16
.lParam
) == -1)
2696 mp16
.lResult
= WINPROC_CallWndProc16( func
, HWND_16(hwnd
), msg16
,
2697 mp16
.wParam
, mp16
.lParam
);
2698 WINPROC_UnmapMsg32WTo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2699 return mp16
.lResult
;
2703 /**********************************************************************
2704 * CallWindowProc (USER.122)
2706 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
2707 WPARAM16 wParam
, LPARAM lParam
)
2711 if (!func
) return 0;
2713 if (!(proc
= WINPROC_GetPtr( func
)))
2714 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2717 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_16
);
2718 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2724 if (!proc
->thunk
.t_from32
.proc
) return 0;
2725 return WINPROC_CallWndProc16( proc
->thunk
.t_from32
.proc
,
2726 hwnd
, msg
, wParam
, lParam
);
2728 if (!proc
->thunk
.t_from16
.proc
) return 0;
2729 return __wine_call_wndproc_32A( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
2731 if (!proc
->thunk
.t_from16
.proc
) return 0;
2732 return __wine_call_wndproc_32W( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
2734 WARN_(relay
)("Invalid proc %p\n", proc
);
2740 /**********************************************************************
2741 * CallWindowProcA (USER32.@)
2743 * The CallWindowProc() function invokes the windows procedure _func_,
2744 * with _hwnd_ as the target window, the message specified by _msg_, and
2745 * the message parameters _wParam_ and _lParam_.
2747 * Some kinds of argument conversion may be done, I'm not sure what.
2749 * CallWindowProc() may be used for windows subclassing. Use
2750 * SetWindowLong() to set a new windows procedure for windows of the
2751 * subclass, and handle subclassed messages in the new windows
2752 * procedure. The new windows procedure may then use CallWindowProc()
2753 * with _func_ set to the parent class's windows procedure to dispatch
2754 * the message to the superclass.
2758 * The return value is message dependent.
2764 LRESULT WINAPI
CallWindowProcA(
2765 WNDPROC func
, /* [in] window procedure */
2766 HWND hwnd
, /* [in] target window */
2767 UINT msg
, /* [in] message */
2768 WPARAM wParam
, /* [in] message dependent parameter */
2769 LPARAM lParam
/* [in] message dependent parameter */
2771 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2773 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2776 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32A
);
2777 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2783 if (!proc
->thunk
.t_from32
.proc
) return 0;
2784 return WINPROC_CallProc32ATo16( proc
->thunk
.t_from32
.proc
,
2785 hwnd
, msg
, wParam
, lParam
);
2787 if (!proc
->thunk
.t_from16
.proc
) return 0;
2788 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2789 hwnd
, msg
, wParam
, lParam
);
2791 if (!proc
->thunk
.t_from16
.proc
) return 0;
2792 return WINPROC_CallProc32ATo32W( proc
->thunk
.t_from16
.proc
,
2793 hwnd
, msg
, wParam
, lParam
);
2795 WARN_(relay
)("Invalid proc %p\n", proc
);
2801 /**********************************************************************
2802 * CallWindowProcW (USER32.@)
2804 LRESULT WINAPI
CallWindowProcW( WNDPROC func
, HWND hwnd
, UINT msg
,
2805 WPARAM wParam
, LPARAM lParam
)
2807 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2809 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2812 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32W
);
2813 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2819 if (!proc
->thunk
.t_from32
.proc
) return 0;
2820 return WINPROC_CallProc32WTo16( proc
->thunk
.t_from32
.proc
,
2821 hwnd
, msg
, wParam
, lParam
);
2823 if (!proc
->thunk
.t_from16
.proc
) return 0;
2824 return WINPROC_CallProc32WTo32A( proc
->thunk
.t_from16
.proc
,
2825 hwnd
, msg
, wParam
, lParam
);
2827 if (!proc
->thunk
.t_from16
.proc
) return 0;
2828 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2829 hwnd
, msg
, wParam
, lParam
);
2831 WARN_(relay
)("Invalid proc %p\n", proc
);