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"
32 #include "wine/winbase16.h"
33 #include "wine/winuser16.h"
34 #include "stackframe.h"
39 #include "user_private.h"
43 #include "wine/unicode.h"
44 #include "wine/debug.h"
46 WINE_DECLARE_DEBUG_CHANNEL(msg
);
47 WINE_DECLARE_DEBUG_CHANNEL(relay
);
48 WINE_DEFAULT_DEBUG_CHANNEL(win
);
54 /* Window procedure 16-to-32-bit thunk */
57 BYTE popl_eax
; /* popl %eax (return address) */
58 BYTE pushl_func
; /* pushl $proc */
60 BYTE pushl_eax
; /* pushl %eax */
61 BYTE ljmp
; /* ljmp relay*/
62 DWORD relay_offset
; /* __wine_call_wndproc_32A/W */
64 } WINPROC_THUNK_FROM16
;
66 /* Window procedure 32-to-16-bit thunk */
69 BYTE popl_eax
; /* popl %eax (return address) */
70 BYTE pushl_func
; /* pushl $proc */
72 BYTE pushl_eax
; /* pushl %eax */
73 BYTE jmp
; /* jmp relay (relative jump)*/
74 void (*relay
)(); /* WINPROC_CallProc32ATo16() */
75 } WINPROC_THUNK_FROM32
;
77 /* Simple jmp to call 32-bit procedure directly */
80 BYTE jmp
; /* jmp proc (relative jump) */
91 } WINPROC_THUNK_FROM16
;
96 } WINPROC_THUNK_FROM32
;
103 #endif /* __i386__ */
107 WINPROC_THUNK_FROM16 t_from16
;
108 WINPROC_THUNK_FROM32 t_from32
;
111 typedef struct tagWINDOWPROC
113 WINPROC_THUNK thunk
; /* Thunk */
114 WINPROC_JUMP jmp
; /* Jump */
115 BYTE type
; /* Function type */
118 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
119 UINT msg
, WPARAM wParam
,
121 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
122 UINT msg
, WPARAM wParam
,
125 #define MAX_WINPROCS (0x10000 / sizeof(WINDOWPROC))
127 static WINDOWPROC winproc_array
[MAX_WINPROCS
];
128 static UINT winproc_used
;
130 static CRITICAL_SECTION winproc_cs
;
131 static CRITICAL_SECTION_DEBUG critsect_debug
=
134 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
135 0, 0, { 0, (DWORD
)(__FILE__
": winproc_cs") }
137 static CRITICAL_SECTION winproc_cs
= { &critsect_debug
, -1, 0, 0, 0, 0 };
139 static BOOL
is_valid_winproc( WINDOWPROC
*proc
)
141 /* check alignment */
142 if (((BYTE
*)proc
- (BYTE
*)winproc_array
) % sizeof(*proc
)) return FALSE
;
143 /* check array limits */
144 if (proc
< winproc_array
|| proc
>= winproc_array
+ winproc_used
) return FALSE
;
145 return (proc
->type
!= WIN_PROC_INVALID
);
148 /* find an existing winproc for a given function and type */
149 /* FIXME: probably should do something more clever than a linear search */
150 static inline WINDOWPROC
*find_winproc( WNDPROC func
, WINDOWPROCTYPE type
)
154 if (type
== WIN_PROC_16
)
156 for (i
= 0; i
< winproc_used
; i
++)
158 if (winproc_array
[i
].type
== type
&&
159 winproc_array
[i
].thunk
.t_from32
.proc
== (WNDPROC16
)func
)
160 return &winproc_array
[i
];
165 for (i
= 0; i
< winproc_used
; i
++)
167 if (winproc_array
[i
].type
== type
&&
168 winproc_array
[i
].thunk
.t_from16
.proc
== func
)
169 return &winproc_array
[i
];
175 /* initialize a new winproc */
176 static inline void set_winproc( WINDOWPROC
*proc
, WNDPROC func
, WINDOWPROCTYPE type
)
179 static FARPROC16 relay_32A
, relay_32W
;
184 proc
->thunk
.t_from32
.popl_eax
= 0x58; /* popl %eax */
185 proc
->thunk
.t_from32
.pushl_func
= 0x68; /* pushl $proc */
186 proc
->thunk
.t_from32
.proc
= (WNDPROC16
)func
;
187 proc
->thunk
.t_from32
.pushl_eax
= 0x50; /* pushl %eax */
188 proc
->thunk
.t_from32
.jmp
= 0xe9; /* jmp relay*/
189 proc
->thunk
.t_from32
.relay
= /* relative jump */
190 (void(*)())((DWORD
)WINPROC_CallProc32ATo16
-
191 (DWORD
)(&proc
->thunk
.t_from32
.relay
+ 1));
194 if (!relay_32A
) relay_32A
= GetProcAddress16( GetModuleHandle16("user"),
195 "__wine_call_wndproc_32A" );
196 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
197 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
198 proc
->thunk
.t_from16
.proc
= func
;
199 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
200 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
201 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32A
);
202 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32A
);
203 proc
->jmp
.jmp
= 0xe9;
204 /* Fixup relative jump */
205 proc
->jmp
.proc
= (WNDPROC
)((DWORD
)func
- (DWORD
)(&proc
->jmp
.proc
+ 1));
208 if (!relay_32W
) relay_32W
= GetProcAddress16( GetModuleHandle16("user"),
209 "__wine_call_wndproc_32W" );
210 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
211 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
212 proc
->thunk
.t_from16
.proc
= func
;
213 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
214 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
215 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32W
);
216 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32W
);
217 proc
->jmp
.jmp
= 0xe9;
218 /* Fixup relative jump */
219 proc
->jmp
.proc
= (WNDPROC
)((char *)func
- (char *)(&proc
->jmp
.proc
+ 1));
222 /* Should not happen */
229 proc
->thunk
.t_from32
.proc
= (WNDPROC16
)func
;
233 proc
->thunk
.t_from16
.proc
= func
;
236 /* Should not happen */
239 #endif /* __i386__ */
244 static WORD
get_winproc_selector(void)
246 static LONG winproc_selector
;
249 if (!(ret
= winproc_selector
))
252 WORD sel
= wine_ldt_alloc_entries(1);
253 wine_ldt_set_base( &entry
, winproc_array
);
254 wine_ldt_set_limit( &entry
, sizeof(winproc_array
) - 1 );
255 wine_ldt_set_flags( &entry
, WINE_LDT_FLAGS_CODE
| WINE_LDT_FLAGS_32BIT
);
256 wine_ldt_set_entry( sel
, &entry
);
257 if (!(ret
= InterlockedCompareExchange( &winproc_selector
, sel
, 0 ))) ret
= sel
;
258 else wine_ldt_free_entries( sel
, 1 ); /* somebody beat us to it */
265 /* Some window procedures modify register they shouldn't, or are not
266 * properly declared stdcall; so we need a small assembly wrapper to
268 extern LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
269 WPARAM wParam
, LPARAM lParam
);
270 __ASM_GLOBAL_FUNC( WINPROC_wrapper
,
280 "movl 8(%ebp),%eax\n\t"
282 "leal -12(%ebp),%esp\n\t"
289 static inline LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
290 WPARAM wParam
, LPARAM lParam
)
292 return proc( hwnd
, msg
, wParam
, lParam
);
294 #endif /* __i386__ */
297 static void MINMAXINFO32to16( const MINMAXINFO
*from
, MINMAXINFO16
*to
)
299 to
->ptReserved
.x
= from
->ptReserved
.x
;
300 to
->ptReserved
.y
= from
->ptReserved
.y
;
301 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
302 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
303 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
304 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
305 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
306 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
307 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
308 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
311 static void MINMAXINFO16to32( const MINMAXINFO16
*from
, MINMAXINFO
*to
)
313 to
->ptReserved
.x
= from
->ptReserved
.x
;
314 to
->ptReserved
.y
= from
->ptReserved
.y
;
315 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
316 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
317 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
318 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
319 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
320 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
321 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
322 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
325 static void WINDOWPOS32to16( const WINDOWPOS
* from
, WINDOWPOS16
* to
)
327 to
->hwnd
= HWND_16(from
->hwnd
);
328 to
->hwndInsertAfter
= HWND_16(from
->hwndInsertAfter
);
333 to
->flags
= from
->flags
;
336 static void WINDOWPOS16to32( const WINDOWPOS16
* from
, WINDOWPOS
* to
)
338 to
->hwnd
= WIN_Handle32(from
->hwnd
);
339 to
->hwndInsertAfter
= (from
->hwndInsertAfter
== (HWND16
)-1) ?
340 HWND_TOPMOST
: WIN_Handle32(from
->hwndInsertAfter
);
345 to
->flags
= from
->flags
;
348 /* The strings are not copied */
349 static void CREATESTRUCT32Ato16( const CREATESTRUCTA
* from
, CREATESTRUCT16
* to
)
351 to
->lpCreateParams
= (SEGPTR
)from
->lpCreateParams
;
352 to
->hInstance
= HINSTANCE_16(from
->hInstance
);
353 to
->hMenu
= HMENU_16(from
->hMenu
);
354 to
->hwndParent
= HWND_16(from
->hwndParent
);
359 to
->style
= from
->style
;
360 to
->dwExStyle
= from
->dwExStyle
;
363 static void CREATESTRUCT16to32A( const CREATESTRUCT16
* from
, CREATESTRUCTA
*to
)
366 to
->lpCreateParams
= (LPVOID
)from
->lpCreateParams
;
367 to
->hInstance
= HINSTANCE_32(from
->hInstance
);
368 to
->hMenu
= HMENU_32(from
->hMenu
);
369 to
->hwndParent
= WIN_Handle32(from
->hwndParent
);
374 to
->style
= from
->style
;
375 to
->dwExStyle
= from
->dwExStyle
;
378 /* The strings are not copied */
379 static void MDICREATESTRUCT32Ato16( const MDICREATESTRUCTA
* from
, MDICREATESTRUCT16
* to
)
381 to
->hOwner
= HINSTANCE_16(from
->hOwner
);
386 to
->style
= from
->style
;
387 to
->lParam
= from
->lParam
;
390 static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16
* from
, MDICREATESTRUCTA
*to
)
392 to
->hOwner
= HINSTANCE_32(from
->hOwner
);
397 to
->style
= from
->style
;
398 to
->lParam
= from
->lParam
;
401 /**********************************************************************
402 * WINPROC_CallWndProc32
404 * Call a 32-bit WndProc.
406 static LRESULT
WINPROC_CallWndProc( WNDPROC proc
, HWND hwnd
, UINT msg
,
407 WPARAM wParam
, LPARAM lParam
)
412 hwnd
= WIN_GetFullHandle( hwnd
);
414 DPRINTF( "%04lx:Call window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
415 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
416 /* To avoid any deadlocks, all the locks on the windows structures
417 must be suspended before the control is passed to the application */
418 iWndsLocks
= WIN_SuspendWndsLock();
419 retvalue
= WINPROC_wrapper( proc
, hwnd
, msg
, wParam
, lParam
);
420 WIN_RestoreWndsLock(iWndsLocks
);
423 DPRINTF( "%04lx:Ret window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
424 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
, retvalue
);
428 /***********************************************************************
429 * WINPROC_CallWndProc16
431 * Call a 16-bit window procedure
433 static LRESULT WINAPI
WINPROC_CallWndProc16( WNDPROC16 proc
, HWND16 hwnd
,
434 UINT16 msg
, WPARAM16 wParam
,
441 TEB
*teb
= NtCurrentTeb();
444 /* Window procedures want ax = hInstance, ds = es = ss */
446 memset(&context
, 0, sizeof(context
));
447 context
.SegDs
= context
.SegEs
= SELECTOROF(teb
->cur_stack
);
448 context
.SegFs
= wine_get_fs();
449 context
.SegGs
= wine_get_gs();
450 if (!(context
.Eax
= GetWindowWord( HWND_32(hwnd
), GWLP_HINSTANCE
))) context
.Eax
= context
.SegDs
;
451 context
.SegCs
= SELECTOROF(proc
);
452 context
.Eip
= OFFSETOF(proc
);
453 context
.Ebp
= OFFSETOF(teb
->cur_stack
)
454 + (WORD
)&((STACK16FRAME
*)0)->bp
;
458 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
459 work if structures passed in lParam are placed in the stack/data
460 segment. Programmers easily make the mistake of converting lParam
461 to a near rather than a far pointer, since Windows apparently
462 allows this. We copy the structures to the 16 bit stack; this is
463 ugly but makes these programs work. */
468 offset
= sizeof(CREATESTRUCT16
); break;
470 offset
= sizeof(DRAWITEMSTRUCT16
); break;
472 offset
= sizeof(COMPAREITEMSTRUCT16
); break;
476 void *s
= MapSL(lParam
);
477 lParam
= stack16_push( offset
);
478 memcpy( MapSL(lParam
), s
, offset
);
482 iWndsLocks
= WIN_SuspendWndsLock();
487 args
[1] = HIWORD(lParam
);
488 args
[0] = LOWORD(lParam
);
489 WOWCallback16Ex( 0, WCB16_REGS
, sizeof(args
), args
, (DWORD
*)&context
);
490 ret
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
492 if (offset
) stack16_pop( offset
);
494 WIN_RestoreWndsLock(iWndsLocks
);
500 /**********************************************************************
503 * Return a pointer to the win proc.
505 static WINDOWPROC
*WINPROC_GetPtr( WNDPROC handle
)
510 /* ptr cannot be < 64K */
511 if (!HIWORD(handle
)) return NULL
;
513 /* Check for a linear pointer */
515 ptr
= (BYTE
*)handle
;
516 /* First check if it is the jmp address */
517 proc
= (WINDOWPROC
*)(ptr
- FIELD_OFFSET(WINDOWPROC
,jmp
));
518 if (is_valid_winproc(proc
)) return proc
;
520 /* Now it must be the thunk address */
521 proc
= (WINDOWPROC
*)(ptr
- FIELD_OFFSET(WINDOWPROC
,thunk
));
522 if (is_valid_winproc(proc
)) return proc
;
524 /* Check for a segmented pointer */
526 if (HIWORD(handle
) == get_winproc_selector())
528 ptr
= (BYTE
*)winproc_array
+ LOWORD(handle
);
529 /* It must be the thunk address */
530 proc
= (WINDOWPROC
*)(ptr
- FIELD_OFFSET(WINDOWPROC
,thunk
));
531 if (is_valid_winproc(proc
)) return proc
;
537 /**********************************************************************
540 * Get a window procedure pointer that can be passed to the Windows program.
542 WNDPROC16
WINPROC_GetProc( WNDPROC proc
, WINDOWPROCTYPE type
)
544 WINDOWPROC
*ptr
= (WINDOWPROC
*)proc
;
546 if (!proc
) return NULL
;
547 if (type
== WIN_PROC_16
) /* We want a 16:16 address */
549 if (ptr
->type
== WIN_PROC_16
)
550 return ptr
->thunk
.t_from32
.proc
;
552 return (WNDPROC16
)MAKESEGPTR( get_winproc_selector(),
553 (char *)&ptr
->thunk
- (char *)winproc_array
);
555 else /* We want a 32-bit address */
557 if (ptr
->type
== WIN_PROC_16
)
558 return (WNDPROC16
)&ptr
->thunk
;
559 else if (type
!= ptr
->type
)
560 /* Have to return the jmp address if types don't match */
561 return (WNDPROC16
)&ptr
->jmp
;
563 /* Some Win16 programs want to get back the proc they set */
564 return (WNDPROC16
)ptr
->thunk
.t_from16
.proc
;
569 /**********************************************************************
572 * Allocate a window procedure for a window or class.
574 * Note that allocated winprocs are never freed; the idea is that even if an app creates a
575 * lot of windows, it will usually only have a limited number of window procedures, so the
576 * array won't grow too large, and this way we avoid the need to track allocations per window.
578 WNDPROC
WINPROC_AllocProc( WNDPROC func
, WINDOWPROCTYPE type
)
582 if (!func
) return NULL
;
584 EnterCriticalSection( &winproc_cs
);
586 /* check if the function is already a win proc */
587 if (!(proc
= WINPROC_GetPtr( func
)))
589 /* then check if we already have a winproc for that function */
590 if (!(proc
= find_winproc( func
, type
)))
592 if (winproc_used
>= MAX_WINPROCS
)
593 FIXME( "too many winprocs, cannot allocate one for %p/%d\n", func
, type
);
596 proc
= &winproc_array
[winproc_used
++];
597 set_winproc( proc
, func
, type
);
598 TRACE( "allocated %p for %p/%d (%d/%d used)\n",
599 proc
, func
, type
, winproc_used
, MAX_WINPROCS
);
602 else TRACE( "reusing %p for %p/%d\n", proc
, func
, type
);
605 LeaveCriticalSection( &winproc_cs
);
606 return (WNDPROC
)proc
;
610 /**********************************************************************
611 * WINPROC_GetProcType
613 * Return the window procedure type.
615 WINDOWPROCTYPE
WINPROC_GetProcType( WNDPROC proc
)
617 if (!proc
) return WIN_PROC_INVALID
;
618 return ((WINDOWPROC
*)proc
)->type
;
620 /**********************************************************************
621 * WINPROC_TestCBForStr
623 * Return TRUE if the lparam is a string
625 inline static BOOL
WINPROC_TestCBForStr( HWND hwnd
)
627 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
628 return (!(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) || (style
& CBS_HASSTRINGS
));
630 /**********************************************************************
631 * WINPROC_TestLBForStr
633 * Return TRUE if the lparam is a string
635 inline static BOOL
WINPROC_TestLBForStr( HWND hwnd
)
637 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
638 return (!(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) || (style
& LBS_HASSTRINGS
));
641 /**********************************************************************
642 * WINPROC_MapMsg32ATo32W
644 * Map a message from Ansi to Unicode.
645 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
648 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
649 * the first four bytes are the handle of the icon
650 * when the WM_SETTEXT message has been used to set the icon
652 INT
WINPROC_MapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
657 case WM_ASKCBFORMATNAME
:
659 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
660 *pwparam
* sizeof(WCHAR
) + sizeof(LPARAM
) );
662 *ptr
++ = *plparam
; /* Store previous lParam */
663 *plparam
= (LPARAM
)ptr
;
666 /* lparam is string (0-terminated) */
668 case WM_WININICHANGE
:
669 case WM_DEVMODECHANGE
:
675 DWORD len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)*plparam
, -1, NULL
, 0);
676 WCHAR
*buf
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
677 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)*plparam
, -1, buf
, len
);
678 *plparam
= (LPARAM
)buf
;
679 return (*plparam
? 1 : -1);
681 case WM_GETTEXTLENGTH
:
682 case CB_GETLBTEXTLEN
:
684 return 1; /* need to map result */
688 UNICODE_STRING usBuffer
;
690 { CREATESTRUCTW cs
; /* new structure */
691 LPCWSTR lpszName
; /* allocated Name */
692 LPCWSTR lpszClass
; /* allocated Class */
695 struct s
*xs
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct s
));
697 xs
->cs
= *(CREATESTRUCTW
*)*plparam
;
698 if (HIWORD(xs
->cs
.lpszName
))
700 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)xs
->cs
.lpszName
);
701 xs
->lpszName
= xs
->cs
.lpszName
= usBuffer
.Buffer
;
703 if (HIWORD(xs
->cs
.lpszClass
))
705 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)xs
->cs
.lpszClass
);
706 xs
->lpszClass
= xs
->cs
.lpszClass
= usBuffer
.Buffer
;
709 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
711 MDICREATESTRUCTW
*mdi_cs
= (MDICREATESTRUCTW
*)HeapAlloc(GetProcessHeap(), 0,
713 *mdi_cs
= *(MDICREATESTRUCTW
*)xs
->cs
.lpCreateParams
;
714 if (HIWORD(mdi_cs
->szTitle
))
716 RtlCreateUnicodeStringFromAsciiz(&usBuffer
, (LPCSTR
)mdi_cs
->szTitle
);
717 mdi_cs
->szTitle
= usBuffer
.Buffer
;
719 if (HIWORD(mdi_cs
->szClass
))
721 RtlCreateUnicodeStringFromAsciiz(&usBuffer
, (LPCSTR
)mdi_cs
->szClass
);
722 mdi_cs
->szClass
= usBuffer
.Buffer
;
724 xs
->cs
.lpCreateParams
= mdi_cs
;
727 *plparam
= (LPARAM
)xs
;
732 MDICREATESTRUCTW
*cs
=
733 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
735 *cs
= *(MDICREATESTRUCTW
*)*plparam
;
736 if (HIWORD(cs
->szClass
))
738 UNICODE_STRING usBuffer
;
739 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)cs
->szClass
);
740 cs
->szClass
= usBuffer
.Buffer
;
742 if (HIWORD(cs
->szTitle
))
744 UNICODE_STRING usBuffer
;
745 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)cs
->szTitle
);
746 cs
->szTitle
= usBuffer
.Buffer
;
748 *plparam
= (LPARAM
)cs
;
754 case LB_INSERTSTRING
:
756 case LB_FINDSTRINGEXACT
:
757 case LB_SELECTSTRING
:
758 if(!*plparam
) return 0;
759 if ( WINPROC_TestLBForStr( hwnd
))
761 UNICODE_STRING usBuffer
;
762 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)*plparam
);
763 *plparam
= (LPARAM
)usBuffer
.Buffer
;
765 return (*plparam
? 1 : -1);
767 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
768 { if ( WINPROC_TestLBForStr( hwnd
))
769 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
771 *ptr
++ = *plparam
; /* Store previous lParam */
772 *plparam
= (LPARAM
)ptr
;
779 case CB_INSERTSTRING
:
780 case CB_FINDSTRINGEXACT
:
782 case CB_SELECTSTRING
:
783 if(!*plparam
) return 0;
784 if ( WINPROC_TestCBForStr( hwnd
))
786 UNICODE_STRING usBuffer
;
787 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)*plparam
);
788 *plparam
= (LPARAM
)usBuffer
.Buffer
;
790 return (*plparam
? 1 : -1);
792 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
793 { if ( WINPROC_TestCBForStr( hwnd
))
794 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
796 *ptr
++ = *plparam
; /* Store previous lParam */
797 *plparam
= (LPARAM
)ptr
;
804 { WORD len
= (WORD
)*plparam
;
805 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(WCHAR
) );
807 *ptr
++ = *plparam
; /* Store previous lParam */
808 *((WORD
*) ptr
) = len
; /* Store the length */
809 *plparam
= (LPARAM
)ptr
;
819 case EM_SETPASSWORDCHAR
:
821 BYTE ch
= LOWORD(*pwparam
);
823 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wch
, 1);
824 *pwparam
= MAKEWPARAM( wch
, HIWORD(*pwparam
) );
832 ch
[0] = (*pwparam
>> 8);
833 ch
[1] = *pwparam
& 0xff;
835 MultiByteToWideChar(CP_ACP
, 0, ch
, 2, &wch
, 1);
837 MultiByteToWideChar(CP_ACP
, 0, &ch
[1], 1, &wch
, 1);
838 *pwparam
= MAKEWPARAM( wch
, HIWORD(*pwparam
) );
842 case WM_PAINTCLIPBOARD
:
843 case WM_SIZECLIPBOARD
:
844 FIXME_(msg
)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg
, hwnd
), msg
);
846 default: /* No translation needed */
852 /**********************************************************************
853 * WINPROC_UnmapMsg32ATo32W
855 * Unmap a message that was mapped from Ansi to Unicode.
857 LRESULT
WINPROC_UnmapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
863 case WM_ASKCBFORMATNAME
:
865 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
866 if (!wParam
) result
= 0;
867 else if (!(result
= WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
868 (LPSTR
)*ptr
, wParam
, NULL
, NULL
)))
870 ((LPSTR
)*ptr
)[wParam
-1] = 0;
873 else result
--; /* do not count terminating null */
874 HeapFree( GetProcessHeap(), 0, ptr
);
877 case WM_GETTEXTLENGTH
:
878 case CB_GETLBTEXTLEN
:
880 /* there may be one DBCS char for each Unicode char */
886 { CREATESTRUCTW cs
; /* new structure */
887 LPWSTR lpszName
; /* allocated Name */
888 LPWSTR lpszClass
; /* allocated Class */
890 struct s
*xs
= (struct s
*)lParam
;
891 HeapFree( GetProcessHeap(), 0, xs
->lpszName
);
892 HeapFree( GetProcessHeap(), 0, xs
->lpszClass
);
894 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
896 MDICREATESTRUCTW
*mdi_cs
= (MDICREATESTRUCTW
*)xs
->cs
.lpCreateParams
;
897 if (HIWORD(mdi_cs
->szTitle
))
898 HeapFree(GetProcessHeap(), 0, (LPVOID
)mdi_cs
->szTitle
);
899 if (HIWORD(mdi_cs
->szClass
))
900 HeapFree(GetProcessHeap(), 0, (LPVOID
)mdi_cs
->szClass
);
901 HeapFree(GetProcessHeap(), 0, mdi_cs
);
903 HeapFree( GetProcessHeap(), 0, xs
);
909 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
910 if (HIWORD(cs
->szTitle
))
911 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
912 if (HIWORD(cs
->szClass
))
913 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
914 HeapFree( GetProcessHeap(), 0, cs
);
919 case WM_WININICHANGE
:
920 case WM_DEVMODECHANGE
:
925 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
930 case LB_INSERTSTRING
:
932 case LB_FINDSTRINGEXACT
:
933 case LB_SELECTSTRING
:
934 if ( WINPROC_TestLBForStr( hwnd
))
935 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
939 if ( WINPROC_TestLBForStr( hwnd
))
941 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
942 result
= WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
943 (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
) - 1;
944 HeapFree( GetProcessHeap(), 0, ptr
);
950 case CB_INSERTSTRING
:
952 case CB_FINDSTRINGEXACT
:
953 case CB_SELECTSTRING
:
954 if ( WINPROC_TestCBForStr( hwnd
))
955 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
959 if ( WINPROC_TestCBForStr( hwnd
))
961 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
962 result
= WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
963 (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
) - 1;
964 HeapFree( GetProcessHeap(), 0, ptr
);
971 LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lParam */
972 WORD len
= *(WORD
*) lParam
;
973 result
= WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, result
,
974 (LPSTR
)*ptr
, len
, NULL
, NULL
);
975 if (result
< len
) ((LPSTR
)*ptr
)[result
] = 0;
976 HeapFree( GetProcessHeap(), 0, ptr
);
984 /**********************************************************************
985 * WINPROC_MapMsg32WTo32A
987 * Map a message from Unicode to Ansi.
988 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
990 static INT
WINPROC_MapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
995 case WM_ASKCBFORMATNAME
:
997 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
998 *pwparam
+ sizeof(LPARAM
) );
1000 *ptr
++ = *plparam
; /* Store previous lParam */
1001 *plparam
= (LPARAM
)ptr
;
1006 case WM_WININICHANGE
:
1007 case WM_DEVMODECHANGE
:
1014 LPCWSTR str
= (LPCWSTR
)*plparam
;
1015 int len
= WideCharToMultiByte(CP_ACP
, 0, str
, -1, NULL
, 0, 0, 0);
1016 *plparam
= (LPARAM
)HeapAlloc(GetProcessHeap(), 0, len
);
1017 if (!*plparam
) return -1;
1018 WideCharToMultiByte(CP_ACP
, 0, str
, -1, (LPSTR
)*plparam
, len
, 0, 0);
1025 MDICREATESTRUCTA
*cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
1027 *cs
= *(MDICREATESTRUCTA
*)*plparam
;
1028 if (HIWORD(cs
->szTitle
))
1030 int len
= WideCharToMultiByte(CP_ACP
, 0, (LPCWSTR
)cs
->szTitle
, -1, NULL
, 0, 0, 0);
1031 LPSTR buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1032 if (buf
) WideCharToMultiByte(CP_ACP
, 0, (LPCWSTR
)cs
->szTitle
, -1, buf
, len
, 0, 0);
1035 if (HIWORD(cs
->szClass
))
1037 int len
= WideCharToMultiByte(CP_ACP
, 0, (LPCWSTR
)cs
->szClass
, -1, NULL
, 0, 0, 0);
1038 LPSTR buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1039 if (buf
) WideCharToMultiByte(CP_ACP
, 0, (LPCWSTR
)cs
->szClass
, -1, buf
, len
, 0, 0);
1042 *plparam
= (LPARAM
)cs
;
1048 case LB_INSERTSTRING
:
1050 case LB_FINDSTRINGEXACT
:
1051 case LB_SELECTSTRING
:
1052 if(!*plparam
) return 0;
1053 if ( WINPROC_TestLBForStr( hwnd
))
1055 int len
= WideCharToMultiByte(CP_ACP
, 0, (LPCWSTR
)*plparam
, -1, NULL
, 0, 0, 0);
1056 LPSTR buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1057 if (buf
) WideCharToMultiByte(CP_ACP
, 0, (LPCWSTR
)*plparam
, -1, buf
, len
, 0, 0);
1058 *plparam
= (LPARAM
)buf
;
1060 return (*plparam
? 1 : -1);
1062 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
1063 { if ( WINPROC_TestLBForStr( hwnd
))
1064 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
1065 if (!ptr
) return -1;
1066 *ptr
++ = *plparam
; /* Store previous lParam */
1067 *plparam
= (LPARAM
)ptr
;
1074 case CB_INSERTSTRING
:
1076 case CB_FINDSTRINGEXACT
:
1077 case CB_SELECTSTRING
:
1078 if(!*plparam
) return 0;
1079 if ( WINPROC_TestCBForStr( hwnd
))
1081 int len
= WideCharToMultiByte(CP_ACP
, 0, (LPCWSTR
)*plparam
, -1, NULL
, 0, 0, 0);
1082 LPSTR buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1083 if (buf
) WideCharToMultiByte(CP_ACP
, 0, (LPCWSTR
)*plparam
, -1, buf
, len
, 0, 0);
1084 *plparam
= (LPARAM
)buf
;
1086 return (*plparam
? 1 : -1);
1088 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
1089 { if ( WINPROC_TestCBForStr( hwnd
))
1090 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
1091 if (!ptr
) return -1;
1092 *ptr
++ = *plparam
; /* Store previous lParam */
1093 *plparam
= (LPARAM
)ptr
;
1098 /* Multiline edit */
1100 { WORD len
= (WORD
)*plparam
;
1101 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(CHAR
) );
1102 if (!ptr
) return -1;
1103 *ptr
++ = *plparam
; /* Store previous lParam */
1104 *((WORD
*) ptr
) = len
; /* Store the length */
1105 *plparam
= (LPARAM
)ptr
;
1114 case WM_SYSDEADCHAR
:
1115 case EM_SETPASSWORDCHAR
:
1117 WCHAR wch
= LOWORD(*pwparam
);
1119 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
1120 *pwparam
= MAKEWPARAM( ch
, HIWORD(*pwparam
) );
1126 WCHAR wch
= LOWORD(*pwparam
);
1129 if (WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, ch
, 2, NULL
, NULL
) == 2)
1130 *pwparam
= MAKEWPARAM( (ch
[0] << 8) | ch
[1], HIWORD(*pwparam
) );
1132 *pwparam
= MAKEWPARAM( ch
[0], HIWORD(*pwparam
) );
1136 case WM_PAINTCLIPBOARD
:
1137 case WM_SIZECLIPBOARD
:
1138 FIXME_(msg
)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg
, hwnd
),msg
);
1140 default: /* No translation needed */
1146 /**********************************************************************
1147 * WINPROC_UnmapMsg32WTo32A
1149 * Unmap a message that was mapped from Unicode to Ansi.
1151 static LRESULT
WINPROC_UnmapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, LRESULT result
)
1156 case WM_ASKCBFORMATNAME
:
1158 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1159 if (!wParam
) result
= 0;
1160 else if (!(result
= MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1,
1161 (LPWSTR
)*ptr
, wParam
)))
1163 ((LPWSTR
)*ptr
)[wParam
-1] = 0;
1164 result
= wParam
- 1;
1166 else result
--; /* do not count terminating null */
1167 HeapFree( GetProcessHeap(), 0, ptr
);
1172 case WM_WININICHANGE
:
1173 case WM_DEVMODECHANGE
:
1178 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1183 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1184 if (HIWORD(cs
->szTitle
))
1185 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
1186 if (HIWORD(cs
->szClass
))
1187 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
1188 HeapFree( GetProcessHeap(), 0, cs
);
1194 case LB_INSERTSTRING
:
1196 case LB_FINDSTRINGEXACT
:
1197 case LB_SELECTSTRING
:
1198 if ( WINPROC_TestLBForStr( hwnd
))
1199 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1203 if ( WINPROC_TestLBForStr( hwnd
))
1205 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1206 result
= MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff ) - 1;
1207 HeapFree( GetProcessHeap(), 0, ptr
);
1213 case CB_INSERTSTRING
:
1215 case CB_FINDSTRINGEXACT
:
1216 case CB_SELECTSTRING
:
1217 if ( WINPROC_TestCBForStr( hwnd
))
1218 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1222 if ( WINPROC_TestCBForStr( hwnd
))
1224 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1225 result
= MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff ) - 1;
1226 HeapFree( GetProcessHeap(), 0, ptr
);
1230 /* Multiline edit */
1233 LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lparam */
1234 WORD len
= *(WORD
*)ptr
;
1237 result
= MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, result
, (LPWSTR
)*ptr
, len
);
1238 if (result
< len
) ((LPWSTR
)*ptr
)[result
] = 0;
1240 HeapFree( GetProcessHeap(), 0, ptr
);
1247 static UINT
convert_handle_16_to_32(HANDLE16 src
, unsigned int flags
)
1250 UINT sz
= GlobalSize16(src
);
1253 if (!(dst
= GlobalAlloc(flags
, sz
)))
1255 ptr16
= GlobalLock16(src
);
1256 ptr32
= GlobalLock(dst
);
1257 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr32
, ptr16
, sz
);
1258 GlobalUnlock16(src
);
1264 /**********************************************************************
1265 * WINPROC_MapMsg16To32A
1267 * Map a message from 16- to 32-bit Ansi.
1268 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1270 INT
WINPROC_MapMsg16To32A( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1271 WPARAM
*pwparam32
, LPARAM
*plparam
)
1273 *pmsg32
= (UINT
)msg16
;
1274 *pwparam32
= (WPARAM
)wParam16
;
1281 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1282 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1286 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1287 *plparam
= (LPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1290 if ( HIWORD(*plparam
) > CTLCOLOR_STATIC
) return -1;
1291 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
1292 *pwparam32
= (WPARAM
)HDC_32(wParam16
);
1293 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1295 case WM_COMPAREITEM
:
1297 COMPAREITEMSTRUCT16
* cis16
= MapSL(*plparam
);
1298 COMPAREITEMSTRUCT
*cis
= (COMPAREITEMSTRUCT
*)
1299 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis
));
1300 if (!cis
) return -1;
1301 cis
->CtlType
= cis16
->CtlType
;
1302 cis
->CtlID
= cis16
->CtlID
;
1303 cis
->hwndItem
= WIN_Handle32( cis16
->hwndItem
);
1304 cis
->itemID1
= cis16
->itemID1
;
1305 cis
->itemData1
= cis16
->itemData1
;
1306 cis
->itemID2
= cis16
->itemID2
;
1307 cis
->itemData2
= cis16
->itemData2
;
1308 cis
->dwLocaleId
= 0; /* FIXME */
1309 *plparam
= (LPARAM
)cis
;
1314 DELETEITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1315 DELETEITEMSTRUCT
*dis
= (DELETEITEMSTRUCT
*)
1316 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis
));
1317 if (!dis
) return -1;
1318 dis
->CtlType
= dis16
->CtlType
;
1319 dis
->CtlID
= dis16
->CtlID
;
1320 dis
->hwndItem
= WIN_Handle32( dis16
->hwndItem
);
1321 dis
->itemData
= dis16
->itemData
;
1322 *plparam
= (LPARAM
)dis
;
1325 case WM_MEASUREITEM
:
1327 MEASUREITEMSTRUCT16
* mis16
= MapSL(*plparam
);
1328 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)
1329 HeapAlloc(GetProcessHeap(), 0,
1330 sizeof(*mis
) + sizeof(LPARAM
));
1331 if (!mis
) return -1;
1332 mis
->CtlType
= mis16
->CtlType
;
1333 mis
->CtlID
= mis16
->CtlID
;
1334 mis
->itemID
= mis16
->itemID
;
1335 mis
->itemWidth
= mis16
->itemWidth
;
1336 mis
->itemHeight
= mis16
->itemHeight
;
1337 mis
->itemData
= mis16
->itemData
;
1338 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1339 *plparam
= (LPARAM
)mis
;
1344 DRAWITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1345 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)HeapAlloc(GetProcessHeap(), 0,
1347 if (!dis
) return -1;
1348 dis
->CtlType
= dis16
->CtlType
;
1349 dis
->CtlID
= dis16
->CtlID
;
1350 dis
->itemID
= dis16
->itemID
;
1351 dis
->itemAction
= dis16
->itemAction
;
1352 dis
->itemState
= dis16
->itemState
;
1353 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND
)HMENU_32(dis16
->hwndItem
)
1354 : WIN_Handle32( dis16
->hwndItem
);
1355 dis
->hDC
= HDC_32(dis16
->hDC
);
1356 dis
->itemData
= dis16
->itemData
;
1357 dis
->rcItem
.left
= dis16
->rcItem
.left
;
1358 dis
->rcItem
.top
= dis16
->rcItem
.top
;
1359 dis
->rcItem
.right
= dis16
->rcItem
.right
;
1360 dis
->rcItem
.bottom
= dis16
->rcItem
.bottom
;
1361 *plparam
= (LPARAM
)dis
;
1364 case WM_GETMINMAXINFO
:
1366 MINMAXINFO
*mmi
= (MINMAXINFO
*)HeapAlloc( GetProcessHeap(), 0,
1367 sizeof(*mmi
) + sizeof(LPARAM
));
1368 if (!mmi
) return -1;
1369 MINMAXINFO16to32( MapSL(*plparam
), mmi
);
1370 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1371 *plparam
= (LPARAM
)mmi
;
1376 case WM_WININICHANGE
:
1377 case WM_DEVMODECHANGE
:
1378 case WM_ASKCBFORMATNAME
:
1379 *plparam
= (LPARAM
)MapSL(*plparam
);
1383 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1384 MDICREATESTRUCTA
*cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) + sizeof(LPARAM
) );
1386 MDICREATESTRUCT16to32A( cs16
, cs
);
1387 cs
->szTitle
= MapSL(cs16
->szTitle
);
1388 cs
->szClass
= MapSL(cs16
->szClass
);
1389 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1390 *plparam
= (LPARAM
)cs
;
1393 case WM_MDIGETACTIVE
:
1394 *plparam
= (LPARAM
)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL
) );
1395 *(BOOL
*)(*plparam
) = 0;
1398 if(wParam16
) *pmsg32
=WM_MDIREFRESHMENU
;
1399 *pwparam32
= (WPARAM
)HMENU_32(LOWORD(*plparam
));
1400 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1403 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1404 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1407 if((LOWORD(*plparam
) & MF_POPUP
) && (LOWORD(*plparam
) != 0xFFFF))
1409 HMENU hmenu
=HMENU_32(HIWORD(*plparam
));
1410 UINT Pos
=MENU_FindSubMenu( &hmenu
, HMENU_32(wParam16
));
1411 if(Pos
==0xFFFF) Pos
=0; /* NO_SELECTED_ITEM */
1412 *pwparam32
= MAKEWPARAM( Pos
, LOWORD(*plparam
) );
1414 else *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1415 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1417 case WM_MDIACTIVATE
:
1420 *pwparam32
= (WPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1421 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1423 else /* message sent to MDI client */
1424 *pwparam32
= wParam16
;
1428 NCCALCSIZE_PARAMS16
*nc16
;
1429 NCCALCSIZE_PARAMS
*nc
;
1431 nc
= (NCCALCSIZE_PARAMS
*)HeapAlloc( GetProcessHeap(), 0,
1432 sizeof(*nc
) + sizeof(LPARAM
) );
1434 nc16
= MapSL(*plparam
);
1435 nc
->rgrc
[0].left
= nc16
->rgrc
[0].left
;
1436 nc
->rgrc
[0].top
= nc16
->rgrc
[0].top
;
1437 nc
->rgrc
[0].right
= nc16
->rgrc
[0].right
;
1438 nc
->rgrc
[0].bottom
= nc16
->rgrc
[0].bottom
;
1441 nc
->lppos
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1442 sizeof(*nc
->lppos
) );
1443 nc
->rgrc
[1].left
= nc16
->rgrc
[1].left
;
1444 nc
->rgrc
[1].top
= nc16
->rgrc
[1].top
;
1445 nc
->rgrc
[1].right
= nc16
->rgrc
[1].right
;
1446 nc
->rgrc
[1].bottom
= nc16
->rgrc
[1].bottom
;
1447 nc
->rgrc
[2].left
= nc16
->rgrc
[2].left
;
1448 nc
->rgrc
[2].top
= nc16
->rgrc
[2].top
;
1449 nc
->rgrc
[2].right
= nc16
->rgrc
[2].right
;
1450 nc
->rgrc
[2].bottom
= nc16
->rgrc
[2].bottom
;
1451 if (nc
->lppos
) WINDOWPOS16to32( MapSL(nc16
->lppos
), nc
->lppos
);
1453 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1454 *plparam
= (LPARAM
)nc
;
1460 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1461 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
1462 sizeof(*cs
) + sizeof(LPARAM
) );
1464 CREATESTRUCT16to32A( cs16
, cs
);
1465 cs
->lpszName
= MapSL(cs16
->lpszName
);
1466 cs
->lpszClass
= MapSL(cs16
->lpszClass
);
1468 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
1470 MDICREATESTRUCT16
*mdi_cs16
;
1471 MDICREATESTRUCTA
*mdi_cs
= (MDICREATESTRUCTA
*)HeapAlloc(GetProcessHeap(), 0,
1475 HeapFree(GetProcessHeap(), 0, cs
);
1478 mdi_cs16
= (MDICREATESTRUCT16
*)MapSL(cs16
->lpCreateParams
);
1479 MDICREATESTRUCT16to32A(mdi_cs16
, mdi_cs
);
1480 mdi_cs
->szTitle
= MapSL(mdi_cs16
->szTitle
);
1481 mdi_cs
->szClass
= MapSL(mdi_cs16
->szClass
);
1483 cs
->lpCreateParams
= mdi_cs
;
1485 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1486 *plparam
= (LPARAM
)cs
;
1489 case WM_PARENTNOTIFY
:
1490 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
1492 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1493 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1496 case WM_WINDOWPOSCHANGING
:
1497 case WM_WINDOWPOSCHANGED
:
1499 WINDOWPOS
*wp
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1500 sizeof(*wp
) + sizeof(LPARAM
) );
1502 WINDOWPOS16to32( MapSL(*plparam
), wp
);
1503 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1504 *plparam
= (LPARAM
)wp
;
1510 LPMSG16 msg16
= MapSL(*plparam
);
1511 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1513 if (!msg32
) return -1;
1514 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1515 msg32
->lParam
= msg16
->lParam
;
1516 msg32
->time
= msg16
->time
;
1517 msg32
->pt
.x
= msg16
->pt
.x
;
1518 msg32
->pt
.y
= msg16
->pt
.y
;
1519 /* this is right, right? */
1520 if (WINPROC_MapMsg16To32A( msg32
->hwnd
, msg16
->message
,msg16
->wParam
,
1521 &msg32
->message
,&msg32
->wParam
,
1522 &msg32
->lParam
)<0) {
1523 HeapFree( GetProcessHeap(), 0, msg32
);
1526 *plparam
= (LPARAM
)msg32
;
1531 *plparam
= (LPARAM
)MapSL(*plparam
);
1533 case WM_ACTIVATEAPP
:
1534 /* We need this when SetActiveWindow sends a Sendmessage16() to
1535 * a 32bit window. Might be superflous with 32bit interprocess
1536 * message queues. */
1537 if (*plparam
) *plparam
= HTASK_32( *plparam
);
1541 MDINEXTMENU
*next
= HeapAlloc( GetProcessHeap(), 0, sizeof(*next
) );
1542 if (!next
) return -1;
1543 next
->hmenuIn
= (HMENU
)*plparam
;
1544 next
->hmenuNext
= 0;
1546 *plparam
= (LPARAM
)next
;
1549 case WM_PAINTCLIPBOARD
:
1550 case WM_SIZECLIPBOARD
:
1551 FIXME_(msg
)("message %04x needs translation\n",msg16
);
1553 case WM_DDE_INITIATE
:
1554 case WM_DDE_TERMINATE
:
1555 case WM_DDE_UNADVISE
:
1556 case WM_DDE_REQUEST
:
1557 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1567 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1568 lo16
= LOWORD(*plparam
);
1569 hi
= HIWORD(*plparam
);
1570 if (lo16
&& !(lo32
= convert_handle_16_to_32(lo16
, GMEM_DDESHARE
)))
1572 *plparam
= PackDDElParam(msg16
, lo32
, hi
);
1574 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1581 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1583 lo
= LOWORD(*plparam
);
1584 hi
= HIWORD(*plparam
);
1586 if (GlobalGetAtomNameA(hi
, buf
, 2) > 0) flag
|= 1;
1587 if (GlobalSize16(hi
) != 0) flag
|= 2;
1593 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1598 break; /* atom, nothing to do */
1600 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
1603 hi
= convert_handle_16_to_32(hi
, GMEM_DDESHARE
);
1606 *plparam
= PackDDElParam(WM_DDE_ACK
, lo
, hi
);
1608 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1609 case WM_DDE_EXECUTE
:
1610 *plparam
= convert_handle_16_to_32(*plparam
, GMEM_DDESHARE
);
1611 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1612 default: /* No translation needed */
1618 /**********************************************************************
1619 * WINPROC_UnmapMsg16To32A
1621 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1623 LRESULT
WINPROC_UnmapMsg16To32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1628 case WM_COMPAREITEM
:
1631 HeapFree( GetProcessHeap(), 0, (LPVOID
)lParam
);
1633 case WM_MEASUREITEM
:
1635 MEASUREITEMSTRUCT16
*mis16
;
1636 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)lParam
;
1637 lParam
= *(LPARAM
*)(mis
+ 1);
1638 mis16
= MapSL(lParam
);
1639 mis16
->itemWidth
= (UINT16
)mis
->itemWidth
;
1640 mis16
->itemHeight
= (UINT16
)mis
->itemHeight
;
1641 HeapFree( GetProcessHeap(), 0, mis
);
1644 case WM_GETMINMAXINFO
:
1646 MINMAXINFO
*mmi
= (MINMAXINFO
*)lParam
;
1647 lParam
= *(LPARAM
*)(mmi
+ 1);
1648 MINMAXINFO32to16( mmi
, MapSL(lParam
));
1649 HeapFree( GetProcessHeap(), 0, mmi
);
1654 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1655 lParam
= *(LPARAM
*)(cs
+ 1);
1656 MDICREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1657 HeapFree( GetProcessHeap(), 0, cs
);
1660 case WM_MDIGETACTIVE
:
1661 result
= MAKELONG( LOWORD(result
), (BOOL16
)(*(BOOL
*)lParam
) );
1662 HeapFree( GetProcessHeap(), 0, (BOOL
*)lParam
);
1666 NCCALCSIZE_PARAMS16
*nc16
;
1667 NCCALCSIZE_PARAMS
*nc
= (NCCALCSIZE_PARAMS
*)lParam
;
1668 lParam
= *(LPARAM
*)(nc
+ 1);
1669 nc16
= MapSL(lParam
);
1670 nc16
->rgrc
[0].left
= nc
->rgrc
[0].left
;
1671 nc16
->rgrc
[0].top
= nc
->rgrc
[0].top
;
1672 nc16
->rgrc
[0].right
= nc
->rgrc
[0].right
;
1673 nc16
->rgrc
[0].bottom
= nc
->rgrc
[0].bottom
;
1676 nc16
->rgrc
[1].left
= nc
->rgrc
[1].left
;
1677 nc16
->rgrc
[1].top
= nc
->rgrc
[1].top
;
1678 nc16
->rgrc
[1].right
= nc
->rgrc
[1].right
;
1679 nc16
->rgrc
[1].bottom
= nc
->rgrc
[1].bottom
;
1680 nc16
->rgrc
[2].left
= nc
->rgrc
[2].left
;
1681 nc16
->rgrc
[2].top
= nc
->rgrc
[2].top
;
1682 nc16
->rgrc
[2].right
= nc
->rgrc
[2].right
;
1683 nc16
->rgrc
[2].bottom
= nc
->rgrc
[2].bottom
;
1686 WINDOWPOS32to16( nc
->lppos
, MapSL(nc16
->lppos
));
1687 HeapFree( GetProcessHeap(), 0, nc
->lppos
);
1690 HeapFree( GetProcessHeap(), 0, nc
);
1696 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1697 lParam
= *(LPARAM
*)(cs
+ 1);
1698 CREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1700 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
1701 HeapFree(GetProcessHeap(), 0, cs
->lpCreateParams
);
1703 HeapFree( GetProcessHeap(), 0, cs
);
1706 case WM_WINDOWPOSCHANGING
:
1707 case WM_WINDOWPOSCHANGED
:
1709 WINDOWPOS
*wp
= (WINDOWPOS
*)lParam
;
1710 lParam
= *(LPARAM
*)(wp
+ 1);
1711 WINDOWPOS32to16(wp
, MapSL(lParam
));
1712 HeapFree( GetProcessHeap(), 0, wp
);
1718 LPMSG msg32
= (LPMSG
)lParam
;
1720 WINPROC_UnmapMsg16To32A( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1722 HeapFree( GetProcessHeap(), 0, msg32
);
1727 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1728 result
= MAKELONG( HMENU_16(next
->hmenuNext
), HWND_16(next
->hwndNext
) );
1729 HeapFree( GetProcessHeap(), 0, next
);
1737 /**********************************************************************
1738 * WINPROC_MapMsg16To32W
1740 * Map a message from 16- to 32-bit Unicode.
1741 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1743 INT
WINPROC_MapMsg16To32W( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1744 WPARAM
*pwparam32
, LPARAM
*plparam
)
1749 *pmsg32
=(UINT
)msg16
;
1750 *pwparam32
= (WPARAM
)wParam16
;
1755 case WM_WININICHANGE
:
1756 case WM_DEVMODECHANGE
:
1757 case WM_ASKCBFORMATNAME
:
1758 *plparam
= (LPARAM
)MapSL(*plparam
);
1759 return WINPROC_MapMsg32ATo32W( hwnd
, *pmsg32
, pwparam32
, plparam
);
1760 case WM_GETTEXTLENGTH
:
1761 case CB_GETLBTEXTLEN
:
1763 return 1; /* need to map result */
1767 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1768 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1769 sizeof(*cs
) + sizeof(LPARAM
) );
1771 CREATESTRUCT16to32A( cs16
, (CREATESTRUCTA
*)cs
);
1772 cs
->lpszName
= map_str_16_to_32W(cs16
->lpszName
);
1773 cs
->lpszClass
= map_str_16_to_32W(cs16
->lpszClass
);
1775 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
1777 MDICREATESTRUCT16
*mdi_cs16
;
1778 MDICREATESTRUCTW
*mdi_cs
= (MDICREATESTRUCTW
*)HeapAlloc(GetProcessHeap(), 0,
1782 HeapFree(GetProcessHeap(), 0, cs
);
1785 mdi_cs16
= (MDICREATESTRUCT16
*)MapSL(cs16
->lpCreateParams
);
1786 MDICREATESTRUCT16to32A(mdi_cs16
, (MDICREATESTRUCTA
*)mdi_cs
);
1787 mdi_cs
->szTitle
= map_str_16_to_32W(mdi_cs16
->szTitle
);
1788 mdi_cs
->szClass
= map_str_16_to_32W(mdi_cs16
->szClass
);
1790 cs
->lpCreateParams
= mdi_cs
;
1792 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1793 *plparam
= (LPARAM
)cs
;
1798 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1799 MDICREATESTRUCTW
*cs
=
1800 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1801 sizeof(*cs
) + sizeof(LPARAM
) );
1803 MDICREATESTRUCT16to32A( cs16
, (MDICREATESTRUCTA
*)cs
);
1804 cs
->szTitle
= map_str_16_to_32W(cs16
->szTitle
);
1805 cs
->szClass
= map_str_16_to_32W(cs16
->szClass
);
1806 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1807 *plparam
= (LPARAM
)cs
;
1813 LPMSG16 msg16
= MapSL(*plparam
);
1814 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1816 if (!msg32
) return -1;
1817 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1818 msg32
->lParam
= msg16
->lParam
;
1819 msg32
->time
= msg16
->time
;
1820 msg32
->pt
.x
= msg16
->pt
.x
;
1821 msg32
->pt
.y
= msg16
->pt
.y
;
1822 /* this is right, right? */
1823 if (WINPROC_MapMsg16To32W(hwnd
, msg16
->message
,msg16
->wParam
,
1824 &msg32
->message
,&msg32
->wParam
,
1825 &msg32
->lParam
)<0) {
1826 HeapFree( GetProcessHeap(), 0, msg32
);
1829 *plparam
= (LPARAM
)msg32
;
1836 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1837 *pwparam32
= MAKEWPARAM( wch
, HIWORD(*plparam
) );
1838 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1842 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1843 *pwparam32
= MAKEWPARAM( wch
, LOWORD(*plparam
) );
1844 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1849 case WM_SYSDEADCHAR
:
1851 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1855 return WINPROC_MapMsg32ATo32W( hwnd
, *pmsg32
, pwparam32
, plparam
);
1857 default: /* No Unicode translation needed */
1858 return WINPROC_MapMsg16To32A( hwnd
, msg16
, wParam16
, pmsg32
,
1859 pwparam32
, plparam
);
1864 /**********************************************************************
1865 * WINPROC_UnmapMsg16To32W
1867 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1869 LRESULT
WINPROC_UnmapMsg16To32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1876 case WM_GETTEXTLENGTH
:
1877 case CB_GETLBTEXTLEN
:
1879 case WM_ASKCBFORMATNAME
:
1880 return WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
1884 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)lParam
;
1885 lParam
= *(LPARAM
*)(cs
+ 1);
1886 CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs
, MapSL(lParam
) );
1887 unmap_str_16_to_32W( cs
->lpszName
);
1888 unmap_str_16_to_32W( cs
->lpszClass
);
1890 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
1892 MDICREATESTRUCTW
*mdi_cs
= (MDICREATESTRUCTW
*)cs
->lpCreateParams
;
1893 unmap_str_16_to_32W( mdi_cs
->szTitle
);
1894 unmap_str_16_to_32W( mdi_cs
->szClass
);
1895 HeapFree(GetProcessHeap(), 0, cs
->lpCreateParams
);
1897 HeapFree( GetProcessHeap(), 0, cs
);
1902 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
1903 lParam
= *(LPARAM
*)(cs
+ 1);
1904 MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs
, MapSL(lParam
) );
1905 unmap_str_16_to_32W( cs
->szTitle
);
1906 unmap_str_16_to_32W( cs
->szClass
);
1907 HeapFree( GetProcessHeap(), 0, cs
);
1913 LPMSG msg32
= (LPMSG
)lParam
;
1915 WINPROC_UnmapMsg16To32W( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1917 HeapFree( GetProcessHeap(), 0, msg32
);
1921 return WINPROC_UnmapMsg16To32A( hwnd
, msg
, wParam
, lParam
, result
);
1926 static HANDLE16
convert_handle_32_to_16(UINT src
, unsigned int flags
)
1929 UINT sz
= GlobalSize((HANDLE
)src
);
1932 if (!(dst
= GlobalAlloc16(flags
, sz
)))
1934 ptr32
= GlobalLock((HANDLE
)src
);
1935 ptr16
= GlobalLock16(dst
);
1936 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr16
, ptr32
, sz
);
1937 GlobalUnlock((HANDLE
)src
);
1938 GlobalUnlock16(dst
);
1944 /**********************************************************************
1945 * WINPROC_MapMsg32ATo16
1947 * Map a message from 32-bit Ansi to 16-bit.
1948 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1950 INT
WINPROC_MapMsg32ATo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
1951 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
1954 *pmsg16
= (UINT16
)msg32
;
1955 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1959 *pmsg16
= SBM_SETRANGE16
;
1960 *plparam
= MAKELPARAM(wParam32
, *plparam
);
1965 *pmsg16
= SBM_GETRANGE16
;
1973 *pmsg16
= (UINT16
)msg32
+ (BM_GETCHECK16
- BM_GETCHECK
);
1982 case EM_SCROLLCARET
:
1985 case EM_GETLINECOUNT
:
1997 case EM_LINEFROMCHAR
:
1998 case EM_SETTABSTOPS
:
1999 case EM_SETPASSWORDCHAR
:
2000 case EM_EMPTYUNDOBUFFER
:
2001 case EM_GETFIRSTVISIBLELINE
:
2002 case EM_SETREADONLY
:
2003 case EM_SETWORDBREAKPROC
:
2004 case EM_GETWORDBREAKPROC
:
2005 case EM_GETPASSWORDCHAR
:
2006 *pmsg16
= (UINT16
)msg32
+ (EM_GETSEL16
- EM_GETSEL
);
2011 case LB_DELETESTRING
:
2012 case LB_GETANCHORINDEX
:
2013 case LB_GETCARETINDEX
:
2016 case LB_GETHORIZONTALEXTENT
:
2017 case LB_GETITEMDATA
:
2018 case LB_GETITEMHEIGHT
:
2020 case LB_GETSELCOUNT
:
2022 case LB_GETTOPINDEX
:
2023 case LB_RESETCONTENT
:
2024 case LB_SELITEMRANGE
:
2025 case LB_SELITEMRANGEEX
:
2026 case LB_SETANCHORINDEX
:
2027 case LB_SETCARETINDEX
:
2028 case LB_SETCOLUMNWIDTH
:
2030 case LB_SETHORIZONTALEXTENT
:
2031 case LB_SETITEMDATA
:
2032 case LB_SETITEMHEIGHT
:
2034 case LB_SETTOPINDEX
:
2035 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2037 case CB_DELETESTRING
:
2039 case CB_GETLBTEXTLEN
:
2041 case CB_RESETCONTENT
:
2045 case CB_SHOWDROPDOWN
:
2046 case CB_SETITEMDATA
:
2047 case CB_SETITEMHEIGHT
:
2048 case CB_GETITEMHEIGHT
:
2049 case CB_SETEXTENDEDUI
:
2050 case CB_GETEXTENDEDUI
:
2051 case CB_GETDROPPEDSTATE
:
2052 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
2055 *pmsg16
= CB_GETEDITSEL16
;
2060 case LB_FINDSTRINGEXACT
:
2061 case LB_INSERTSTRING
:
2062 case LB_SELECTSTRING
:
2065 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
2066 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2071 case CB_FINDSTRINGEXACT
:
2072 case CB_INSERTSTRING
:
2073 case CB_SELECTSTRING
:
2075 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
2076 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
2079 case LB_GETITEMRECT
:
2081 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
2082 if (!rect
) return -1;
2083 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
2084 *plparam
= MapLS( rect
);
2086 *pmsg16
= LB_GETITEMRECT16
;
2088 case LB_GETSELITEMS
:
2090 LPARAM
*items
; /* old LPARAM first, then *pwparam16 x INT16 entries */
2092 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
2093 if (!(items
= HeapAlloc( GetProcessHeap(), 0,
2094 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
2095 *items
++ = *plparam
; /* Store the previous lParam */
2096 *plparam
= MapLS( items
);
2098 *pmsg16
= LB_GETSELITEMS16
;
2100 case LB_SETTABSTOPS
:
2105 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
2106 if (!(stops
= HeapAlloc( GetProcessHeap(), 0,
2107 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
2108 for (i
= 0; i
< *pwparam16
; i
++) stops
[i
] = *((LPINT
)*plparam
+i
);
2109 *plparam
= MapLS( stops
);
2112 *pmsg16
= LB_SETTABSTOPS16
;
2115 case CB_GETDROPPEDCONTROLRECT
:
2117 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
2118 if (!rect
) return -1;
2119 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
2120 *plparam
= (LPARAM
)MapLS(rect
);
2122 *pmsg16
= CB_GETDROPPEDCONTROLRECT16
;
2126 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
2127 *pmsg16
= LB_GETTEXT16
;
2131 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
2132 *pmsg16
= CB_GETLBTEXT16
;
2137 *plparam
= MAKELONG( (INT16
)(INT
)wParam32
, (INT16
)*plparam
);
2138 *pmsg16
= EM_SETSEL16
;
2145 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
2149 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
2151 case WM_CTLCOLORMSGBOX
:
2152 case WM_CTLCOLOREDIT
:
2153 case WM_CTLCOLORLISTBOX
:
2154 case WM_CTLCOLORBTN
:
2155 case WM_CTLCOLORDLG
:
2156 case WM_CTLCOLORSCROLLBAR
:
2157 case WM_CTLCOLORSTATIC
:
2158 *pmsg16
= WM_CTLCOLOR
;
2159 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
2160 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
2162 case WM_COMPAREITEM
:
2164 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)*plparam
;
2165 COMPAREITEMSTRUCT16
*cis
= HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16
));
2166 if (!cis
) return -1;
2167 cis
->CtlType
= (UINT16
)cis32
->CtlType
;
2168 cis
->CtlID
= (UINT16
)cis32
->CtlID
;
2169 cis
->hwndItem
= HWND_16( cis32
->hwndItem
);
2170 cis
->itemID1
= (UINT16
)cis32
->itemID1
;
2171 cis
->itemData1
= cis32
->itemData1
;
2172 cis
->itemID2
= (UINT16
)cis32
->itemID2
;
2173 cis
->itemData2
= cis32
->itemData2
;
2174 *plparam
= MapLS( cis
);
2179 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)*plparam
;
2180 DELETEITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16
) );
2181 if (!dis
) return -1;
2182 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
2183 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
2184 dis
->itemID
= (UINT16
)dis32
->itemID
;
2185 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
2186 : HWND_16( dis32
->hwndItem
);
2187 dis
->itemData
= dis32
->itemData
;
2188 *plparam
= MapLS( dis
);
2193 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)*plparam
;
2194 DRAWITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16
) );
2195 if (!dis
) return -1;
2196 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
2197 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
2198 dis
->itemID
= (UINT16
)dis32
->itemID
;
2199 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
2200 dis
->itemState
= (UINT16
)dis32
->itemState
;
2201 dis
->hwndItem
= HWND_16( dis32
->hwndItem
);
2202 dis
->hDC
= HDC_16(dis32
->hDC
);
2203 dis
->itemData
= dis32
->itemData
;
2204 dis
->rcItem
.left
= dis32
->rcItem
.left
;
2205 dis
->rcItem
.top
= dis32
->rcItem
.top
;
2206 dis
->rcItem
.right
= dis32
->rcItem
.right
;
2207 dis
->rcItem
.bottom
= dis32
->rcItem
.bottom
;
2208 *plparam
= MapLS( dis
);
2211 case WM_MEASUREITEM
:
2213 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)*plparam
;
2214 MEASUREITEMSTRUCT16
*mis
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mis
)+sizeof(LPARAM
));
2215 if (!mis
) return -1;
2216 mis
->CtlType
= (UINT16
)mis32
->CtlType
;
2217 mis
->CtlID
= (UINT16
)mis32
->CtlID
;
2218 mis
->itemID
= (UINT16
)mis32
->itemID
;
2219 mis
->itemWidth
= (UINT16
)mis32
->itemWidth
;
2220 mis
->itemHeight
= (UINT16
)mis32
->itemHeight
;
2221 mis
->itemData
= mis32
->itemData
;
2222 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
2223 *plparam
= MapLS( mis
);
2226 case WM_GETMINMAXINFO
:
2228 MINMAXINFO16
*mmi
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi
) + sizeof(LPARAM
) );
2229 if (!mmi
) return -1;
2230 MINMAXINFO32to16( (MINMAXINFO
*)*plparam
, mmi
);
2231 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
2232 *plparam
= MapLS( mmi
);
2236 case WM_ASKCBFORMATNAME
:
2238 LPARAM
*str
; /* store LPARAM, then *pwparam16 char space */
2239 *pwparam16
= (WPARAM16
)min( wParam32
, 0xff80 ); /* Must be < 64K */
2240 if (!(str
= HeapAlloc( GetProcessHeap(), 0, *pwparam16
+ sizeof(LPARAM
)))) return -1;
2241 *str
++ = *plparam
; /* Store the previous lParam */
2242 *plparam
= MapLS( str
);
2247 MDICREATESTRUCT16
*cs
;
2248 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)*plparam
;
2250 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2251 MDICREATESTRUCT32Ato16( cs32
, cs
);
2252 cs
->szTitle
= MapLS( cs32
->szTitle
);
2253 cs
->szClass
= MapLS( cs32
->szClass
);
2254 *plparam
= MapLS( cs
);
2257 case WM_MDIGETACTIVE
:
2260 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
2261 (HMENU16
)LOWORD(*plparam
) );
2262 *pwparam16
= (*plparam
== 0);
2265 if(HIWORD(wParam32
) & MF_POPUP
)
2268 if (((UINT
)HIWORD(wParam32
) != 0xFFFF) || (*plparam
))
2270 if((hmenu
= GetSubMenu((HMENU
)*plparam
, *pwparam16
)))
2271 *pwparam16
=HMENU_16(hmenu
);
2276 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2278 case WM_MDIACTIVATE
:
2279 if (GetWindowLongW( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2281 *pwparam16
= ((HWND
)*plparam
== hwnd
);
2282 *plparam
= MAKELPARAM( (HWND16
)LOWORD(*plparam
),
2283 (HWND16
)LOWORD(wParam32
) );
2287 *pwparam16
= HWND_16( (HWND
)wParam32
);
2293 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)*plparam
;
2294 NCCALCSIZE_PARAMS16
*nc
= HeapAlloc( GetProcessHeap(), 0, sizeof(*nc
) + sizeof(LPARAM
));
2297 nc
->rgrc
[0].left
= nc32
->rgrc
[0].left
;
2298 nc
->rgrc
[0].top
= nc32
->rgrc
[0].top
;
2299 nc
->rgrc
[0].right
= nc32
->rgrc
[0].right
;
2300 nc
->rgrc
[0].bottom
= nc32
->rgrc
[0].bottom
;
2304 nc
->rgrc
[1].left
= nc32
->rgrc
[1].left
;
2305 nc
->rgrc
[1].top
= nc32
->rgrc
[1].top
;
2306 nc
->rgrc
[1].right
= nc32
->rgrc
[1].right
;
2307 nc
->rgrc
[1].bottom
= nc32
->rgrc
[1].bottom
;
2308 nc
->rgrc
[2].left
= nc32
->rgrc
[2].left
;
2309 nc
->rgrc
[2].top
= nc32
->rgrc
[2].top
;
2310 nc
->rgrc
[2].right
= nc32
->rgrc
[2].right
;
2311 nc
->rgrc
[2].bottom
= nc32
->rgrc
[2].bottom
;
2312 if (!(wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16
) )))
2314 HeapFree( GetProcessHeap(), 0, nc
);
2317 WINDOWPOS32to16( nc32
->lppos
, wp
);
2318 nc
->lppos
= MapLS( wp
);
2320 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
2321 *plparam
= MapLS( nc
);
2328 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)*plparam
;
2330 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2331 CREATESTRUCT32Ato16( cs32
, cs
);
2332 cs
->lpszName
= MapLS( cs32
->lpszName
);
2333 cs
->lpszClass
= MapLS( cs32
->lpszClass
);
2335 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2337 MDICREATESTRUCT16
*mdi_cs16
;
2338 MDICREATESTRUCTA
*mdi_cs
= (MDICREATESTRUCTA
*)cs32
->lpCreateParams
;
2339 mdi_cs16
= HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs16
));
2342 HeapFree(GetProcessHeap(), 0, cs
);
2345 MDICREATESTRUCT32Ato16(mdi_cs
, mdi_cs16
);
2346 mdi_cs16
->szTitle
= MapLS( mdi_cs
->szTitle
);
2347 mdi_cs16
->szClass
= MapLS( mdi_cs
->szClass
);
2348 cs
->lpCreateParams
= MapLS( mdi_cs16
);
2350 *plparam
= MapLS( cs
);
2353 case WM_PARENTNOTIFY
:
2354 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
2355 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
2356 /* else nothing to do */
2359 *plparam
= MapLS( (NMHDR
*)*plparam
); /* NMHDR is already 32-bit */
2362 case WM_WININICHANGE
:
2363 case WM_DEVMODECHANGE
:
2364 *plparam
= MapLS( (LPSTR
)*plparam
);
2366 case WM_WINDOWPOSCHANGING
:
2367 case WM_WINDOWPOSCHANGED
:
2369 WINDOWPOS16
*wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(*wp
) + sizeof(LPARAM
) );
2371 WINDOWPOS32to16( (WINDOWPOS
*)*plparam
, wp
);
2372 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
2373 *plparam
= MapLS( wp
);
2378 LPMSG msg32
= (LPMSG
) *plparam
;
2379 LPMSG16 msg16
= HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16
) );
2381 if (!msg16
) return -1;
2382 msg16
->hwnd
= HWND_16( msg32
->hwnd
);
2383 msg16
->lParam
= msg32
->lParam
;
2384 msg16
->time
= msg32
->time
;
2385 msg16
->pt
.x
= msg32
->pt
.x
;
2386 msg16
->pt
.y
= msg32
->pt
.y
;
2387 /* this is right, right? */
2388 if (WINPROC_MapMsg32ATo16(msg32
->hwnd
,msg32
->message
,msg32
->wParam
,
2389 &msg16
->message
,&msg16
->wParam
, &msg16
->lParam
)<0)
2391 HeapFree( GetProcessHeap(), 0, msg16
);
2394 *plparam
= MapLS( msg16
);
2399 case WM_ACTIVATEAPP
:
2400 if (*plparam
) *plparam
= HTASK_16( (HANDLE
)*plparam
);
2404 MDINEXTMENU
*next
= (MDINEXTMENU
*)*plparam
;
2405 *plparam
= (LPARAM
)next
->hmenuIn
;
2409 if (IsIconic( hwnd
) && GetClassLongW( hwnd
, GCL_HICON
))
2411 *pmsg16
= WM_PAINTICON
;
2416 if (IsIconic( hwnd
) && GetClassLongW( hwnd
, GCL_HICON
))
2417 *pmsg16
= WM_ICONERASEBKGND
;
2419 case WM_PAINTCLIPBOARD
:
2420 case WM_SIZECLIPBOARD
:
2421 FIXME_(msg
)("message %04x needs translation\n", msg32
);
2423 /* following messages should not be sent to 16-bit apps */
2426 case WM_CAPTURECHANGED
:
2427 case WM_STYLECHANGING
:
2428 case WM_STYLECHANGED
:
2430 case WM_DDE_INITIATE
:
2431 case WM_DDE_TERMINATE
:
2432 case WM_DDE_UNADVISE
:
2433 case WM_DDE_REQUEST
:
2434 *pwparam16
= HWND_16((HWND
)wParam32
);
2443 *pwparam16
= HWND_16((HWND
)wParam32
);
2444 UnpackDDElParam(msg32
, *plparam
, &lo32
, &hi
);
2445 if (lo32
&& !(lo16
= convert_handle_32_to_16(lo32
, GMEM_DDESHARE
)))
2447 *plparam
= MAKELPARAM(lo16
, hi
);
2449 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2456 *pwparam16
= HWND_16((HWND
)wParam32
);
2458 UnpackDDElParam(msg32
, *plparam
, &lo
, &hi
);
2460 if (GlobalGetAtomNameA((ATOM
)hi
, buf
, sizeof(buf
)) > 0) flag
|= 1;
2461 if (GlobalSize((HANDLE
)hi
) != 0) flag
|= 2;
2467 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
2472 break; /* atom, nothing to do */
2474 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
2477 hi
= convert_handle_32_to_16(hi
, GMEM_DDESHARE
);
2480 *plparam
= MAKELPARAM(lo
, hi
);
2482 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2483 case WM_DDE_EXECUTE
:
2484 *plparam
= convert_handle_32_to_16(*plparam
, GMEM_DDESHARE
);
2485 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2486 default: /* No translation needed */
2492 /**********************************************************************
2493 * WINPROC_UnmapMsg32ATo16
2495 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2497 void WINPROC_UnmapMsg32ATo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2503 *(LPINT
)wParam
= LOWORD(p16
->lResult
);
2504 *(LPINT
)lParam
= HIWORD(p16
->lResult
);
2511 case LB_FINDSTRINGEXACT
:
2512 case LB_INSERTSTRING
:
2513 case LB_SELECTSTRING
:
2517 case CB_FINDSTRINGEXACT
:
2518 case CB_INSERTSTRING
:
2519 case CB_SELECTSTRING
:
2523 case WM_WININICHANGE
:
2524 case WM_DEVMODECHANGE
:
2525 UnMapLS( (SEGPTR
)p16
->lParam
);
2527 case LB_SETTABSTOPS
:
2528 case WM_COMPAREITEM
:
2532 void *ptr
= MapSL( p16
->lParam
);
2533 UnMapLS( p16
->lParam
);
2534 HeapFree( GetProcessHeap(), 0, ptr
);
2537 case CB_GETDROPPEDCONTROLRECT
:
2538 case LB_GETITEMRECT
:
2541 RECT16
*rect
= MapSL(p16
->lParam
);
2542 UnMapLS( p16
->lParam
);
2543 p16
->lParam
= *(LPARAM
*)(rect
+ 1);
2544 r32
= (RECT
*)p16
->lParam
;
2545 r32
->left
= rect
->left
;
2546 r32
->top
= rect
->top
;
2547 r32
->right
= rect
->right
;
2548 r32
->bottom
= rect
->bottom
;
2549 HeapFree( GetProcessHeap(), 0, rect
);
2552 case LB_GETSELITEMS
:
2555 LPINT16 items
= MapSL(p16
->lParam
);
2556 UnMapLS( p16
->lParam
);
2557 p16
->lParam
= *((LPARAM
*)items
- 1);
2558 for (i
= 0; i
< p16
->wParam
; i
++) *((LPINT
)(p16
->lParam
) + i
) = items
[i
];
2559 HeapFree( GetProcessHeap(), 0, (LPARAM
*)items
- 1 );
2565 *((PUINT
)(wParam
)) = LOWORD(p16
->lResult
);
2567 *((PUINT
)(lParam
)) = HIWORD(p16
->lResult
); /* FIXME: substract 1? */
2570 case WM_MEASUREITEM
:
2572 MEASUREITEMSTRUCT16
*mis
= MapSL(p16
->lParam
);
2573 MEASUREITEMSTRUCT
*mis32
= *(MEASUREITEMSTRUCT
**)(mis
+ 1);
2574 mis32
->itemWidth
= mis
->itemWidth
;
2575 mis32
->itemHeight
= mis
->itemHeight
;
2576 UnMapLS( p16
->lParam
);
2577 HeapFree( GetProcessHeap(), 0, mis
);
2580 case WM_GETMINMAXINFO
:
2582 MINMAXINFO16
*mmi
= MapSL(p16
->lParam
);
2583 UnMapLS( p16
->lParam
);
2584 p16
->lParam
= *(LPARAM
*)(mmi
+ 1);
2585 MINMAXINFO16to32( mmi
, (MINMAXINFO
*)(p16
->lParam
) );
2586 HeapFree( GetProcessHeap(), 0, mmi
);
2590 case WM_ASKCBFORMATNAME
:
2592 LPSTR str
= MapSL(p16
->lParam
);
2593 UnMapLS( p16
->lParam
);
2594 p16
->lParam
= *((LPARAM
*)str
- 1);
2595 lstrcpynA( (LPSTR
)(p16
->lParam
), str
, p16
->wParam
);
2596 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2601 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2602 UnMapLS( cs
->szTitle
);
2603 UnMapLS( cs
->szClass
);
2604 UnMapLS( p16
->lParam
);
2605 HeapFree( GetProcessHeap(), 0, cs
);
2608 case WM_MDIGETACTIVE
:
2609 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(p16
->lResult
);
2610 p16
->lResult
= (LRESULT
)WIN_Handle32( LOWORD(p16
->lResult
) );
2614 NCCALCSIZE_PARAMS
*nc32
;
2615 NCCALCSIZE_PARAMS16
*nc
= MapSL(p16
->lParam
);
2616 UnMapLS( p16
->lParam
);
2617 p16
->lParam
= *(LPARAM
*)(nc
+ 1);
2618 nc32
= (NCCALCSIZE_PARAMS
*)(p16
->lParam
);
2619 nc32
->rgrc
[0].left
= nc
->rgrc
[0].left
;
2620 nc32
->rgrc
[0].top
= nc
->rgrc
[0].top
;
2621 nc32
->rgrc
[0].right
= nc
->rgrc
[0].right
;
2622 nc32
->rgrc
[0].bottom
= nc
->rgrc
[0].bottom
;
2625 WINDOWPOS16
*pos
= MapSL(nc
->lppos
);
2626 UnMapLS( nc
->lppos
);
2627 nc32
->rgrc
[1].left
= nc
->rgrc
[1].left
;
2628 nc32
->rgrc
[1].top
= nc
->rgrc
[1].top
;
2629 nc32
->rgrc
[1].right
= nc
->rgrc
[1].right
;
2630 nc32
->rgrc
[1].bottom
= nc
->rgrc
[1].bottom
;
2631 nc32
->rgrc
[2].left
= nc
->rgrc
[2].left
;
2632 nc32
->rgrc
[2].top
= nc
->rgrc
[2].top
;
2633 nc32
->rgrc
[2].right
= nc
->rgrc
[2].right
;
2634 nc32
->rgrc
[2].bottom
= nc
->rgrc
[2].bottom
;
2635 WINDOWPOS16to32( pos
, nc32
->lppos
);
2636 HeapFree( GetProcessHeap(), 0, pos
);
2638 HeapFree( GetProcessHeap(), 0, nc
);
2644 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2645 UnMapLS( p16
->lParam
);
2646 UnMapLS( cs
->lpszName
);
2647 UnMapLS( cs
->lpszClass
);
2648 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2650 MDICREATESTRUCT16
*mdi_cs16
= (MDICREATESTRUCT16
*)MapSL(cs
->lpCreateParams
);
2651 UnMapLS( cs
->lpCreateParams
);
2652 UnMapLS( mdi_cs16
->szTitle
);
2653 UnMapLS( mdi_cs16
->szClass
);
2654 HeapFree(GetProcessHeap(), 0, mdi_cs16
);
2656 HeapFree( GetProcessHeap(), 0, cs
);
2659 case WM_WINDOWPOSCHANGING
:
2660 case WM_WINDOWPOSCHANGED
:
2662 WINDOWPOS16
*wp
= MapSL(p16
->lParam
);
2663 UnMapLS( p16
->lParam
);
2664 p16
->lParam
= *(LPARAM
*)(wp
+ 1);
2665 WINDOWPOS16to32( wp
, (WINDOWPOS
*)p16
->lParam
);
2666 HeapFree( GetProcessHeap(), 0, wp
);
2670 UnMapLS(p16
->lParam
);
2675 LPMSG16 msg16
= MapSL(p16
->lParam
);
2677 UnMapLS( p16
->lParam
);
2678 msgp16
.wParam
=msg16
->wParam
;
2679 msgp16
.lParam
=msg16
->lParam
;
2680 WINPROC_UnmapMsg32ATo16(((LPMSG
)lParam
)->hwnd
, ((LPMSG
)lParam
)->message
,
2681 ((LPMSG
)lParam
)->wParam
, ((LPMSG
)lParam
)->lParam
,
2683 HeapFree( GetProcessHeap(), 0, msg16
);
2688 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
2689 next
->hmenuNext
= HMENU_32( LOWORD(p16
->lResult
) );
2690 next
->hwndNext
= WIN_Handle32( HIWORD(p16
->lResult
) );
2698 /**********************************************************************
2699 * WINPROC_MapMsg32WTo16
2701 * Map a message from 32-bit Unicode to 16-bit.
2702 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2704 INT
WINPROC_MapMsg32WTo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
2705 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
2711 *pmsg16
= LOWORD(msg32
);
2712 *pwparam16
= LOWORD(wParam32
);
2717 case LB_FINDSTRINGEXACT
:
2718 case LB_INSERTSTRING
:
2719 case LB_SELECTSTRING
:
2722 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2723 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2728 case CB_FINDSTRINGEXACT
:
2729 case CB_INSERTSTRING
:
2730 case CB_SELECTSTRING
:
2732 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2733 *pmsg16
= (UINT16
)msg32
+ (CB_ADDSTRING16
- CB_ADDSTRING
);
2740 CREATESTRUCTW
*cs32
= (CREATESTRUCTW
*)*plparam
;
2742 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2743 CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs32
, cs
);
2744 cs
->lpszName
= map_str_32W_to_16( cs32
->lpszName
);
2745 cs
->lpszClass
= map_str_32W_to_16( cs32
->lpszClass
);
2747 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2749 MDICREATESTRUCT16
*mdi_cs16
;
2750 MDICREATESTRUCTW
*mdi_cs
= (MDICREATESTRUCTW
*)cs32
->lpCreateParams
;
2751 mdi_cs16
= HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs16
));
2754 HeapFree(GetProcessHeap(), 0, cs
);
2757 MDICREATESTRUCT32Ato16((MDICREATESTRUCTA
*)mdi_cs
, mdi_cs16
);
2758 mdi_cs16
->szTitle
= map_str_32W_to_16(mdi_cs
->szTitle
);
2759 mdi_cs16
->szClass
= map_str_32W_to_16(mdi_cs
->szClass
);
2760 cs
->lpCreateParams
= MapLS(mdi_cs16
);
2762 *plparam
= MapLS(cs
);
2767 MDICREATESTRUCT16
*cs
;
2768 MDICREATESTRUCTW
*cs32
= (MDICREATESTRUCTW
*)*plparam
;
2770 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2771 MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs32
, cs
);
2772 cs
->szTitle
= map_str_32W_to_16( cs32
->szTitle
);
2773 cs
->szClass
= map_str_32W_to_16( cs32
->szClass
);
2774 *plparam
= MapLS(cs
);
2778 case WM_WININICHANGE
:
2779 case WM_DEVMODECHANGE
:
2780 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2783 if ( WINPROC_TestLBForStr( hwnd
))
2785 LPSTR str
= HeapAlloc( GetProcessHeap(), 0, 256 ); /* FIXME: fixed sized buffer */
2786 if (!str
) return -1;
2787 *pmsg16
= LB_GETTEXT16
;
2788 *plparam
= (LPARAM
)MapLS(str
);
2792 if ( WINPROC_TestCBForStr( hwnd
))
2794 LPSTR str
= HeapAlloc( GetProcessHeap(), 0, 256 ); /* FIXME: fixed sized buffer */
2795 if (!str
) return -1;
2796 *pmsg16
= CB_GETLBTEXT16
;
2797 *plparam
= (LPARAM
)MapLS(str
);
2802 wch
= LOWORD(wParam32
);
2803 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2805 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
2808 wch
= LOWORD(wParam32
);
2809 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2811 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2816 case WM_SYSDEADCHAR
:
2818 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2826 if (WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, ch
, 2, NULL
, NULL
) == 2)
2827 *pwparam16
= (ch
[0] << 8) | ch
[1];
2833 default: /* No Unicode translation needed (?) */
2834 return WINPROC_MapMsg32ATo16( hwnd
, msg32
, wParam32
, pmsg16
,
2835 pwparam16
, plparam
);
2840 /**********************************************************************
2841 * WINPROC_UnmapMsg32WTo16
2843 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2845 void WINPROC_UnmapMsg32WTo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2852 case LB_FINDSTRINGEXACT
:
2853 case LB_INSERTSTRING
:
2854 case LB_SELECTSTRING
:
2859 case CB_FINDSTRINGEXACT
:
2860 case CB_INSERTSTRING
:
2861 case CB_SELECTSTRING
:
2864 case WM_WININICHANGE
:
2865 case WM_DEVMODECHANGE
:
2866 unmap_str_32W_to_16( p16
->lParam
);
2871 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2872 UnMapLS( p16
->lParam
);
2873 unmap_str_32W_to_16( cs
->lpszName
);
2874 unmap_str_32W_to_16( cs
->lpszClass
);
2876 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2878 MDICREATESTRUCT16
*mdi_cs16
= (MDICREATESTRUCT16
*)MapSL(cs
->lpCreateParams
);
2879 UnMapLS( cs
->lpCreateParams
);
2880 unmap_str_32W_to_16(mdi_cs16
->szTitle
);
2881 unmap_str_32W_to_16(mdi_cs16
->szClass
);
2882 HeapFree(GetProcessHeap(), 0, mdi_cs16
);
2884 HeapFree( GetProcessHeap(), 0, cs
);
2889 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2890 UnMapLS( p16
->lParam
);
2891 unmap_str_32W_to_16( cs
->szTitle
);
2892 unmap_str_32W_to_16( cs
->szClass
);
2893 HeapFree( GetProcessHeap(), 0, cs
);
2897 case WM_ASKCBFORMATNAME
:
2899 LPSTR str
= MapSL(p16
->lParam
);
2900 UnMapLS( p16
->lParam
);
2901 p16
->lParam
= *((LPARAM
*)str
- 1);
2902 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)p16
->lParam
, 0x7fffffff );
2903 p16
->lResult
= strlenW( (LPWSTR
)p16
->lParam
);
2904 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2908 if ( WINPROC_TestLBForStr( hwnd
))
2910 LPSTR str
= MapSL(p16
->lParam
);
2911 UnMapLS( p16
->lParam
);
2912 p16
->lResult
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)lParam
, 0x7fffffff ) - 1;
2913 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
);
2917 if ( WINPROC_TestCBForStr( hwnd
))
2919 LPSTR str
= MapSL(p16
->lParam
);
2920 UnMapLS( p16
->lParam
);
2921 p16
->lResult
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)lParam
, 0x7fffffff ) - 1;
2922 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
);
2926 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, p16
);
2932 /**********************************************************************
2933 * WINPROC_CallProc32ATo32W
2935 * Call a window procedure, translating args from Ansi to Unicode.
2937 static LRESULT
WINPROC_CallProc32ATo32W( WNDPROC func
, HWND hwnd
,
2938 UINT msg
, WPARAM wParam
,
2944 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2945 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2947 if( (unmap
= WINPROC_MapMsg32ATo32W( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
2948 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2949 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2952 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2953 if (unmap
) result
= WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
2958 /**********************************************************************
2959 * WINPROC_CallProc32WTo32A_fast
2962 static BOOL
WINPROC_CallProc32WTo32A_fast( WNDPROC func
, HWND hwnd
,
2963 UINT msg
, WPARAM wParam
,
2964 LPARAM lParam
, LRESULT
*result
)
2970 { /* csW->lpszName and csW->lpszClass are NOT supposed to be atoms
2974 char *cls
= buffer
, *name
;
2975 CREATESTRUCTW
*csW
= (CREATESTRUCTW
*)lParam
;
2976 CREATESTRUCTA csA
= *(CREATESTRUCTA
*)csW
;
2977 DWORD name_lenA
, name_lenW
, class_lenA
, class_lenW
;
2979 class_lenW
= strlenW(csW
->lpszClass
) * sizeof(WCHAR
);
2980 RtlUnicodeToMultiByteSize(&class_lenA
, csW
->lpszClass
, class_lenW
);
2984 name_lenW
= strlenW(csW
->lpszName
) * sizeof(WCHAR
);
2985 RtlUnicodeToMultiByteSize(&name_lenA
, csW
->lpszName
, name_lenW
);
2988 name_lenW
= name_lenA
= 0;
2990 if (class_lenA
+ name_lenA
+ 2 > sizeof(buffer
))
2992 cls
= HeapAlloc(GetProcessHeap(), 0, class_lenA
+ name_lenA
+ 2);
2993 if (!cls
) return FALSE
;
2996 RtlUnicodeToMultiByteN(cls
, class_lenA
, NULL
, csW
->lpszClass
, class_lenW
);
2997 cls
[class_lenA
] = 0;
2998 csA
.lpszClass
= cls
;
3002 name
= cls
+ class_lenA
+ 1;
3003 RtlUnicodeToMultiByteN(name
, name_lenA
, NULL
, csW
->lpszName
, name_lenW
);
3004 name
[name_lenA
] = 0;
3005 csA
.lpszName
= name
;
3008 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
3010 MDICREATESTRUCTA mdi_cs
;
3012 mdi_cs
= *(MDICREATESTRUCTA
*)csW
->lpCreateParams
;
3013 mdi_cs
.szTitle
= csA
.lpszName
;
3014 mdi_cs
.szClass
= csA
.lpszClass
;
3015 csA
.lpCreateParams
= &mdi_cs
;
3018 lParam
= (LPARAM
)&csA
;
3019 *result
= WINPROC_CallWndProc(func
, hwnd
, msg
, wParam
, lParam
);
3021 if (cls
!= buffer
) HeapFree(GetProcessHeap(), 0, cls
);
3030 /**********************************************************************
3031 * WINPROC_CallProc32WTo32A
3033 * Call a window procedure, translating args from Unicode to Ansi.
3035 static LRESULT
WINPROC_CallProc32WTo32A( WNDPROC func
, HWND hwnd
,
3036 UINT msg
, WPARAM wParam
,
3042 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3043 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
3045 if (WINPROC_CallProc32WTo32A_fast( func
, hwnd
, msg
, wParam
, lParam
, &result
))
3048 if ((unmap
= WINPROC_MapMsg32WTo32A( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
3049 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
3050 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
3053 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
3054 if( unmap
) result
= WINPROC_UnmapMsg32WTo32A( hwnd
, msg
, wParam
, lParam
, result
);
3059 /**********************************************************************
3060 * __wine_call_wndproc_32A (USER.1010)
3062 LRESULT WINAPI
__wine_call_wndproc_32A( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
3068 HWND hwnd32
= WIN_Handle32( hwnd
);
3070 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3071 func
, hwnd32
, SPY_GetMsgName(msg
, hwnd32
), wParam
, lParam
);
3073 if (WINPROC_MapMsg16To32A( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
3075 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
3076 return WINPROC_UnmapMsg16To32A( hwnd32
, msg32
, wParam32
, lParam
, result
);
3080 /**********************************************************************
3081 * __wine_call_wndproc_32W (USER.1011)
3083 LRESULT WINAPI
__wine_call_wndproc_32W( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
3089 HWND hwnd32
= WIN_Handle32( hwnd
);
3091 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3092 func
, hwnd32
, SPY_GetMsgName(msg
, hwnd32
), wParam
, lParam
);
3094 if (WINPROC_MapMsg16To32W( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
3096 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
3097 return WINPROC_UnmapMsg16To32W( hwnd32
, msg32
, wParam32
, lParam
, result
);
3101 /**********************************************************************
3102 * WINPROC_CallProc32ATo16
3104 * Call a 16-bit window procedure, translating the 32-bit args.
3106 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
3107 UINT msg
, WPARAM wParam
,
3113 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3114 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
3116 mp16
.lParam
= lParam
;
3117 if (WINPROC_MapMsg32ATo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
, &mp16
.lParam
) == -1)
3119 mp16
.lResult
= WINPROC_CallWndProc16( func
, HWND_16(hwnd
), msg16
,
3120 mp16
.wParam
, mp16
.lParam
);
3121 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
3122 return mp16
.lResult
;
3126 /**********************************************************************
3127 * WINPROC_CallProc32WTo16
3129 * Call a 16-bit window procedure, translating the 32-bit args.
3131 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
3132 UINT msg
, WPARAM wParam
,
3138 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
3139 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
3141 mp16
.lParam
= lParam
;
3142 if (WINPROC_MapMsg32WTo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
,
3143 &mp16
.lParam
) == -1)
3145 mp16
.lResult
= WINPROC_CallWndProc16( func
, HWND_16(hwnd
), msg16
,
3146 mp16
.wParam
, mp16
.lParam
);
3147 WINPROC_UnmapMsg32WTo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
3148 return mp16
.lResult
;
3152 /**********************************************************************
3153 * CallWindowProc (USER.122)
3155 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
3156 WPARAM16 wParam
, LPARAM lParam
)
3160 if (!func
) return 0;
3162 if (!(proc
= WINPROC_GetPtr( (WNDPROC
)func
)))
3163 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
3166 func
= WINPROC_GetProc( (WNDPROC
)proc
, WIN_PROC_16
);
3167 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
3173 if (!proc
->thunk
.t_from32
.proc
) return 0;
3174 return WINPROC_CallWndProc16( proc
->thunk
.t_from32
.proc
,
3175 hwnd
, msg
, wParam
, lParam
);
3177 if (!proc
->thunk
.t_from16
.proc
) return 0;
3178 return __wine_call_wndproc_32A( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
3180 if (!proc
->thunk
.t_from16
.proc
) return 0;
3181 return __wine_call_wndproc_32W( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
3183 WARN_(relay
)("Invalid proc %p\n", proc
);
3189 /**********************************************************************
3190 * CallWindowProcA (USER32.@)
3192 * The CallWindowProc() function invokes the windows procedure _func_,
3193 * with _hwnd_ as the target window, the message specified by _msg_, and
3194 * the message parameters _wParam_ and _lParam_.
3196 * Some kinds of argument conversion may be done, I'm not sure what.
3198 * CallWindowProc() may be used for windows subclassing. Use
3199 * SetWindowLong() to set a new windows procedure for windows of the
3200 * subclass, and handle subclassed messages in the new windows
3201 * procedure. The new windows procedure may then use CallWindowProc()
3202 * with _func_ set to the parent class's windows procedure to dispatch
3203 * the message to the superclass.
3207 * The return value is message dependent.
3213 LRESULT WINAPI
CallWindowProcA(
3214 WNDPROC func
, /* [in] window procedure */
3215 HWND hwnd
, /* [in] target window */
3216 UINT msg
, /* [in] message */
3217 WPARAM wParam
, /* [in] message dependent parameter */
3218 LPARAM lParam
/* [in] message dependent parameter */
3222 if (!func
) return 0;
3224 if (!(proc
= WINPROC_GetPtr( func
)))
3225 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
3228 func
= WINPROC_GetProc( (WNDPROC
)proc
, WIN_PROC_32A
);
3229 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
3235 if (!proc
->thunk
.t_from32
.proc
) return 0;
3236 return WINPROC_CallProc32ATo16( proc
->thunk
.t_from32
.proc
,
3237 hwnd
, msg
, wParam
, lParam
);
3239 if (!proc
->thunk
.t_from16
.proc
) return 0;
3240 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
3241 hwnd
, msg
, wParam
, lParam
);
3243 if (!proc
->thunk
.t_from16
.proc
) return 0;
3244 return WINPROC_CallProc32ATo32W( proc
->thunk
.t_from16
.proc
,
3245 hwnd
, msg
, wParam
, lParam
);
3247 WARN_(relay
)("Invalid proc %p\n", proc
);
3253 /**********************************************************************
3254 * CallWindowProcW (USER32.@)
3256 LRESULT WINAPI
CallWindowProcW( WNDPROC func
, HWND hwnd
, UINT msg
,
3257 WPARAM wParam
, LPARAM lParam
)
3261 if (!func
) return 0;
3263 if (!(proc
= WINPROC_GetPtr( (WNDPROC
)func
)))
3264 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
3267 func
= WINPROC_GetProc( (WNDPROC
)proc
, WIN_PROC_32W
);
3268 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
3274 if (!proc
->thunk
.t_from32
.proc
) return 0;
3275 return WINPROC_CallProc32WTo16( proc
->thunk
.t_from32
.proc
,
3276 hwnd
, msg
, wParam
, lParam
);
3278 if (!proc
->thunk
.t_from16
.proc
) return 0;
3279 return WINPROC_CallProc32WTo32A( proc
->thunk
.t_from16
.proc
,
3280 hwnd
, msg
, wParam
, lParam
);
3282 if (!proc
->thunk
.t_from16
.proc
) return 0;
3283 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
3284 hwnd
, msg
, wParam
, lParam
);
3286 WARN_(relay
)("Invalid proc %p\n", proc
);