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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/port.h"
33 #include "wine/winbase16.h"
34 #include "wine/winuser16.h"
38 #include "user_private.h"
41 #include "wine/unicode.h"
42 #include "wine/debug.h"
44 WINE_DECLARE_DEBUG_CHANNEL(msg
);
45 WINE_DECLARE_DEBUG_CHANNEL(relay
);
46 WINE_DEFAULT_DEBUG_CHANNEL(win
);
48 typedef struct tagWINDOWPROC
50 WNDPROC16 proc16
; /* 16-bit window proc */
51 WNDPROC procA
; /* ASCII window proc */
52 WNDPROC procW
; /* Unicode window proc */
55 #define WINPROC_HANDLE (~0UL >> 16)
56 #define MAX_WINPROCS 8192
58 static WINDOWPROC winproc_array
[MAX_WINPROCS
];
59 static UINT winproc_used
;
61 static CRITICAL_SECTION winproc_cs
;
62 static CRITICAL_SECTION_DEBUG critsect_debug
=
65 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
66 0, 0, { (DWORD_PTR
)(__FILE__
": winproc_cs") }
68 static CRITICAL_SECTION winproc_cs
= { &critsect_debug
, -1, 0, 0, 0, 0 };
70 static inline void *get_buffer( void *static_buffer
, size_t size
, size_t need
)
72 if (size
>= need
) return static_buffer
;
73 return HeapAlloc( GetProcessHeap(), 0, need
);
76 static inline void free_buffer( void *static_buffer
, void *buffer
)
78 if (buffer
!= static_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
81 /* map a Unicode string to a 16-bit pointer */
82 inline static SEGPTR
map_str_32W_to_16( LPCWSTR str
)
87 if (!HIWORD(str
)) return (SEGPTR
)LOWORD(str
);
88 len
= WideCharToMultiByte( CP_ACP
, 0, str
, -1, NULL
, 0, NULL
, NULL
);
89 if ((ret
= HeapAlloc( GetProcessHeap(), 0, len
)))
90 WideCharToMultiByte( CP_ACP
, 0, str
, -1, ret
, len
, NULL
, NULL
);
94 /* unmap a Unicode string that was converted to a 16-bit pointer */
95 inline static void unmap_str_32W_to_16( SEGPTR str
)
97 if (!HIWORD(str
)) return;
98 HeapFree( GetProcessHeap(), 0, MapSL(str
) );
102 /* map a 16-bit pointer to a Unicode string */
103 inline static LPWSTR
map_str_16_to_32W( SEGPTR str
)
108 if (!HIWORD(str
)) return (LPWSTR
)(ULONG_PTR
)LOWORD(str
);
109 len
= MultiByteToWideChar( CP_ACP
, 0, MapSL(str
), -1, NULL
, 0 );
110 if ((ret
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
111 MultiByteToWideChar( CP_ACP
, 0, MapSL(str
), -1, ret
, len
);
115 /* unmap a 16-bit pointer that was converted to a Unicode string */
116 inline static void unmap_str_16_to_32W( LPCWSTR str
)
118 if (HIWORD(str
)) HeapFree( GetProcessHeap(), 0, (void *)str
);
121 /* find an existing winproc for a given 16-bit function and type */
122 /* FIXME: probably should do something more clever than a linear search */
123 static inline WINDOWPROC
*find_winproc16( WNDPROC16 func
)
127 for (i
= 0; i
< winproc_used
; i
++)
129 if (winproc_array
[i
].proc16
== func
) return &winproc_array
[i
];
134 /* find an existing winproc for a given function and type */
135 /* FIXME: probably should do something more clever than a linear search */
136 static inline WINDOWPROC
*find_winproc( WNDPROC funcA
, WNDPROC funcW
)
140 for (i
= 0; i
< winproc_used
; i
++)
142 if (funcA
&& winproc_array
[i
].procA
!= funcA
) continue;
143 if (funcW
&& winproc_array
[i
].procW
!= funcW
) continue;
144 return &winproc_array
[i
];
149 /* return the window proc for a given handle, or NULL for an invalid handle */
150 static inline WINDOWPROC
*handle_to_proc( WNDPROC handle
)
152 UINT index
= LOWORD(handle
);
153 if ((ULONG_PTR
)handle
>> 16 != WINPROC_HANDLE
) return NULL
;
154 if (index
>= winproc_used
) return NULL
;
155 return &winproc_array
[index
];
158 /* create a handle for a given window proc */
159 static inline WNDPROC
proc_to_handle( WINDOWPROC
*proc
)
161 return (WNDPROC
)(ULONG_PTR
)((proc
- winproc_array
) | (WINPROC_HANDLE
<< 16));
164 /* allocate and initialize a new winproc */
165 static inline WINDOWPROC
*alloc_winproc( WNDPROC funcA
, WNDPROC funcW
)
169 /* check if the function is already a win proc */
170 if (funcA
&& (proc
= handle_to_proc( funcA
))) return proc
;
171 if (funcW
&& (proc
= handle_to_proc( funcW
))) return proc
;
172 if (!funcA
&& !funcW
) return NULL
;
174 EnterCriticalSection( &winproc_cs
);
176 /* check if we already have a winproc for that function */
177 if (!(proc
= find_winproc( funcA
, funcW
)))
179 if (winproc_used
< MAX_WINPROCS
)
181 proc
= &winproc_array
[winproc_used
++];
184 TRACE( "allocated %p for %p/%p (%d/%d used)\n",
185 proc_to_handle(proc
), funcA
, funcW
, winproc_used
, MAX_WINPROCS
);
187 else FIXME( "too many winprocs, cannot allocate one for %p/%p\n", funcA
, funcW
);
189 else TRACE( "reusing %p for %p/%p\n", proc_to_handle(proc
), funcA
, funcW
);
191 LeaveCriticalSection( &winproc_cs
);
198 #include "pshpack1.h"
200 /* Window procedure 16-to-32-bit thunk */
203 BYTE popl_eax
; /* popl %eax (return address) */
204 BYTE pushl_func
; /* pushl $proc */
206 BYTE pushl_eax
; /* pushl %eax */
207 BYTE ljmp
; /* ljmp relay*/
208 DWORD relay_offset
; /* __wine_call_wndproc */
214 #define MAX_THUNKS (0x10000 / sizeof(WINPROC_THUNK))
216 static WINPROC_THUNK
*thunk_array
;
217 static UINT thunk_selector
;
218 static UINT thunk_used
;
220 /* return the window proc for a given handle, or NULL for an invalid handle */
221 static inline WINDOWPROC
*handle16_to_proc( WNDPROC16 handle
)
223 if (HIWORD(handle
) == thunk_selector
)
225 UINT index
= LOWORD(handle
) / sizeof(WINPROC_THUNK
);
226 /* check alignment */
227 if (index
* sizeof(WINPROC_THUNK
) != LOWORD(handle
)) return NULL
;
228 /* check array limits */
229 if (index
>= thunk_used
) return NULL
;
230 return thunk_array
[index
].proc
;
232 return handle_to_proc( (WNDPROC
)handle
);
235 /* allocate a 16-bit thunk for an existing window proc */
236 static WNDPROC16
alloc_win16_thunk( WINDOWPROC
*proc
)
238 static FARPROC16 relay
;
241 if (proc
->proc16
) return proc
->proc16
;
243 EnterCriticalSection( &winproc_cs
);
245 if (!thunk_array
) /* allocate the array and its selector */
249 if (!(thunk_selector
= wine_ldt_alloc_entries(1))) goto done
;
250 if (!(thunk_array
= VirtualAlloc( NULL
, MAX_THUNKS
* sizeof(WINPROC_THUNK
), MEM_COMMIT
,
251 PAGE_EXECUTE_READWRITE
))) goto done
;
252 wine_ldt_set_base( &entry
, thunk_array
);
253 wine_ldt_set_limit( &entry
, MAX_THUNKS
* sizeof(WINPROC_THUNK
) - 1 );
254 wine_ldt_set_flags( &entry
, WINE_LDT_FLAGS_CODE
| WINE_LDT_FLAGS_32BIT
);
255 wine_ldt_set_entry( thunk_selector
, &entry
);
256 relay
= GetProcAddress16( GetModuleHandle16("user"), "__wine_call_wndproc" );
259 /* check if it already exists */
260 for (i
= 0; i
< thunk_used
; i
++) if (thunk_array
[i
].proc
== proc
) break;
262 if (i
== thunk_used
) /* create a new one */
264 WINPROC_THUNK
*thunk
;
266 if (thunk_used
>= MAX_THUNKS
) goto done
;
267 thunk
= &thunk_array
[thunk_used
++];
268 thunk
->popl_eax
= 0x58; /* popl %eax */
269 thunk
->pushl_func
= 0x68; /* pushl $proc */
271 thunk
->pushl_eax
= 0x50; /* pushl %eax */
272 thunk
->ljmp
= 0xea; /* ljmp relay*/
273 thunk
->relay_offset
= OFFSETOF(relay
);
274 thunk
->relay_sel
= SELECTOROF(relay
);
276 proc
->proc16
= (WNDPROC16
)MAKESEGPTR( thunk_selector
, i
* sizeof(WINPROC_THUNK
) );
278 LeaveCriticalSection( &winproc_cs
);
284 static inline WINDOWPROC
*handle16_to_proc( WNDPROC16 handle
)
286 return handle_to_proc( (WNDPROC
)handle
);
289 static inline WNDPROC16
alloc_win16_thunk( WINDOWPROC
*proc
)
294 #endif /* __i386__ */
298 /* Some window procedures modify register they shouldn't, or are not
299 * properly declared stdcall; so we need a small assembly wrapper to
301 extern LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
302 WPARAM wParam
, LPARAM lParam
);
303 __ASM_GLOBAL_FUNC( WINPROC_wrapper
,
314 "movl 8(%ebp),%eax\n\t"
316 "leal -12(%ebp),%esp\n\t"
323 static inline LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
324 WPARAM wParam
, LPARAM lParam
)
326 return proc( hwnd
, msg
, wParam
, lParam
);
328 #endif /* __i386__ */
331 static void MINMAXINFO32to16( const MINMAXINFO
*from
, MINMAXINFO16
*to
)
333 to
->ptReserved
.x
= from
->ptReserved
.x
;
334 to
->ptReserved
.y
= from
->ptReserved
.y
;
335 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
336 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
337 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
338 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
339 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
340 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
341 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
342 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
345 static void MINMAXINFO16to32( const MINMAXINFO16
*from
, MINMAXINFO
*to
)
347 to
->ptReserved
.x
= from
->ptReserved
.x
;
348 to
->ptReserved
.y
= from
->ptReserved
.y
;
349 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
350 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
351 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
352 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
353 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
354 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
355 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
356 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
359 static void WINDOWPOS32to16( const WINDOWPOS
* from
, WINDOWPOS16
* to
)
361 to
->hwnd
= HWND_16(from
->hwnd
);
362 to
->hwndInsertAfter
= HWND_16(from
->hwndInsertAfter
);
367 to
->flags
= from
->flags
;
370 static void WINDOWPOS16to32( const WINDOWPOS16
* from
, WINDOWPOS
* to
)
372 to
->hwnd
= WIN_Handle32(from
->hwnd
);
373 to
->hwndInsertAfter
= (from
->hwndInsertAfter
== (HWND16
)-1) ?
374 HWND_TOPMOST
: WIN_Handle32(from
->hwndInsertAfter
);
379 to
->flags
= from
->flags
;
382 /* The strings are not copied */
383 static void CREATESTRUCT32Ato16( const CREATESTRUCTA
* from
, CREATESTRUCT16
* to
)
385 to
->lpCreateParams
= (SEGPTR
)from
->lpCreateParams
;
386 to
->hInstance
= HINSTANCE_16(from
->hInstance
);
387 to
->hMenu
= HMENU_16(from
->hMenu
);
388 to
->hwndParent
= HWND_16(from
->hwndParent
);
393 to
->style
= from
->style
;
394 to
->dwExStyle
= from
->dwExStyle
;
397 static void CREATESTRUCT16to32A( const CREATESTRUCT16
* from
, CREATESTRUCTA
*to
)
400 to
->lpCreateParams
= (LPVOID
)from
->lpCreateParams
;
401 to
->hInstance
= HINSTANCE_32(from
->hInstance
);
402 to
->hMenu
= HMENU_32(from
->hMenu
);
403 to
->hwndParent
= WIN_Handle32(from
->hwndParent
);
408 to
->style
= from
->style
;
409 to
->dwExStyle
= from
->dwExStyle
;
412 /* The strings are not copied */
413 static void MDICREATESTRUCT32Ato16( const MDICREATESTRUCTA
* from
, MDICREATESTRUCT16
* to
)
415 to
->hOwner
= HINSTANCE_16(from
->hOwner
);
420 to
->style
= from
->style
;
421 to
->lParam
= from
->lParam
;
424 static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16
* from
, MDICREATESTRUCTA
*to
)
426 to
->hOwner
= HINSTANCE_32(from
->hOwner
);
431 to
->style
= from
->style
;
432 to
->lParam
= from
->lParam
;
435 static WPARAM
map_wparam_char_AtoW( WPARAM wParam
, DWORD len
)
440 ch
[0] = (wParam
>> 8);
441 ch
[1] = wParam
& 0xff;
442 if (len
> 1 && ch
[0])
443 RtlMultiByteToUnicodeN( &wch
, sizeof(wch
), NULL
, ch
, 2 );
445 RtlMultiByteToUnicodeN( &wch
, sizeof(wch
), NULL
, ch
+ 1, 1 );
446 return MAKEWPARAM( wch
, HIWORD(wParam
) );
449 static WPARAM
map_wparam_char_WtoA( WPARAM wParam
, DWORD len
)
454 RtlUnicodeToMultiByteN( (LPSTR
)ch
, len
, &len
, &wch
, sizeof(wch
) );
456 return MAKEWPARAM( (ch
[0] << 8) | ch
[1], HIWORD(wParam
) );
458 return MAKEWPARAM( ch
[0], HIWORD(wParam
) );
461 /* call a 32-bit window procedure */
462 static LRESULT
call_window_proc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
, LRESULT
*result
, void *arg
)
468 hwnd
= WIN_GetFullHandle( hwnd
);
470 DPRINTF( "%04lx:Call window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
471 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wp
, lp
);
473 *result
= WINPROC_wrapper( proc
, hwnd
, msg
, wp
, lp
);
476 DPRINTF( "%04lx:Ret window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
477 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wp
, lp
, *result
);
481 /* call a 32-bit dialog procedure */
482 static LRESULT
call_dialog_proc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
, LRESULT
*result
, void *arg
)
489 hwnd
= WIN_GetFullHandle( hwnd
);
491 DPRINTF( "%04lx:Call dialog proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
492 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wp
, lp
);
494 ret
= WINPROC_wrapper( proc
, hwnd
, msg
, wp
, lp
);
495 *result
= GetWindowLongPtrW( hwnd
, DWLP_MSGRESULT
);
498 DPRINTF( "%04lx:Ret dialog proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx result=%08lx\n",
499 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wp
, lp
, ret
, *result
);
503 /* call a 16-bit window procedure */
504 static LRESULT
call_window_proc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
505 LRESULT
*result
, void *arg
)
507 WNDPROC16 proc
= arg
;
516 DRAWITEMSTRUCT16 dis16
;
517 COMPAREITEMSTRUCT16 cis16
;
523 /* Window procedures want ax = hInstance, ds = es = ss */
525 memset(&context
, 0, sizeof(context
));
526 context
.SegDs
= context
.SegEs
= SELECTOROF(NtCurrentTeb()->WOW32Reserved
);
527 context
.SegFs
= wine_get_fs();
528 context
.SegGs
= wine_get_gs();
529 if (!(context
.Eax
= GetWindowWord( HWND_32(hwnd
), GWLP_HINSTANCE
))) context
.Eax
= context
.SegDs
;
530 context
.SegCs
= SELECTOROF(proc
);
531 context
.Eip
= OFFSETOF(proc
);
532 context
.Ebp
= OFFSETOF(NtCurrentTeb()->WOW32Reserved
) + (WORD
)&((STACK16FRAME
*)0)->bp
;
536 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
537 work if structures passed in lParam are placed in the stack/data
538 segment. Programmers easily make the mistake of converting lParam
539 to a near rather than a far pointer, since Windows apparently
540 allows this. We copy the structures to the 16 bit stack; this is
541 ugly but makes these programs work. */
546 size
= sizeof(CREATESTRUCT16
); break;
548 size
= sizeof(DRAWITEMSTRUCT16
); break;
550 size
= sizeof(COMPAREITEMSTRUCT16
); break;
554 memcpy( &args
.u
, MapSL(lParam
), size
);
555 lParam
= (SEGPTR
)NtCurrentTeb()->WOW32Reserved
- size
;
559 args
.params
[4] = hwnd
;
560 args
.params
[3] = msg
;
561 args
.params
[2] = wParam
;
562 args
.params
[1] = HIWORD(lParam
);
563 args
.params
[0] = LOWORD(lParam
);
564 WOWCallback16Ex( 0, WCB16_REGS
, sizeof(args
.params
) + size
, &args
, (DWORD
*)&context
);
565 *result
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
569 /* call a 16-bit dialog procedure */
570 static LRESULT
call_dialog_proc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wp
, LPARAM lp
,
571 LRESULT
*result
, void *arg
)
573 LRESULT ret
= call_window_proc16( hwnd
, msg
, wp
, lp
, result
, arg
);
574 *result
= GetWindowLongPtrW( WIN_Handle32(hwnd
), DWLP_MSGRESULT
);
579 /**********************************************************************
582 * Get a window procedure pointer that can be passed to the Windows program.
584 WNDPROC16
WINPROC_GetProc16( WNDPROC proc
, BOOL unicode
)
588 if (unicode
) ptr
= alloc_winproc( NULL
, proc
);
589 else ptr
= alloc_winproc( proc
, NULL
);
592 return alloc_win16_thunk( ptr
);
596 /**********************************************************************
599 * Get a window procedure pointer that can be passed to the Windows program.
601 WNDPROC
WINPROC_GetProc( WNDPROC proc
, BOOL unicode
)
603 WINDOWPROC
*ptr
= handle_to_proc( proc
);
605 if (!ptr
) return proc
;
608 if (ptr
->procW
) return ptr
->procW
;
613 if (ptr
->procA
) return ptr
->procA
;
619 /**********************************************************************
620 * WINPROC_AllocProc16
622 * Allocate a window procedure for a window or class.
624 * Note that allocated winprocs are never freed; the idea is that even if an app creates a
625 * lot of windows, it will usually only have a limited number of window procedures, so the
626 * array won't grow too large, and this way we avoid the need to track allocations per window.
628 WNDPROC
WINPROC_AllocProc16( WNDPROC16 func
)
632 if (!func
) return NULL
;
634 /* check if the function is already a win proc */
635 if (!(proc
= handle16_to_proc( func
)))
637 EnterCriticalSection( &winproc_cs
);
639 /* then check if we already have a winproc for that function */
640 if (!(proc
= find_winproc16( func
)))
642 if (winproc_used
< MAX_WINPROCS
)
644 proc
= &winproc_array
[winproc_used
++];
646 TRACE( "allocated %p for %p/16-bit (%d/%d used)\n",
647 proc_to_handle(proc
), func
, winproc_used
, MAX_WINPROCS
);
649 else FIXME( "too many winprocs, cannot allocate one for 16-bit %p\n", func
);
651 else TRACE( "reusing %p for %p/16-bit\n", proc_to_handle(proc
), func
);
653 LeaveCriticalSection( &winproc_cs
);
655 return proc_to_handle( proc
);
659 /**********************************************************************
662 * Allocate a window procedure for a window or class.
664 * Note that allocated winprocs are never freed; the idea is that even if an app creates a
665 * lot of windows, it will usually only have a limited number of window procedures, so the
666 * array won't grow too large, and this way we avoid the need to track allocations per window.
668 WNDPROC
WINPROC_AllocProc( WNDPROC funcA
, WNDPROC funcW
)
672 if (!(proc
= alloc_winproc( funcA
, funcW
))) return NULL
;
673 return proc_to_handle( proc
);
677 /**********************************************************************
680 * Return the window procedure type, or the default value if not a winproc handle.
682 BOOL
WINPROC_IsUnicode( WNDPROC proc
, BOOL def_val
)
684 WINDOWPROC
*ptr
= handle_to_proc( proc
);
686 if (!ptr
) return def_val
;
687 if (ptr
->procA
&& ptr
->procW
) return def_val
; /* can be both */
688 return (ptr
->procW
!= NULL
);
692 /**********************************************************************
693 * WINPROC_TestLBForStr
695 * Return TRUE if the lparam is a string
697 inline static BOOL
WINPROC_TestLBForStr( HWND hwnd
, UINT msg
)
699 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
700 if (msg
<= CB_MSGMAX
)
701 return (!(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) || (style
& CBS_HASSTRINGS
));
703 return (!(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) || (style
& LBS_HASSTRINGS
));
708 static UINT
convert_handle_16_to_32(HANDLE16 src
, unsigned int flags
)
711 UINT sz
= GlobalSize16(src
);
714 if (!(dst
= GlobalAlloc(flags
, sz
)))
716 ptr16
= GlobalLock16(src
);
717 ptr32
= GlobalLock(dst
);
718 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr32
, ptr16
, sz
);
725 /**********************************************************************
726 * WINPROC_MapMsg16To32A
728 * Map a message from 16- to 32-bit Ansi.
729 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
731 static INT
WINPROC_MapMsg16To32A( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
732 WPARAM
*pwparam32
, LPARAM
*plparam
)
734 *pmsg32
= (UINT
)msg16
;
735 *pwparam32
= (WPARAM
)wParam16
;
742 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
743 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
747 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
748 *plparam
= (LPARAM
)WIN_Handle32( HIWORD(*plparam
) );
751 if ( HIWORD(*plparam
) > CTLCOLOR_STATIC
) return -1;
752 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
753 *pwparam32
= (WPARAM
)HDC_32(wParam16
);
754 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
758 COMPAREITEMSTRUCT16
* cis16
= MapSL(*plparam
);
759 COMPAREITEMSTRUCT
*cis
= HeapAlloc(GetProcessHeap(), 0, sizeof(*cis
));
761 cis
->CtlType
= cis16
->CtlType
;
762 cis
->CtlID
= cis16
->CtlID
;
763 cis
->hwndItem
= WIN_Handle32( cis16
->hwndItem
);
764 cis
->itemID1
= cis16
->itemID1
;
765 cis
->itemData1
= cis16
->itemData1
;
766 cis
->itemID2
= cis16
->itemID2
;
767 cis
->itemData2
= cis16
->itemData2
;
768 cis
->dwLocaleId
= 0; /* FIXME */
769 *plparam
= (LPARAM
)cis
;
774 PCOPYDATASTRUCT16 pcds16
= MapSL(*plparam
);
775 PCOPYDATASTRUCT pcds
= HeapAlloc ( GetProcessHeap(), 0, sizeof(*pcds
));
776 pcds
->dwData
= pcds16
->dwData
;
777 pcds
->cbData
= pcds16
->cbData
;
778 pcds
->lpData
= MapSL( pcds16
->lpData
);
779 *plparam
= (LPARAM
)pcds
;
784 DELETEITEMSTRUCT16
* dis16
= MapSL(*plparam
);
785 DELETEITEMSTRUCT
*dis
= HeapAlloc(GetProcessHeap(), 0, sizeof(*dis
));
787 dis
->CtlType
= dis16
->CtlType
;
788 dis
->CtlID
= dis16
->CtlID
;
789 dis
->hwndItem
= WIN_Handle32( dis16
->hwndItem
);
790 dis
->itemData
= dis16
->itemData
;
791 *plparam
= (LPARAM
)dis
;
796 MEASUREITEMSTRUCT16
* mis16
= MapSL(*plparam
);
797 MEASUREITEMSTRUCT
*mis
= HeapAlloc(GetProcessHeap(), 0,
798 sizeof(*mis
) + sizeof(LPARAM
));
800 mis
->CtlType
= mis16
->CtlType
;
801 mis
->CtlID
= mis16
->CtlID
;
802 mis
->itemID
= mis16
->itemID
;
803 mis
->itemWidth
= mis16
->itemWidth
;
804 mis
->itemHeight
= mis16
->itemHeight
;
805 mis
->itemData
= mis16
->itemData
;
806 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
807 *plparam
= (LPARAM
)mis
;
812 DRAWITEMSTRUCT16
* dis16
= MapSL(*plparam
);
813 DRAWITEMSTRUCT
*dis
= HeapAlloc(GetProcessHeap(), 0, sizeof(*dis
));
815 dis
->CtlType
= dis16
->CtlType
;
816 dis
->CtlID
= dis16
->CtlID
;
817 dis
->itemID
= dis16
->itemID
;
818 dis
->itemAction
= dis16
->itemAction
;
819 dis
->itemState
= dis16
->itemState
;
820 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND
)HMENU_32(dis16
->hwndItem
)
821 : WIN_Handle32( dis16
->hwndItem
);
822 dis
->hDC
= HDC_32(dis16
->hDC
);
823 dis
->itemData
= dis16
->itemData
;
824 dis
->rcItem
.left
= dis16
->rcItem
.left
;
825 dis
->rcItem
.top
= dis16
->rcItem
.top
;
826 dis
->rcItem
.right
= dis16
->rcItem
.right
;
827 dis
->rcItem
.bottom
= dis16
->rcItem
.bottom
;
828 *plparam
= (LPARAM
)dis
;
831 case WM_GETMINMAXINFO
:
833 MINMAXINFO
*mmi
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi
) + sizeof(LPARAM
));
835 MINMAXINFO16to32( MapSL(*plparam
), mmi
);
836 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
837 *plparam
= (LPARAM
)mmi
;
842 case WM_WININICHANGE
:
843 case WM_DEVMODECHANGE
:
844 case WM_ASKCBFORMATNAME
:
845 *plparam
= (LPARAM
)MapSL(*plparam
);
849 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
850 MDICREATESTRUCTA
*cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) + sizeof(LPARAM
) );
852 MDICREATESTRUCT16to32A( cs16
, cs
);
853 cs
->szTitle
= MapSL(cs16
->szTitle
);
854 cs
->szClass
= MapSL(cs16
->szClass
);
855 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
856 *plparam
= (LPARAM
)cs
;
859 case WM_MDIGETACTIVE
:
860 *plparam
= (LPARAM
)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL
) );
861 *(BOOL
*)(*plparam
) = 0;
864 if(wParam16
) *pmsg32
=WM_MDIREFRESHMENU
;
865 *pwparam32
= (WPARAM
)HMENU_32(LOWORD(*plparam
));
866 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
869 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
870 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
873 if((LOWORD(*plparam
) & MF_POPUP
) && (LOWORD(*plparam
) != 0xFFFF))
875 HMENU hmenu
=HMENU_32(HIWORD(*plparam
));
876 UINT Pos
=MENU_FindSubMenu( &hmenu
, HMENU_32(wParam16
));
877 if(Pos
==0xFFFF) Pos
=0; /* NO_SELECTED_ITEM */
878 *pwparam32
= MAKEWPARAM( Pos
, LOWORD(*plparam
) );
880 else *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
881 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
886 *pwparam32
= (WPARAM
)WIN_Handle32( HIWORD(*plparam
) );
887 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
889 else /* message sent to MDI client */
890 *pwparam32
= wParam16
;
894 NCCALCSIZE_PARAMS16
*nc16
;
895 NCCALCSIZE_PARAMS
*nc
;
897 nc
= HeapAlloc( GetProcessHeap(), 0, sizeof(*nc
) + sizeof(LPARAM
) );
899 nc16
= MapSL(*plparam
);
900 nc
->rgrc
[0].left
= nc16
->rgrc
[0].left
;
901 nc
->rgrc
[0].top
= nc16
->rgrc
[0].top
;
902 nc
->rgrc
[0].right
= nc16
->rgrc
[0].right
;
903 nc
->rgrc
[0].bottom
= nc16
->rgrc
[0].bottom
;
906 nc
->lppos
= HeapAlloc( GetProcessHeap(), 0, sizeof(*nc
->lppos
) );
907 nc
->rgrc
[1].left
= nc16
->rgrc
[1].left
;
908 nc
->rgrc
[1].top
= nc16
->rgrc
[1].top
;
909 nc
->rgrc
[1].right
= nc16
->rgrc
[1].right
;
910 nc
->rgrc
[1].bottom
= nc16
->rgrc
[1].bottom
;
911 nc
->rgrc
[2].left
= nc16
->rgrc
[2].left
;
912 nc
->rgrc
[2].top
= nc16
->rgrc
[2].top
;
913 nc
->rgrc
[2].right
= nc16
->rgrc
[2].right
;
914 nc
->rgrc
[2].bottom
= nc16
->rgrc
[2].bottom
;
915 if (nc
->lppos
) WINDOWPOS16to32( MapSL(nc16
->lppos
), nc
->lppos
);
917 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
918 *plparam
= (LPARAM
)nc
;
924 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
925 CREATESTRUCTA
*cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) + sizeof(LPARAM
) );
927 CREATESTRUCT16to32A( cs16
, cs
);
928 cs
->lpszName
= MapSL(cs16
->lpszName
);
929 cs
->lpszClass
= MapSL(cs16
->lpszClass
);
931 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
933 MDICREATESTRUCT16
*mdi_cs16
;
934 MDICREATESTRUCTA
*mdi_cs
= HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs
));
937 HeapFree(GetProcessHeap(), 0, cs
);
940 mdi_cs16
= (MDICREATESTRUCT16
*)MapSL(cs16
->lpCreateParams
);
941 MDICREATESTRUCT16to32A(mdi_cs16
, mdi_cs
);
942 mdi_cs
->szTitle
= MapSL(mdi_cs16
->szTitle
);
943 mdi_cs
->szClass
= MapSL(mdi_cs16
->szClass
);
945 cs
->lpCreateParams
= mdi_cs
;
947 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
948 *plparam
= (LPARAM
)cs
;
951 case WM_PARENTNOTIFY
:
952 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
954 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
955 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
958 case WM_WINDOWPOSCHANGING
:
959 case WM_WINDOWPOSCHANGED
:
961 WINDOWPOS
*wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(*wp
) + sizeof(LPARAM
) );
963 WINDOWPOS16to32( MapSL(*plparam
), wp
);
964 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
965 *plparam
= (LPARAM
)wp
;
971 LPMSG16 msg16
= MapSL(*plparam
);
972 LPMSG msg32
= HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
974 if (!msg32
) return -1;
975 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
976 msg32
->message
= msg16
->message
;
977 msg32
->wParam
= msg16
->wParam
;
978 msg32
->lParam
= msg16
->lParam
;
979 msg32
->time
= msg16
->time
;
980 msg32
->pt
.x
= msg16
->pt
.x
;
981 msg32
->pt
.y
= msg16
->pt
.y
;
982 *plparam
= (LPARAM
)msg32
;
987 *plparam
= (LPARAM
)MapSL(*plparam
);
990 /* We need this when SetActiveWindow sends a Sendmessage16() to
991 * a 32bit window. Might be superflous with 32bit interprocess
993 if (*plparam
) *plparam
= HTASK_32( *plparam
);
997 MDINEXTMENU
*next
= HeapAlloc( GetProcessHeap(), 0, sizeof(*next
) );
998 if (!next
) return -1;
999 next
->hmenuIn
= (HMENU
)*plparam
;
1000 next
->hmenuNext
= 0;
1002 *plparam
= (LPARAM
)next
;
1005 case WM_PAINTCLIPBOARD
:
1006 case WM_SIZECLIPBOARD
:
1007 FIXME_(msg
)("message %04x needs translation\n",msg16
);
1009 case WM_DDE_INITIATE
:
1010 case WM_DDE_TERMINATE
:
1011 case WM_DDE_UNADVISE
:
1012 case WM_DDE_REQUEST
:
1013 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1023 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1024 lo16
= LOWORD(*plparam
);
1025 hi
= HIWORD(*plparam
);
1026 if (lo16
&& !(lo32
= convert_handle_16_to_32(lo16
, GMEM_DDESHARE
)))
1028 *plparam
= PackDDElParam(msg16
, lo32
, hi
);
1030 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1037 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1039 lo
= LOWORD(*plparam
);
1040 hi
= HIWORD(*plparam
);
1042 if (GlobalGetAtomNameA(hi
, buf
, 2) > 0) flag
|= 1;
1043 if (GlobalSize16(hi
) != 0) flag
|= 2;
1049 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1054 break; /* atom, nothing to do */
1056 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
1059 hi
= convert_handle_16_to_32(hi
, GMEM_DDESHARE
);
1062 *plparam
= PackDDElParam(WM_DDE_ACK
, lo
, hi
);
1064 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1065 case WM_DDE_EXECUTE
:
1066 *plparam
= convert_handle_16_to_32(*plparam
, GMEM_DDESHARE
);
1067 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1068 default: /* No translation needed */
1074 /**********************************************************************
1075 * WINPROC_UnmapMsg16To32A
1077 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1079 static LRESULT
WINPROC_UnmapMsg16To32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1084 case WM_COMPAREITEM
:
1088 HeapFree( GetProcessHeap(), 0, (LPVOID
)lParam
);
1090 case WM_MEASUREITEM
:
1092 MEASUREITEMSTRUCT16
*mis16
;
1093 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)lParam
;
1094 lParam
= *(LPARAM
*)(mis
+ 1);
1095 mis16
= MapSL(lParam
);
1096 mis16
->itemWidth
= (UINT16
)mis
->itemWidth
;
1097 mis16
->itemHeight
= (UINT16
)mis
->itemHeight
;
1098 HeapFree( GetProcessHeap(), 0, mis
);
1101 case WM_GETMINMAXINFO
:
1103 MINMAXINFO
*mmi
= (MINMAXINFO
*)lParam
;
1104 lParam
= *(LPARAM
*)(mmi
+ 1);
1105 MINMAXINFO32to16( mmi
, MapSL(lParam
));
1106 HeapFree( GetProcessHeap(), 0, mmi
);
1111 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1112 lParam
= *(LPARAM
*)(cs
+ 1);
1113 MDICREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1114 HeapFree( GetProcessHeap(), 0, cs
);
1117 case WM_MDIGETACTIVE
:
1118 result
= MAKELONG( LOWORD(result
), (BOOL16
)(*(BOOL
*)lParam
) );
1119 HeapFree( GetProcessHeap(), 0, (BOOL
*)lParam
);
1123 NCCALCSIZE_PARAMS16
*nc16
;
1124 NCCALCSIZE_PARAMS
*nc
= (NCCALCSIZE_PARAMS
*)lParam
;
1125 lParam
= *(LPARAM
*)(nc
+ 1);
1126 nc16
= MapSL(lParam
);
1127 nc16
->rgrc
[0].left
= nc
->rgrc
[0].left
;
1128 nc16
->rgrc
[0].top
= nc
->rgrc
[0].top
;
1129 nc16
->rgrc
[0].right
= nc
->rgrc
[0].right
;
1130 nc16
->rgrc
[0].bottom
= nc
->rgrc
[0].bottom
;
1133 nc16
->rgrc
[1].left
= nc
->rgrc
[1].left
;
1134 nc16
->rgrc
[1].top
= nc
->rgrc
[1].top
;
1135 nc16
->rgrc
[1].right
= nc
->rgrc
[1].right
;
1136 nc16
->rgrc
[1].bottom
= nc
->rgrc
[1].bottom
;
1137 nc16
->rgrc
[2].left
= nc
->rgrc
[2].left
;
1138 nc16
->rgrc
[2].top
= nc
->rgrc
[2].top
;
1139 nc16
->rgrc
[2].right
= nc
->rgrc
[2].right
;
1140 nc16
->rgrc
[2].bottom
= nc
->rgrc
[2].bottom
;
1143 WINDOWPOS32to16( nc
->lppos
, MapSL(nc16
->lppos
));
1144 HeapFree( GetProcessHeap(), 0, nc
->lppos
);
1147 HeapFree( GetProcessHeap(), 0, nc
);
1153 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1154 lParam
= *(LPARAM
*)(cs
+ 1);
1155 CREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1157 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
1158 HeapFree(GetProcessHeap(), 0, cs
->lpCreateParams
);
1160 HeapFree( GetProcessHeap(), 0, cs
);
1163 case WM_WINDOWPOSCHANGING
:
1164 case WM_WINDOWPOSCHANGED
:
1166 WINDOWPOS
*wp
= (WINDOWPOS
*)lParam
;
1167 lParam
= *(LPARAM
*)(wp
+ 1);
1168 WINDOWPOS32to16(wp
, MapSL(lParam
));
1169 HeapFree( GetProcessHeap(), 0, wp
);
1175 LPMSG msg32
= (LPMSG
)lParam
;
1176 HeapFree( GetProcessHeap(), 0, msg32
);
1181 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1182 result
= MAKELONG( HMENU_16(next
->hmenuNext
), HWND_16(next
->hwndNext
) );
1183 HeapFree( GetProcessHeap(), 0, next
);
1191 /**********************************************************************
1192 * WINPROC_MapMsg16To32W
1194 * Map a message from 16- to 32-bit Unicode.
1195 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1197 static INT
WINPROC_MapMsg16To32W( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1198 WPARAM
*pwparam32
, LPARAM
*plparam
)
1200 *pmsg32
=(UINT
)msg16
;
1201 *pwparam32
= (WPARAM
)wParam16
;
1207 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1208 CREATESTRUCTW
*cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) + sizeof(LPARAM
) );
1210 CREATESTRUCT16to32A( cs16
, (CREATESTRUCTA
*)cs
);
1211 cs
->lpszName
= map_str_16_to_32W(cs16
->lpszName
);
1212 cs
->lpszClass
= map_str_16_to_32W(cs16
->lpszClass
);
1214 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
1216 MDICREATESTRUCT16
*mdi_cs16
;
1217 MDICREATESTRUCTW
*mdi_cs
= HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs
));
1220 HeapFree(GetProcessHeap(), 0, cs
);
1223 mdi_cs16
= (MDICREATESTRUCT16
*)MapSL(cs16
->lpCreateParams
);
1224 MDICREATESTRUCT16to32A(mdi_cs16
, (MDICREATESTRUCTA
*)mdi_cs
);
1225 mdi_cs
->szTitle
= map_str_16_to_32W(mdi_cs16
->szTitle
);
1226 mdi_cs
->szClass
= map_str_16_to_32W(mdi_cs16
->szClass
);
1228 cs
->lpCreateParams
= mdi_cs
;
1230 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1231 *plparam
= (LPARAM
)cs
;
1236 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1237 MDICREATESTRUCTW
*cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) + sizeof(LPARAM
) );
1239 MDICREATESTRUCT16to32A( cs16
, (MDICREATESTRUCTA
*)cs
);
1240 cs
->szTitle
= map_str_16_to_32W(cs16
->szTitle
);
1241 cs
->szClass
= map_str_16_to_32W(cs16
->szClass
);
1242 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1243 *plparam
= (LPARAM
)cs
;
1249 LPMSG16 msg16
= MapSL(*plparam
);
1250 LPMSG msg32
= HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1252 if (!msg32
) return -1;
1253 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1254 msg32
->message
= msg16
->message
;
1255 msg32
->wParam
= msg16
->wParam
;
1256 msg32
->lParam
= msg16
->lParam
;
1257 msg32
->time
= msg16
->time
;
1258 msg32
->pt
.x
= msg16
->pt
.x
;
1259 msg32
->pt
.y
= msg16
->pt
.y
;
1260 switch(msg32
->message
)
1265 case WM_SYSDEADCHAR
:
1266 msg32
->wParam
= map_wparam_char_AtoW( msg16
->wParam
, 1 );
1269 *plparam
= (LPARAM
)msg32
;
1275 *pwparam32
= MAKEWPARAM( map_wparam_char_AtoW( wParam16
, 1 ), HIWORD(*plparam
) );
1276 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1279 *pwparam32
= MAKEWPARAM( map_wparam_char_AtoW( wParam16
, 1 ), LOWORD(*plparam
) );
1280 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1285 case WM_SYSDEADCHAR
:
1286 *pwparam32
= map_wparam_char_AtoW( wParam16
, 1 );
1289 *pwparam32
= map_wparam_char_AtoW( wParam16
, 2 );
1292 default: /* No Unicode translation needed */
1293 return WINPROC_MapMsg16To32A( hwnd
, msg16
, wParam16
, pmsg32
,
1294 pwparam32
, plparam
);
1299 /**********************************************************************
1300 * WINPROC_UnmapMsg16To32W
1302 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1304 static LRESULT
WINPROC_UnmapMsg16To32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1312 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)lParam
;
1313 lParam
= *(LPARAM
*)(cs
+ 1);
1314 CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs
, MapSL(lParam
) );
1315 unmap_str_16_to_32W( cs
->lpszName
);
1316 unmap_str_16_to_32W( cs
->lpszClass
);
1318 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
1320 MDICREATESTRUCTW
*mdi_cs
= (MDICREATESTRUCTW
*)cs
->lpCreateParams
;
1321 unmap_str_16_to_32W( mdi_cs
->szTitle
);
1322 unmap_str_16_to_32W( mdi_cs
->szClass
);
1323 HeapFree(GetProcessHeap(), 0, cs
->lpCreateParams
);
1325 HeapFree( GetProcessHeap(), 0, cs
);
1330 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
1331 lParam
= *(LPARAM
*)(cs
+ 1);
1332 MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs
, MapSL(lParam
) );
1333 unmap_str_16_to_32W( cs
->szTitle
);
1334 unmap_str_16_to_32W( cs
->szClass
);
1335 HeapFree( GetProcessHeap(), 0, cs
);
1341 LPMSG msg32
= (LPMSG
)lParam
;
1342 HeapFree( GetProcessHeap(), 0, msg32
);
1346 return WINPROC_UnmapMsg16To32A( hwnd
, msg
, wParam
, lParam
, result
);
1351 static HANDLE16
convert_handle_32_to_16(UINT src
, unsigned int flags
)
1354 UINT sz
= GlobalSize((HANDLE
)src
);
1357 if (!(dst
= GlobalAlloc16(flags
, sz
)))
1359 ptr32
= GlobalLock((HANDLE
)src
);
1360 ptr16
= GlobalLock16(dst
);
1361 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr16
, ptr32
, sz
);
1362 GlobalUnlock((HANDLE
)src
);
1363 GlobalUnlock16(dst
);
1369 /**********************************************************************
1370 * WINPROC_MapMsg32ATo16
1372 * Map a message from 32-bit Ansi to 16-bit.
1373 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1375 static INT
WINPROC_MapMsg32ATo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
1376 UINT16
*pmsg16
, WPARAM16
*pwparam16
, LPARAM
*plparam
)
1378 *pmsg16
= (UINT16
)msg32
;
1379 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1383 *pmsg16
= SBM_SETRANGE16
;
1384 *plparam
= MAKELPARAM(wParam32
, *plparam
);
1389 *pmsg16
= SBM_GETRANGE16
;
1397 *pmsg16
= (UINT16
)msg32
+ (BM_GETCHECK16
- BM_GETCHECK
);
1406 case EM_SCROLLCARET
:
1409 case EM_GETLINECOUNT
:
1421 case EM_LINEFROMCHAR
:
1422 case EM_SETTABSTOPS
:
1423 case EM_SETPASSWORDCHAR
:
1424 case EM_EMPTYUNDOBUFFER
:
1425 case EM_GETFIRSTVISIBLELINE
:
1426 case EM_SETREADONLY
:
1427 case EM_SETWORDBREAKPROC
:
1428 case EM_GETWORDBREAKPROC
:
1429 case EM_GETPASSWORDCHAR
:
1430 *pmsg16
= (UINT16
)msg32
+ (EM_GETSEL16
- EM_GETSEL
);
1435 case LB_DELETESTRING
:
1436 case LB_GETANCHORINDEX
:
1437 case LB_GETCARETINDEX
:
1440 case LB_GETHORIZONTALEXTENT
:
1441 case LB_GETITEMDATA
:
1442 case LB_GETITEMHEIGHT
:
1444 case LB_GETSELCOUNT
:
1446 case LB_GETTOPINDEX
:
1447 case LB_RESETCONTENT
:
1448 case LB_SELITEMRANGE
:
1449 case LB_SELITEMRANGEEX
:
1450 case LB_SETANCHORINDEX
:
1451 case LB_SETCARETINDEX
:
1452 case LB_SETCOLUMNWIDTH
:
1454 case LB_SETHORIZONTALEXTENT
:
1455 case LB_SETITEMDATA
:
1456 case LB_SETITEMHEIGHT
:
1458 case LB_SETTOPINDEX
:
1459 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1461 case CB_DELETESTRING
:
1463 case CB_GETLBTEXTLEN
:
1465 case CB_RESETCONTENT
:
1469 case CB_SHOWDROPDOWN
:
1470 case CB_SETITEMDATA
:
1471 case CB_SETITEMHEIGHT
:
1472 case CB_GETITEMHEIGHT
:
1473 case CB_SETEXTENDEDUI
:
1474 case CB_GETEXTENDEDUI
:
1475 case CB_GETDROPPEDSTATE
:
1476 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1479 *pmsg16
= CB_GETEDITSEL16
;
1484 case LB_FINDSTRINGEXACT
:
1485 case LB_INSERTSTRING
:
1486 case LB_SELECTSTRING
:
1489 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1490 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1495 case CB_FINDSTRINGEXACT
:
1496 case CB_INSERTSTRING
:
1497 case CB_SELECTSTRING
:
1499 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1500 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1503 case LB_GETITEMRECT
:
1505 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1506 if (!rect
) return -1;
1507 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1508 *plparam
= MapLS( rect
);
1510 *pmsg16
= LB_GETITEMRECT16
;
1512 case LB_GETSELITEMS
:
1514 LPARAM
*items
; /* old LPARAM first, then *pwparam16 x INT16 entries */
1516 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1517 if (!(items
= HeapAlloc( GetProcessHeap(), 0,
1518 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1519 *items
++ = *plparam
; /* Store the previous lParam */
1520 *plparam
= MapLS( items
);
1522 *pmsg16
= LB_GETSELITEMS16
;
1524 case LB_SETTABSTOPS
:
1529 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1530 if (!(stops
= HeapAlloc( GetProcessHeap(), 0,
1531 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1532 for (i
= 0; i
< *pwparam16
; i
++) stops
[i
] = *((LPINT
)*plparam
+i
);
1533 *plparam
= MapLS( stops
);
1536 *pmsg16
= LB_SETTABSTOPS16
;
1539 case CB_GETDROPPEDCONTROLRECT
:
1541 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1542 if (!rect
) return -1;
1543 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1544 *plparam
= (LPARAM
)MapLS(rect
);
1546 *pmsg16
= CB_GETDROPPEDCONTROLRECT16
;
1550 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1551 *pmsg16
= LB_GETTEXT16
;
1555 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1556 *pmsg16
= CB_GETLBTEXT16
;
1561 *plparam
= MAKELONG( (INT16
)(INT
)wParam32
, (INT16
)*plparam
);
1562 *pmsg16
= EM_SETSEL16
;
1569 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
1573 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
1577 PCOPYDATASTRUCT pcds32
= (PCOPYDATASTRUCT
) *plparam
;
1578 PCOPYDATASTRUCT16 pcds
= HeapAlloc( GetProcessHeap(), 0, sizeof( *pcds
));
1579 pcds
->dwData
= pcds32
->dwData
;
1580 pcds
->cbData
= pcds32
->cbData
;
1581 pcds
->lpData
= MapLS( pcds32
->lpData
);
1582 *plparam
= MapLS( pcds
);
1585 case WM_CTLCOLORMSGBOX
:
1586 case WM_CTLCOLOREDIT
:
1587 case WM_CTLCOLORLISTBOX
:
1588 case WM_CTLCOLORBTN
:
1589 case WM_CTLCOLORDLG
:
1590 case WM_CTLCOLORSCROLLBAR
:
1591 case WM_CTLCOLORSTATIC
:
1592 *pmsg16
= WM_CTLCOLOR
;
1593 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
1594 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
1596 case WM_COMPAREITEM
:
1598 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)*plparam
;
1599 COMPAREITEMSTRUCT16
*cis
= HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16
));
1600 if (!cis
) return -1;
1601 cis
->CtlType
= (UINT16
)cis32
->CtlType
;
1602 cis
->CtlID
= (UINT16
)cis32
->CtlID
;
1603 cis
->hwndItem
= HWND_16( cis32
->hwndItem
);
1604 cis
->itemID1
= (UINT16
)cis32
->itemID1
;
1605 cis
->itemData1
= cis32
->itemData1
;
1606 cis
->itemID2
= (UINT16
)cis32
->itemID2
;
1607 cis
->itemData2
= cis32
->itemData2
;
1608 *plparam
= MapLS( cis
);
1613 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)*plparam
;
1614 DELETEITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16
) );
1615 if (!dis
) return -1;
1616 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1617 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1618 dis
->itemID
= (UINT16
)dis32
->itemID
;
1619 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
1620 : HWND_16( dis32
->hwndItem
);
1621 dis
->itemData
= dis32
->itemData
;
1622 *plparam
= MapLS( dis
);
1627 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)*plparam
;
1628 DRAWITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16
) );
1629 if (!dis
) return -1;
1630 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1631 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1632 dis
->itemID
= (UINT16
)dis32
->itemID
;
1633 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
1634 dis
->itemState
= (UINT16
)dis32
->itemState
;
1635 dis
->hwndItem
= HWND_16( dis32
->hwndItem
);
1636 dis
->hDC
= HDC_16(dis32
->hDC
);
1637 dis
->itemData
= dis32
->itemData
;
1638 dis
->rcItem
.left
= dis32
->rcItem
.left
;
1639 dis
->rcItem
.top
= dis32
->rcItem
.top
;
1640 dis
->rcItem
.right
= dis32
->rcItem
.right
;
1641 dis
->rcItem
.bottom
= dis32
->rcItem
.bottom
;
1642 *plparam
= MapLS( dis
);
1645 case WM_MEASUREITEM
:
1647 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)*plparam
;
1648 MEASUREITEMSTRUCT16
*mis
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mis
)+sizeof(LPARAM
));
1649 if (!mis
) return -1;
1650 mis
->CtlType
= (UINT16
)mis32
->CtlType
;
1651 mis
->CtlID
= (UINT16
)mis32
->CtlID
;
1652 mis
->itemID
= (UINT16
)mis32
->itemID
;
1653 mis
->itemWidth
= (UINT16
)mis32
->itemWidth
;
1654 mis
->itemHeight
= (UINT16
)mis32
->itemHeight
;
1655 mis
->itemData
= mis32
->itemData
;
1656 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1657 *plparam
= MapLS( mis
);
1660 case WM_GETMINMAXINFO
:
1662 MINMAXINFO16
*mmi
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi
) + sizeof(LPARAM
) );
1663 if (!mmi
) return -1;
1664 MINMAXINFO32to16( (MINMAXINFO
*)*plparam
, mmi
);
1665 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1666 *plparam
= MapLS( mmi
);
1670 case WM_ASKCBFORMATNAME
:
1672 LPARAM
*str
; /* store LPARAM, then *pwparam16 char space */
1673 *pwparam16
= (WPARAM16
)min( wParam32
, 0xff80 ); /* Must be < 64K */
1674 if (!(str
= HeapAlloc( GetProcessHeap(), 0, *pwparam16
+ sizeof(LPARAM
)))) return -1;
1675 *str
++ = *plparam
; /* Store the previous lParam */
1676 *plparam
= MapLS( str
);
1681 MDICREATESTRUCT16
*cs
;
1682 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)*plparam
;
1684 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
1685 MDICREATESTRUCT32Ato16( cs32
, cs
);
1686 cs
->szTitle
= MapLS( cs32
->szTitle
);
1687 cs
->szClass
= MapLS( cs32
->szClass
);
1688 *plparam
= MapLS( cs
);
1691 case WM_MDIGETACTIVE
:
1694 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
1695 (HMENU16
)LOWORD(*plparam
) );
1696 *pwparam16
= (*plparam
== 0);
1699 if(HIWORD(wParam32
) & MF_POPUP
)
1702 if (((UINT
)HIWORD(wParam32
) != 0xFFFF) || (*plparam
))
1704 if((hmenu
= GetSubMenu((HMENU
)*plparam
, *pwparam16
)))
1705 *pwparam16
=HMENU_16(hmenu
);
1710 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
1712 case WM_MDIACTIVATE
:
1713 if (GetWindowLongW( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
1715 *pwparam16
= ((HWND
)*plparam
== hwnd
);
1716 *plparam
= MAKELPARAM( (HWND16
)LOWORD(*plparam
),
1717 (HWND16
)LOWORD(wParam32
) );
1721 *pwparam16
= HWND_16( (HWND
)wParam32
);
1727 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)*plparam
;
1728 NCCALCSIZE_PARAMS16
*nc
= HeapAlloc( GetProcessHeap(), 0, sizeof(*nc
) + sizeof(LPARAM
));
1731 nc
->rgrc
[0].left
= nc32
->rgrc
[0].left
;
1732 nc
->rgrc
[0].top
= nc32
->rgrc
[0].top
;
1733 nc
->rgrc
[0].right
= nc32
->rgrc
[0].right
;
1734 nc
->rgrc
[0].bottom
= nc32
->rgrc
[0].bottom
;
1738 nc
->rgrc
[1].left
= nc32
->rgrc
[1].left
;
1739 nc
->rgrc
[1].top
= nc32
->rgrc
[1].top
;
1740 nc
->rgrc
[1].right
= nc32
->rgrc
[1].right
;
1741 nc
->rgrc
[1].bottom
= nc32
->rgrc
[1].bottom
;
1742 nc
->rgrc
[2].left
= nc32
->rgrc
[2].left
;
1743 nc
->rgrc
[2].top
= nc32
->rgrc
[2].top
;
1744 nc
->rgrc
[2].right
= nc32
->rgrc
[2].right
;
1745 nc
->rgrc
[2].bottom
= nc32
->rgrc
[2].bottom
;
1746 if (!(wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16
) )))
1748 HeapFree( GetProcessHeap(), 0, nc
);
1751 WINDOWPOS32to16( nc32
->lppos
, wp
);
1752 nc
->lppos
= MapLS( wp
);
1754 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1755 *plparam
= MapLS( nc
);
1762 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)*plparam
;
1764 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
1765 CREATESTRUCT32Ato16( cs32
, cs
);
1766 cs
->lpszName
= MapLS( cs32
->lpszName
);
1767 cs
->lpszClass
= MapLS( cs32
->lpszClass
);
1769 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
1771 MDICREATESTRUCT16
*mdi_cs16
;
1772 MDICREATESTRUCTA
*mdi_cs
= (MDICREATESTRUCTA
*)cs32
->lpCreateParams
;
1773 mdi_cs16
= HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs16
));
1776 HeapFree(GetProcessHeap(), 0, cs
);
1779 MDICREATESTRUCT32Ato16(mdi_cs
, mdi_cs16
);
1780 mdi_cs16
->szTitle
= MapLS( mdi_cs
->szTitle
);
1781 mdi_cs16
->szClass
= MapLS( mdi_cs
->szClass
);
1782 cs
->lpCreateParams
= MapLS( mdi_cs16
);
1784 *plparam
= MapLS( cs
);
1787 case WM_PARENTNOTIFY
:
1788 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
1789 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
1790 /* else nothing to do */
1793 *plparam
= MapLS( (NMHDR
*)*plparam
); /* NMHDR is already 32-bit */
1796 case WM_WININICHANGE
:
1797 case WM_DEVMODECHANGE
:
1798 *plparam
= MapLS( (LPSTR
)*plparam
);
1800 case WM_WINDOWPOSCHANGING
:
1801 case WM_WINDOWPOSCHANGED
:
1803 WINDOWPOS16
*wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(*wp
) + sizeof(LPARAM
) );
1805 WINDOWPOS32to16( (WINDOWPOS
*)*plparam
, wp
);
1806 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1807 *plparam
= MapLS( wp
);
1812 LPMSG msg32
= (LPMSG
) *plparam
;
1813 LPMSG16 msg16
= HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16
) );
1815 if (!msg16
) return -1;
1816 msg16
->hwnd
= HWND_16( msg32
->hwnd
);
1817 msg16
->message
= msg32
->message
;
1818 msg16
->wParam
= msg32
->wParam
;
1819 msg16
->lParam
= msg32
->lParam
;
1820 msg16
->time
= msg32
->time
;
1821 msg16
->pt
.x
= msg32
->pt
.x
;
1822 msg16
->pt
.y
= msg32
->pt
.y
;
1823 *plparam
= MapLS( msg16
);
1828 case WM_ACTIVATEAPP
:
1829 if (*plparam
) *plparam
= HTASK_16( (HANDLE
)*plparam
);
1833 MDINEXTMENU
*next
= (MDINEXTMENU
*)*plparam
;
1834 *plparam
= (LPARAM
)next
->hmenuIn
;
1838 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
))
1840 *pmsg16
= WM_PAINTICON
;
1845 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
))
1846 *pmsg16
= WM_ICONERASEBKGND
;
1848 case WM_PAINTCLIPBOARD
:
1849 case WM_SIZECLIPBOARD
:
1850 FIXME_(msg
)("message %04x needs translation\n", msg32
);
1852 /* following messages should not be sent to 16-bit apps */
1855 case WM_CAPTURECHANGED
:
1856 case WM_STYLECHANGING
:
1857 case WM_STYLECHANGED
:
1859 case WM_DDE_INITIATE
:
1860 case WM_DDE_TERMINATE
:
1861 case WM_DDE_UNADVISE
:
1862 case WM_DDE_REQUEST
:
1863 *pwparam16
= HWND_16((HWND
)wParam32
);
1872 *pwparam16
= HWND_16((HWND
)wParam32
);
1873 UnpackDDElParam(msg32
, *plparam
, &lo32
, &hi
);
1874 if (lo32
&& !(lo16
= convert_handle_32_to_16(lo32
, GMEM_DDESHARE
)))
1876 *plparam
= MAKELPARAM(lo16
, hi
);
1878 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1885 *pwparam16
= HWND_16((HWND
)wParam32
);
1887 UnpackDDElParam(msg32
, *plparam
, &lo
, &hi
);
1889 if (GlobalGetAtomNameA((ATOM
)hi
, buf
, sizeof(buf
)) > 0) flag
|= 1;
1890 if (GlobalSize((HANDLE
)hi
) != 0) flag
|= 2;
1896 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1901 break; /* atom, nothing to do */
1903 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
1906 hi
= convert_handle_32_to_16(hi
, GMEM_DDESHARE
);
1909 *plparam
= MAKELPARAM(lo
, hi
);
1911 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1912 case WM_DDE_EXECUTE
:
1913 *plparam
= convert_handle_32_to_16(*plparam
, GMEM_DDESHARE
);
1914 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1915 default: /* No translation needed */
1921 /**********************************************************************
1922 * WINPROC_UnmapMsg32ATo16
1924 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1926 static void WINPROC_UnmapMsg32ATo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1927 WPARAM16 wParam16
, LPARAM lParam16
, LRESULT
*result
)
1932 *(LPINT
)wParam
= LOWORD(*result
);
1933 *(LPINT
)lParam
= HIWORD(*result
);
1940 case LB_FINDSTRINGEXACT
:
1941 case LB_INSERTSTRING
:
1942 case LB_SELECTSTRING
:
1946 case CB_FINDSTRINGEXACT
:
1947 case CB_INSERTSTRING
:
1948 case CB_SELECTSTRING
:
1952 case WM_WININICHANGE
:
1953 case WM_DEVMODECHANGE
:
1954 UnMapLS( (SEGPTR
)lParam16
);
1956 case LB_SETTABSTOPS
:
1957 case WM_COMPAREITEM
:
1961 void *ptr
= MapSL( lParam16
);
1962 UnMapLS( lParam16
);
1963 HeapFree( GetProcessHeap(), 0, ptr
);
1968 PCOPYDATASTRUCT16 pcds
= MapSL( lParam16
);
1969 UnMapLS( lParam16
);
1970 UnMapLS( pcds
->lpData
);
1971 HeapFree( GetProcessHeap(), 0, pcds
);
1974 case CB_GETDROPPEDCONTROLRECT
:
1975 case LB_GETITEMRECT
:
1978 RECT16
*rect
= MapSL(lParam16
);
1979 UnMapLS( lParam16
);
1980 lParam16
= *(LPARAM
*)(rect
+ 1);
1981 r32
= (RECT
*)lParam16
;
1982 r32
->left
= rect
->left
;
1983 r32
->top
= rect
->top
;
1984 r32
->right
= rect
->right
;
1985 r32
->bottom
= rect
->bottom
;
1986 HeapFree( GetProcessHeap(), 0, rect
);
1989 case LB_GETSELITEMS
:
1992 LPINT16 items
= MapSL(lParam16
);
1993 UnMapLS( lParam16
);
1994 lParam16
= *((LPARAM
*)items
- 1);
1995 for (i
= 0; i
< wParam16
; i
++) *((LPINT
)lParam16
+ i
) = items
[i
];
1996 HeapFree( GetProcessHeap(), 0, (LPARAM
*)items
- 1 );
2002 *((PUINT
)(wParam
)) = LOWORD(*result
);
2004 *((PUINT
)(lParam
)) = HIWORD(*result
); /* FIXME: substract 1? */
2007 case WM_MEASUREITEM
:
2009 MEASUREITEMSTRUCT16
*mis
= MapSL(lParam16
);
2010 MEASUREITEMSTRUCT
*mis32
= *(MEASUREITEMSTRUCT
**)(mis
+ 1);
2011 mis32
->itemWidth
= mis
->itemWidth
;
2012 mis32
->itemHeight
= mis
->itemHeight
;
2013 UnMapLS( lParam16
);
2014 HeapFree( GetProcessHeap(), 0, mis
);
2017 case WM_GETMINMAXINFO
:
2019 MINMAXINFO16
*mmi
= MapSL(lParam16
);
2020 UnMapLS( lParam16
);
2021 lParam16
= *(LPARAM
*)(mmi
+ 1);
2022 MINMAXINFO16to32( mmi
, (MINMAXINFO
*)lParam16
);
2023 HeapFree( GetProcessHeap(), 0, mmi
);
2027 case WM_ASKCBFORMATNAME
:
2029 LPSTR str
= MapSL(lParam16
);
2030 UnMapLS( lParam16
);
2031 lParam16
= *((LPARAM
*)str
- 1);
2032 lstrcpynA( (LPSTR
)lParam16
, str
, wParam16
);
2033 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2038 MDICREATESTRUCT16
*cs
= MapSL(lParam16
);
2039 UnMapLS( cs
->szTitle
);
2040 UnMapLS( cs
->szClass
);
2041 UnMapLS( lParam16
);
2042 HeapFree( GetProcessHeap(), 0, cs
);
2045 case WM_MDIGETACTIVE
:
2046 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(*result
);
2047 *result
= (LRESULT
)WIN_Handle32( LOWORD(*result
) );
2051 NCCALCSIZE_PARAMS
*nc32
;
2052 NCCALCSIZE_PARAMS16
*nc
= MapSL(lParam16
);
2053 UnMapLS( lParam16
);
2054 lParam16
= *(LPARAM
*)(nc
+ 1);
2055 nc32
= (NCCALCSIZE_PARAMS
*)lParam16
;
2056 nc32
->rgrc
[0].left
= nc
->rgrc
[0].left
;
2057 nc32
->rgrc
[0].top
= nc
->rgrc
[0].top
;
2058 nc32
->rgrc
[0].right
= nc
->rgrc
[0].right
;
2059 nc32
->rgrc
[0].bottom
= nc
->rgrc
[0].bottom
;
2062 WINDOWPOS16
*pos
= MapSL(nc
->lppos
);
2063 UnMapLS( nc
->lppos
);
2064 nc32
->rgrc
[1].left
= nc
->rgrc
[1].left
;
2065 nc32
->rgrc
[1].top
= nc
->rgrc
[1].top
;
2066 nc32
->rgrc
[1].right
= nc
->rgrc
[1].right
;
2067 nc32
->rgrc
[1].bottom
= nc
->rgrc
[1].bottom
;
2068 nc32
->rgrc
[2].left
= nc
->rgrc
[2].left
;
2069 nc32
->rgrc
[2].top
= nc
->rgrc
[2].top
;
2070 nc32
->rgrc
[2].right
= nc
->rgrc
[2].right
;
2071 nc32
->rgrc
[2].bottom
= nc
->rgrc
[2].bottom
;
2072 WINDOWPOS16to32( pos
, nc32
->lppos
);
2073 HeapFree( GetProcessHeap(), 0, pos
);
2075 HeapFree( GetProcessHeap(), 0, nc
);
2081 CREATESTRUCT16
*cs
= MapSL(lParam16
);
2082 UnMapLS( lParam16
);
2083 UnMapLS( cs
->lpszName
);
2084 UnMapLS( cs
->lpszClass
);
2085 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2087 MDICREATESTRUCT16
*mdi_cs16
= (MDICREATESTRUCT16
*)MapSL(cs
->lpCreateParams
);
2088 UnMapLS( cs
->lpCreateParams
);
2089 UnMapLS( mdi_cs16
->szTitle
);
2090 UnMapLS( mdi_cs16
->szClass
);
2091 HeapFree(GetProcessHeap(), 0, mdi_cs16
);
2093 HeapFree( GetProcessHeap(), 0, cs
);
2096 case WM_WINDOWPOSCHANGING
:
2097 case WM_WINDOWPOSCHANGED
:
2099 WINDOWPOS16
*wp
= MapSL(lParam16
);
2100 UnMapLS( lParam16
);
2101 lParam16
= *(LPARAM
*)(wp
+ 1);
2102 WINDOWPOS16to32( wp
, (WINDOWPOS
*)lParam16
);
2103 HeapFree( GetProcessHeap(), 0, wp
);
2112 LPMSG16 msg16
= MapSL(lParam16
);
2113 UnMapLS( lParam16
);
2114 HeapFree( GetProcessHeap(), 0, msg16
);
2119 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
2120 next
->hmenuNext
= HMENU_32( LOWORD(*result
) );
2121 next
->hwndNext
= WIN_Handle32( HIWORD(*result
) );
2129 /**********************************************************************
2130 * WINPROC_MapMsg32WTo16
2132 * Map a message from 32-bit Unicode to 16-bit.
2133 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2135 static INT
WINPROC_MapMsg32WTo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
2136 UINT16
*pmsg16
, WPARAM16
*pwparam16
, LPARAM
*plparam
)
2138 *pmsg16
= LOWORD(msg32
);
2139 *pwparam16
= LOWORD(wParam32
);
2144 case LB_FINDSTRINGEXACT
:
2145 case LB_INSERTSTRING
:
2146 case LB_SELECTSTRING
:
2149 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2150 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2155 case CB_FINDSTRINGEXACT
:
2156 case CB_INSERTSTRING
:
2157 case CB_SELECTSTRING
:
2159 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2160 *pmsg16
= (UINT16
)msg32
+ (CB_ADDSTRING16
- CB_ADDSTRING
);
2167 CREATESTRUCTW
*cs32
= (CREATESTRUCTW
*)*plparam
;
2169 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2170 CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs32
, cs
);
2171 cs
->lpszName
= map_str_32W_to_16( cs32
->lpszName
);
2172 cs
->lpszClass
= map_str_32W_to_16( cs32
->lpszClass
);
2174 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2176 MDICREATESTRUCT16
*mdi_cs16
;
2177 MDICREATESTRUCTW
*mdi_cs
= (MDICREATESTRUCTW
*)cs32
->lpCreateParams
;
2178 mdi_cs16
= HeapAlloc(GetProcessHeap(), 0, sizeof(*mdi_cs16
));
2181 HeapFree(GetProcessHeap(), 0, cs
);
2184 MDICREATESTRUCT32Ato16((MDICREATESTRUCTA
*)mdi_cs
, mdi_cs16
);
2185 mdi_cs16
->szTitle
= map_str_32W_to_16(mdi_cs
->szTitle
);
2186 mdi_cs16
->szClass
= map_str_32W_to_16(mdi_cs
->szClass
);
2187 cs
->lpCreateParams
= MapLS(mdi_cs16
);
2189 *plparam
= MapLS(cs
);
2194 MDICREATESTRUCT16
*cs
;
2195 MDICREATESTRUCTW
*cs32
= (MDICREATESTRUCTW
*)*plparam
;
2197 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2198 MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs32
, cs
);
2199 cs
->szTitle
= map_str_32W_to_16( cs32
->szTitle
);
2200 cs
->szClass
= map_str_32W_to_16( cs32
->szClass
);
2201 *plparam
= MapLS(cs
);
2205 case WM_WININICHANGE
:
2206 case WM_DEVMODECHANGE
:
2207 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2211 if ( WINPROC_TestLBForStr( hwnd
, msg32
))
2213 LPSTR str
= HeapAlloc( GetProcessHeap(), 0, 512 ); /* FIXME: fixed sized buffer */
2214 if (!str
) return -1;
2215 *pmsg16
= (msg32
== LB_GETTEXT
) ? LB_GETTEXT16
: CB_GETLBTEXT16
;
2216 *plparam
= (LPARAM
)MapLS(str
);
2221 *pwparam16
= map_wparam_char_WtoA( wParam32
, 1 );
2222 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
2225 *pwparam16
= map_wparam_char_WtoA( wParam32
, 1 );
2226 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2231 case WM_SYSDEADCHAR
:
2232 *pwparam16
= map_wparam_char_WtoA( wParam32
, 1 );
2235 *pwparam16
= map_wparam_char_WtoA( wParam32
, 2 );
2238 default: /* No Unicode translation needed (?) */
2239 return WINPROC_MapMsg32ATo16( hwnd
, msg32
, wParam32
, pmsg16
,
2240 pwparam16
, plparam
);
2245 /**********************************************************************
2246 * WINPROC_UnmapMsg32WTo16
2248 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2250 static void WINPROC_UnmapMsg32WTo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2251 WPARAM16 wParam16
, LPARAM lParam16
, LRESULT
*result
)
2257 case LB_FINDSTRINGEXACT
:
2258 case LB_INSERTSTRING
:
2259 case LB_SELECTSTRING
:
2264 case CB_FINDSTRINGEXACT
:
2265 case CB_INSERTSTRING
:
2266 case CB_SELECTSTRING
:
2269 case WM_WININICHANGE
:
2270 case WM_DEVMODECHANGE
:
2271 unmap_str_32W_to_16( lParam16
);
2276 CREATESTRUCT16
*cs
= MapSL(lParam16
);
2277 UnMapLS( lParam16
);
2278 unmap_str_32W_to_16( cs
->lpszName
);
2279 unmap_str_32W_to_16( cs
->lpszClass
);
2281 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2283 MDICREATESTRUCT16
*mdi_cs16
= (MDICREATESTRUCT16
*)MapSL(cs
->lpCreateParams
);
2284 UnMapLS( cs
->lpCreateParams
);
2285 unmap_str_32W_to_16(mdi_cs16
->szTitle
);
2286 unmap_str_32W_to_16(mdi_cs16
->szClass
);
2287 HeapFree(GetProcessHeap(), 0, mdi_cs16
);
2289 HeapFree( GetProcessHeap(), 0, cs
);
2294 MDICREATESTRUCT16
*cs
= MapSL(lParam16
);
2295 UnMapLS( lParam16
);
2296 unmap_str_32W_to_16( cs
->szTitle
);
2297 unmap_str_32W_to_16( cs
->szClass
);
2298 HeapFree( GetProcessHeap(), 0, cs
);
2302 case WM_ASKCBFORMATNAME
:
2304 LPSTR str
= MapSL(lParam16
);
2305 UnMapLS( lParam16
);
2306 lParam16
= *((LPARAM
*)str
- 1);
2307 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)lParam16
, 0x7fffffff );
2308 *result
= strlenW( (LPWSTR
)lParam16
);
2309 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2314 if ( WINPROC_TestLBForStr( hwnd
, msg
))
2316 LPSTR str
= MapSL(lParam16
);
2317 UnMapLS( lParam16
);
2318 *result
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)lParam
, 0x7fffffff ) - 1;
2319 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
);
2323 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, wParam16
, lParam16
, result
);
2329 /**********************************************************************
2330 * WINPROC_CallProcAtoW
2332 * Call a window procedure, translating args from Ansi to Unicode.
2334 LRESULT
WINPROC_CallProcAtoW( winproc_callback_t callback
, HWND hwnd
, UINT msg
, WPARAM wParam
,
2335 LPARAM lParam
, LRESULT
*result
, void *arg
)
2339 TRACE_(msg
)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2340 hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2347 WCHAR
*ptr
, buffer
[512];
2348 CREATESTRUCTA
*csA
= (CREATESTRUCTA
*)lParam
;
2349 CREATESTRUCTW csW
= *(CREATESTRUCTW
*)csA
;
2350 MDICREATESTRUCTW mdi_cs
;
2351 DWORD name_lenA
= 0, name_lenW
= 0, class_lenA
= 0, class_lenW
= 0;
2353 if (HIWORD(csA
->lpszClass
))
2355 class_lenA
= strlen(csA
->lpszClass
) + 1;
2356 RtlMultiByteToUnicodeSize( &class_lenW
, csA
->lpszClass
, class_lenA
);
2358 if (HIWORD(csA
->lpszName
))
2360 name_lenA
= strlen(csA
->lpszName
) + 1;
2361 RtlMultiByteToUnicodeSize( &name_lenW
, csA
->lpszName
, name_lenA
);
2364 if (!(ptr
= get_buffer( buffer
, sizeof(buffer
), class_lenW
+ name_lenW
))) break;
2368 csW
.lpszClass
= ptr
;
2369 RtlMultiByteToUnicodeN( ptr
, class_lenW
, NULL
, csA
->lpszClass
, class_lenA
);
2373 csW
.lpszName
= ptr
+ class_lenW
/sizeof(WCHAR
);
2374 RtlMultiByteToUnicodeN( ptr
+ class_lenW
/sizeof(WCHAR
), name_lenW
, NULL
,
2375 csA
->lpszName
, name_lenA
);
2378 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2380 mdi_cs
= *(MDICREATESTRUCTW
*)csA
->lpCreateParams
;
2381 mdi_cs
.szTitle
= csW
.lpszName
;
2382 mdi_cs
.szClass
= csW
.lpszClass
;
2383 csW
.lpCreateParams
= &mdi_cs
;
2386 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)&csW
, result
, arg
);
2387 free_buffer( buffer
, ptr
);
2393 WCHAR
*ptr
, buffer
[512];
2394 DWORD title_lenA
= 0, title_lenW
= 0, class_lenA
= 0, class_lenW
= 0;
2395 MDICREATESTRUCTA
*csA
= (MDICREATESTRUCTA
*)lParam
;
2396 MDICREATESTRUCTW csW
;
2398 memcpy( &csW
, csA
, sizeof(csW
) );
2400 if (HIWORD(csA
->szTitle
))
2402 title_lenA
= strlen(csA
->szTitle
) + 1;
2403 RtlMultiByteToUnicodeSize( &title_lenW
, csA
->szTitle
, title_lenA
);
2405 if (HIWORD(csA
->szClass
))
2407 class_lenA
= strlen(csA
->szClass
) + 1;
2408 RtlMultiByteToUnicodeSize( &class_lenW
, csA
->szClass
, class_lenA
);
2411 if (!(ptr
= get_buffer( buffer
, sizeof(buffer
), title_lenW
+ class_lenW
))) break;
2416 RtlMultiByteToUnicodeN( ptr
, title_lenW
, NULL
, csA
->szTitle
, title_lenA
);
2420 csW
.szClass
= ptr
+ title_lenW
/sizeof(WCHAR
);
2421 RtlMultiByteToUnicodeN( ptr
+ title_lenW
/sizeof(WCHAR
), class_lenW
, NULL
,
2422 csA
->szClass
, class_lenA
);
2424 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)&csW
, result
, arg
);
2425 free_buffer( buffer
, ptr
);
2430 case WM_ASKCBFORMATNAME
:
2432 WCHAR
*ptr
, buffer
[512];
2433 LPSTR str
= (LPSTR
)lParam
;
2434 DWORD len
= wParam
* sizeof(WCHAR
);
2436 if (!(ptr
= get_buffer( buffer
, sizeof(buffer
), len
))) break;
2437 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)ptr
, result
, arg
);
2438 if (*result
&& wParam
)
2440 RtlUnicodeToMultiByteN( str
, wParam
- 1, &len
, ptr
, strlenW(ptr
) * sizeof(WCHAR
) );
2444 free_buffer( buffer
, ptr
);
2449 case LB_INSERTSTRING
:
2451 case LB_FINDSTRINGEXACT
:
2452 case LB_SELECTSTRING
:
2454 case CB_INSERTSTRING
:
2456 case CB_FINDSTRINGEXACT
:
2457 case CB_SELECTSTRING
:
2458 if (!lParam
|| !WINPROC_TestLBForStr( hwnd
, msg
))
2460 ret
= callback( hwnd
, msg
, wParam
, lParam
, result
, arg
);
2465 case WM_WININICHANGE
:
2466 case WM_DEVMODECHANGE
:
2471 if (!lParam
) ret
= callback( hwnd
, msg
, wParam
, lParam
, result
, arg
);
2474 WCHAR
*ptr
, buffer
[512];
2475 LPCSTR strA
= (LPCSTR
)lParam
;
2476 DWORD lenW
, lenA
= strlen(strA
) + 1;
2478 RtlMultiByteToUnicodeSize( &lenW
, strA
, lenA
);
2479 if ((ptr
= get_buffer( buffer
, sizeof(buffer
), lenW
)))
2481 RtlMultiByteToUnicodeN( ptr
, lenW
, NULL
, strA
, lenA
);
2482 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)ptr
, result
, arg
);
2483 free_buffer( buffer
, ptr
);
2490 if (lParam
&& WINPROC_TestLBForStr( hwnd
, msg
))
2492 WCHAR buffer
[512]; /* FIXME: fixed sized buffer */
2494 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)buffer
, result
, arg
);
2498 RtlUnicodeToMultiByteN( (LPSTR
)lParam
, ~0u, &len
,
2499 buffer
, (strlenW(buffer
) + 1) * sizeof(WCHAR
) );
2503 else ret
= callback( hwnd
, msg
, wParam
, lParam
, result
, arg
);
2508 WCHAR
*ptr
, buffer
[512];
2509 WORD len
= *(WORD
*)lParam
;
2511 if (!(ptr
= get_buffer( buffer
, sizeof(buffer
), len
* sizeof(WCHAR
) ))) break;
2512 *((WORD
*)ptr
) = len
; /* store the length */
2513 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)ptr
, result
, arg
);
2517 RtlUnicodeToMultiByteN( (LPSTR
)lParam
, len
, &reslen
, ptr
, *result
* sizeof(WCHAR
) );
2518 if (reslen
< len
) ((LPSTR
)lParam
)[reslen
] = 0;
2521 free_buffer( buffer
, ptr
);
2528 MSG newmsg
= *(MSG
*)lParam
;
2529 switch(newmsg
.message
)
2534 case WM_SYSDEADCHAR
:
2535 newmsg
.wParam
= map_wparam_char_AtoW( newmsg
.wParam
, 1 );
2538 newmsg
.wParam
= map_wparam_char_AtoW( newmsg
.wParam
, 2 );
2541 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)&newmsg
, result
, arg
);
2543 else ret
= callback( hwnd
, msg
, wParam
, lParam
, result
, arg
);
2551 case WM_SYSDEADCHAR
:
2552 case EM_SETPASSWORDCHAR
:
2553 ret
= callback( hwnd
, msg
, map_wparam_char_AtoW(wParam
,1), lParam
, result
, arg
);
2557 ret
= callback( hwnd
, msg
, map_wparam_char_AtoW(wParam
,2), lParam
, result
, arg
);
2560 case WM_GETTEXTLENGTH
:
2561 case CB_GETLBTEXTLEN
:
2563 ret
= callback( hwnd
, msg
, wParam
, lParam
, result
, arg
);
2566 WCHAR
*ptr
, buffer
[512];
2568 DWORD len
= *result
+ 1;
2569 /* Determine respective GETTEXT message */
2570 UINT msgGetText
= (msg
== WM_GETTEXTLENGTH
) ? WM_GETTEXT
:
2571 ((msg
== CB_GETLBTEXTLEN
) ? CB_GETLBTEXT
: LB_GETTEXT
);
2572 /* wParam differs between the messages */
2573 WPARAM wp
= (msg
== WM_GETTEXTLENGTH
) ? len
: wParam
;
2575 if (!(ptr
= get_buffer( buffer
, sizeof(buffer
), len
* sizeof(WCHAR
) ))) break;
2577 if (callback
== call_window_proc
) /* FIXME: hack */
2578 callback( hwnd
, msgGetText
, wp
, (LPARAM
)ptr
, &tmp
, arg
);
2580 tmp
= SendMessageW( hwnd
, msgGetText
, wp
, (LPARAM
)ptr
);
2581 RtlUnicodeToMultiByteSize( &len
, ptr
, tmp
* sizeof(WCHAR
) );
2583 free_buffer( buffer
, ptr
);
2587 case WM_PAINTCLIPBOARD
:
2588 case WM_SIZECLIPBOARD
:
2589 FIXME_(msg
)( "message %s (0x%x) needs translation, please report\n",
2590 SPY_GetMsgName(msg
, hwnd
), msg
);
2594 ret
= callback( hwnd
, msg
, wParam
, lParam
, result
, arg
);
2601 /**********************************************************************
2602 * WINPROC_CallProcWtoA
2604 * Call a window procedure, translating args from Unicode to Ansi.
2606 static LRESULT
WINPROC_CallProcWtoA( winproc_callback_t callback
, HWND hwnd
, UINT msg
, WPARAM wParam
,
2607 LPARAM lParam
, LRESULT
*result
, void *arg
)
2611 TRACE_(msg
)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2612 hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2618 { /* csW->lpszName and csW->lpszClass are NOT supposed to be atoms
2621 char buffer
[1024], *cls
, *name
;
2622 CREATESTRUCTW
*csW
= (CREATESTRUCTW
*)lParam
;
2623 CREATESTRUCTA csA
= *(CREATESTRUCTA
*)csW
;
2624 MDICREATESTRUCTA mdi_cs
;
2625 DWORD name_lenA
, name_lenW
, class_lenA
, class_lenW
;
2627 class_lenW
= strlenW(csW
->lpszClass
) * sizeof(WCHAR
);
2628 RtlUnicodeToMultiByteSize(&class_lenA
, csW
->lpszClass
, class_lenW
);
2632 name_lenW
= strlenW(csW
->lpszName
) * sizeof(WCHAR
);
2633 RtlUnicodeToMultiByteSize(&name_lenA
, csW
->lpszName
, name_lenW
);
2636 name_lenW
= name_lenA
= 0;
2638 if (!(cls
= get_buffer( buffer
, sizeof(buffer
), class_lenA
+ name_lenA
+ 2 ))) break;
2640 RtlUnicodeToMultiByteN(cls
, class_lenA
, NULL
, csW
->lpszClass
, class_lenW
);
2641 cls
[class_lenA
] = 0;
2642 csA
.lpszClass
= cls
;
2646 name
= cls
+ class_lenA
+ 1;
2647 RtlUnicodeToMultiByteN(name
, name_lenA
, NULL
, csW
->lpszName
, name_lenW
);
2648 name
[name_lenA
] = 0;
2649 csA
.lpszName
= name
;
2652 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2654 mdi_cs
= *(MDICREATESTRUCTA
*)csW
->lpCreateParams
;
2655 mdi_cs
.szTitle
= csA
.lpszName
;
2656 mdi_cs
.szClass
= csA
.lpszClass
;
2657 csA
.lpCreateParams
= &mdi_cs
;
2660 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)&csA
, result
, arg
);
2661 free_buffer( buffer
, cls
);
2666 case WM_ASKCBFORMATNAME
:
2668 char *ptr
, buffer
[512];
2669 DWORD len
= wParam
* 2;
2671 if (!(ptr
= get_buffer( buffer
, sizeof(buffer
), len
))) break;
2672 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)ptr
, result
, arg
);
2675 RtlMultiByteToUnicodeN( (LPWSTR
)lParam
, wParam
*sizeof(WCHAR
), &len
, ptr
, strlen(ptr
)+1 );
2676 *result
= len
/sizeof(WCHAR
) - 1; /* do not count terminating null */
2677 ((LPWSTR
)lParam
)[*result
] = 0;
2679 free_buffer( buffer
, ptr
);
2684 case LB_INSERTSTRING
:
2686 case LB_FINDSTRINGEXACT
:
2687 case LB_SELECTSTRING
:
2689 case CB_INSERTSTRING
:
2691 case CB_FINDSTRINGEXACT
:
2692 case CB_SELECTSTRING
:
2693 if (!lParam
|| !WINPROC_TestLBForStr( hwnd
, msg
))
2695 ret
= callback( hwnd
, msg
, wParam
, lParam
, result
, arg
);
2700 case WM_WININICHANGE
:
2701 case WM_DEVMODECHANGE
:
2706 if (!lParam
) ret
= callback( hwnd
, msg
, wParam
, lParam
, result
, arg
);
2709 char *ptr
, buffer
[512];
2710 LPCWSTR strW
= (LPCWSTR
)lParam
;
2711 DWORD lenA
, lenW
= (strlenW(strW
) + 1) * sizeof(WCHAR
);
2713 RtlUnicodeToMultiByteSize( &lenA
, strW
, lenW
);
2714 if ((ptr
= get_buffer( buffer
, sizeof(buffer
), lenA
)))
2716 RtlUnicodeToMultiByteN( ptr
, lenA
, NULL
, strW
, lenW
);
2717 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)ptr
, result
, arg
);
2718 free_buffer( buffer
, ptr
);
2725 char *ptr
, buffer
[1024];
2726 DWORD title_lenA
= 0, title_lenW
= 0, class_lenA
= 0, class_lenW
= 0;
2727 MDICREATESTRUCTW
*csW
= (MDICREATESTRUCTW
*)lParam
;
2728 MDICREATESTRUCTA csA
;
2730 memcpy( &csA
, csW
, sizeof(csA
) );
2732 if (HIWORD(csW
->szTitle
))
2734 title_lenW
= (strlenW(csW
->szTitle
) + 1) * sizeof(WCHAR
);
2735 RtlUnicodeToMultiByteSize( &title_lenA
, csW
->szTitle
, title_lenW
);
2737 if (HIWORD(csW
->szClass
))
2739 class_lenW
= (strlenW(csW
->szClass
) + 1) * sizeof(WCHAR
);
2740 RtlUnicodeToMultiByteSize( &class_lenA
, csW
->szClass
, class_lenW
);
2743 if (!(ptr
= get_buffer( buffer
, sizeof(buffer
), title_lenA
+ class_lenA
))) break;
2747 RtlUnicodeToMultiByteN( ptr
, title_lenA
, NULL
, csW
->szTitle
, title_lenW
);
2752 RtlUnicodeToMultiByteN( ptr
+ title_lenA
, class_lenA
, NULL
, csW
->szClass
, class_lenW
);
2753 csA
.szClass
= ptr
+ title_lenA
;
2755 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)&csA
, result
, arg
);
2756 free_buffer( buffer
, ptr
);
2762 if (lParam
&& WINPROC_TestLBForStr( hwnd
, msg
))
2764 char buffer
[512]; /* FIXME: fixed sized buffer */
2766 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)buffer
, result
, arg
);
2770 RtlMultiByteToUnicodeN( (LPWSTR
)lParam
, ~0u, &len
, buffer
, strlen(buffer
) + 1 );
2771 *result
= len
/ sizeof(WCHAR
) - 1;
2774 else ret
= callback( hwnd
, msg
, wParam
, lParam
, result
, arg
);
2779 char *ptr
, buffer
[512];
2780 WORD len
= *(WORD
*)lParam
;
2782 if (!(ptr
= get_buffer( buffer
, sizeof(buffer
), len
* 2 ))) break;
2783 *((WORD
*)ptr
) = len
* 2; /* store the length */
2784 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)ptr
, result
, arg
);
2788 RtlMultiByteToUnicodeN( (LPWSTR
)lParam
, len
*sizeof(WCHAR
), &reslen
, ptr
, *result
);
2789 *result
= reslen
/ sizeof(WCHAR
);
2790 if (*result
< len
) ((LPWSTR
)lParam
)[*result
] = 0;
2792 free_buffer( buffer
, ptr
);
2799 MSG newmsg
= *(MSG
*)lParam
;
2800 switch(newmsg
.message
)
2805 case WM_SYSDEADCHAR
:
2806 newmsg
.wParam
= map_wparam_char_WtoA( newmsg
.wParam
, 1 );
2809 newmsg
.wParam
= map_wparam_char_WtoA( newmsg
.wParam
, 2 );
2812 ret
= callback( hwnd
, msg
, wParam
, (LPARAM
)&newmsg
, result
, arg
);
2814 else ret
= callback( hwnd
, msg
, wParam
, lParam
, result
, arg
);
2822 case WM_SYSDEADCHAR
:
2823 case EM_SETPASSWORDCHAR
:
2824 ret
= callback( hwnd
, msg
, map_wparam_char_WtoA(wParam
,1), lParam
, result
, arg
);
2828 ret
= callback( hwnd
, msg
, map_wparam_char_WtoA(wParam
,2), lParam
, result
, arg
);
2831 case WM_PAINTCLIPBOARD
:
2832 case WM_SIZECLIPBOARD
:
2833 FIXME_(msg
)( "message %s (%04x) needs translation, please report\n",
2834 SPY_GetMsgName(msg
, hwnd
), msg
);
2838 ret
= callback( hwnd
, msg
, wParam
, lParam
, result
, arg
);
2846 /**********************************************************************
2847 * WINPROC_CallProc16To32A
2849 LRESULT
WINPROC_CallProc16To32A( winproc_callback_t callback
, HWND16 hwnd
, UINT16 msg
,
2850 WPARAM16 wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
2855 HWND hwnd32
= WIN_Handle32( hwnd
);
2857 TRACE_(msg
)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2858 hwnd32
, SPY_GetMsgName(msg
, hwnd32
), wParam
, lParam
);
2860 if (WINPROC_MapMsg16To32A( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2863 ret
= callback( hwnd32
, msg32
, wParam32
, lParam
, result
, arg
);
2864 *result
= WINPROC_UnmapMsg16To32A( hwnd32
, msg32
, wParam32
, lParam
, *result
);
2869 /**********************************************************************
2870 * WINPROC_CallProc16To32W
2872 static LRESULT
WINPROC_CallProc16To32W( winproc_callback_t callback
, HWND16 hwnd
, UINT16 msg
,
2873 WPARAM16 wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
2878 HWND hwnd32
= WIN_Handle32( hwnd
);
2880 TRACE_(msg
)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2881 hwnd32
, SPY_GetMsgName(msg
, hwnd32
), wParam
, lParam
);
2886 case WM_ASKCBFORMATNAME
:
2888 case WM_WININICHANGE
:
2889 case WM_DEVMODECHANGE
:
2894 ret
= WINPROC_CallProcAtoW( callback
, hwnd32
, msg
, wParam
, (LPARAM
)MapSL(lParam
), result
, arg
);
2897 case WM_GETTEXTLENGTH
:
2898 case CB_GETLBTEXTLEN
:
2900 ret
= WINPROC_CallProcAtoW( callback
, hwnd32
, msg
, wParam
, lParam
, result
, arg
);
2904 if (WINPROC_MapMsg16To32W( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2906 ret
= callback( hwnd32
, msg32
, wParam32
, lParam
, result
, arg
);
2907 *result
= WINPROC_UnmapMsg16To32W( hwnd32
, msg32
, wParam32
, lParam
, *result
);
2913 /**********************************************************************
2914 * __wine_call_wndproc (USER.1010)
2916 LRESULT WINAPI
__wine_call_wndproc( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
2922 WINPROC_CallProc16To32A( call_window_proc
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->procA
);
2924 WINPROC_CallProc16To32W( call_window_proc
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->procW
);
2929 /**********************************************************************
2930 * WINPROC_CallProc32ATo16
2932 * Call a 16-bit window procedure, translating the 32-bit args.
2934 LRESULT
WINPROC_CallProc32ATo16( winproc_callback16_t callback
, HWND hwnd
, UINT msg
,
2935 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
2942 TRACE_(msg
)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2943 hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2946 if (WINPROC_MapMsg32ATo16( hwnd
, msg
, wParam
, &msg16
, &wParam16
, &lParam16
) == -1)
2948 ret
= callback( HWND_16(hwnd
), msg16
, wParam16
, lParam16
, result
, arg
);
2949 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, wParam16
, lParam16
, result
);
2954 /**********************************************************************
2955 * WINPROC_CallProc32WTo16
2957 * Call a 16-bit window procedure, translating the 32-bit args.
2959 static LRESULT
WINPROC_CallProc32WTo16( winproc_callback16_t callback
, HWND hwnd
, UINT msg
,
2960 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
2967 TRACE_(msg
)("(hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2968 hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2971 if (WINPROC_MapMsg32WTo16( hwnd
, msg
, wParam
, &msg16
, &wParam16
, &lParam16
) == -1)
2973 ret
= callback( HWND_16(hwnd
), msg16
, wParam16
, lParam16
, result
, arg
);
2974 WINPROC_UnmapMsg32WTo16( hwnd
, msg
, wParam
, lParam
, wParam16
, lParam16
, result
);
2979 /**********************************************************************
2980 * CallWindowProc (USER.122)
2982 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
2983 WPARAM16 wParam
, LPARAM lParam
)
2988 if (!func
) return 0;
2990 if (!(proc
= handle16_to_proc( func
)))
2991 call_window_proc16( hwnd
, msg
, wParam
, lParam
, &result
, func
);
2992 else if (proc
->procA
)
2993 WINPROC_CallProc16To32A( call_window_proc
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->procA
);
2994 else if (proc
->procW
)
2995 WINPROC_CallProc16To32W( call_window_proc
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->procW
);
2997 call_window_proc16( hwnd
, msg
, wParam
, lParam
, &result
, proc
->proc16
);
3003 /**********************************************************************
3004 * CallWindowProcA (USER32.@)
3006 * The CallWindowProc() function invokes the windows procedure _func_,
3007 * with _hwnd_ as the target window, the message specified by _msg_, and
3008 * the message parameters _wParam_ and _lParam_.
3010 * Some kinds of argument conversion may be done, I'm not sure what.
3012 * CallWindowProc() may be used for windows subclassing. Use
3013 * SetWindowLong() to set a new windows procedure for windows of the
3014 * subclass, and handle subclassed messages in the new windows
3015 * procedure. The new windows procedure may then use CallWindowProc()
3016 * with _func_ set to the parent class's windows procedure to dispatch
3017 * the message to the superclass.
3021 * The return value is message dependent.
3027 LRESULT WINAPI
CallWindowProcA(
3028 WNDPROC func
, /* [in] window procedure */
3029 HWND hwnd
, /* [in] target window */
3030 UINT msg
, /* [in] message */
3031 WPARAM wParam
, /* [in] message dependent parameter */
3032 LPARAM lParam
/* [in] message dependent parameter */
3037 if (!func
) return 0;
3039 if (!(proc
= handle_to_proc( func
)))
3040 call_window_proc( hwnd
, msg
, wParam
, lParam
, &result
, func
);
3041 else if (proc
->procA
)
3042 call_window_proc( hwnd
, msg
, wParam
, lParam
, &result
, proc
->procA
);
3043 else if (proc
->procW
)
3044 WINPROC_CallProcAtoW( call_window_proc
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->procW
);
3046 WINPROC_CallProc32ATo16( call_window_proc16
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->proc16
);
3051 /**********************************************************************
3052 * CallWindowProcW (USER32.@)
3054 * See CallWindowProcA.
3056 LRESULT WINAPI
CallWindowProcW( WNDPROC func
, HWND hwnd
, UINT msg
,
3057 WPARAM wParam
, LPARAM lParam
)
3062 if (!func
) return 0;
3064 if (!(proc
= handle_to_proc( func
)))
3065 call_window_proc( hwnd
, msg
, wParam
, lParam
, &result
, func
);
3066 else if (proc
->procW
)
3067 call_window_proc( hwnd
, msg
, wParam
, lParam
, &result
, proc
->procW
);
3068 else if (proc
->procA
)
3069 WINPROC_CallProcWtoA( call_window_proc
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->procA
);
3071 WINPROC_CallProc32WTo16( call_window_proc16
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->proc16
);
3076 /**********************************************************************
3077 * WINPROC_CallDlgProc16
3079 INT_PTR
WINPROC_CallDlgProc16( DLGPROC16 func
, HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
3085 if (!func
) return 0;
3087 if (!(proc
= handle16_to_proc( (WNDPROC16
)func
)))
3089 ret
= call_dialog_proc16( hwnd
, msg
, wParam
, lParam
, &result
, func
);
3091 else if (proc
->procA
)
3093 ret
= WINPROC_CallProc16To32A( call_dialog_proc
, hwnd
, msg
, wParam
, lParam
,
3094 &result
, proc
->procA
);
3095 SetWindowLongPtrW( WIN_Handle32(hwnd
), DWLP_MSGRESULT
, result
);
3097 else if (proc
->procW
)
3099 ret
= WINPROC_CallProc16To32W( call_dialog_proc
, hwnd
, msg
, wParam
, lParam
,
3100 &result
, proc
->procW
);
3101 SetWindowLongPtrW( WIN_Handle32(hwnd
), DWLP_MSGRESULT
, result
);
3105 ret
= call_dialog_proc16( hwnd
, msg
, wParam
, lParam
, &result
, proc
->proc16
);
3111 /**********************************************************************
3112 * WINPROC_CallDlgProcA
3114 INT_PTR
WINPROC_CallDlgProcA( DLGPROC func
, HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
3120 if (!func
) return 0;
3122 if (!(proc
= handle_to_proc( (WNDPROC
)func
)))
3123 ret
= call_dialog_proc( hwnd
, msg
, wParam
, lParam
, &result
, func
);
3124 else if (proc
->procA
)
3125 ret
= call_dialog_proc( hwnd
, msg
, wParam
, lParam
, &result
, proc
->procA
);
3126 else if (proc
->procW
)
3128 ret
= WINPROC_CallProcAtoW( call_dialog_proc
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->procW
);
3129 SetWindowLongPtrW( hwnd
, DWLP_MSGRESULT
, result
);
3133 ret
= WINPROC_CallProc32ATo16( call_dialog_proc16
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->proc16
);
3134 SetWindowLongPtrW( hwnd
, DWLP_MSGRESULT
, result
);
3140 /**********************************************************************
3141 * WINPROC_CallDlgProcW
3143 INT_PTR
WINPROC_CallDlgProcW( DLGPROC func
, HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
3149 if (!func
) return 0;
3151 if (!(proc
= handle_to_proc( (WNDPROC
)func
)))
3152 ret
= call_dialog_proc( hwnd
, msg
, wParam
, lParam
, &result
, func
);
3153 else if (proc
->procW
)
3154 ret
= call_dialog_proc( hwnd
, msg
, wParam
, lParam
, &result
, proc
->procW
);
3155 else if (proc
->procA
)
3157 ret
= WINPROC_CallProcWtoA( call_dialog_proc
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->procA
);
3158 SetWindowLongPtrW( hwnd
, DWLP_MSGRESULT
, result
);
3162 ret
= WINPROC_CallProc32WTo16( call_dialog_proc16
, hwnd
, msg
, wParam
, lParam
, &result
, proc
->proc16
);
3163 SetWindowLongPtrW( hwnd
, DWLP_MSGRESULT
, result
);