2 * 16-bit messaging support
4 * Copyright 2001 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/winuser16.h"
29 #include "user_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(msg
);
33 WINE_DECLARE_DEBUG_CHANNEL(message
);
35 DWORD USER16_AlertableWait
= 0;
37 struct wow_handlers32 wow_handlers32
;
39 static LRESULT
send_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
40 LRESULT
*result
, void *arg
)
42 *result
= SendMessageA( hwnd
, msg
, wp
, lp
);
46 static LRESULT
post_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
47 LRESULT
*result
, void *arg
)
50 return PostMessageA( hwnd
, msg
, wp
, lp
);
53 static LRESULT
post_thread_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
54 LRESULT
*result
, void *arg
)
56 DWORD_PTR tid
= (DWORD_PTR
)arg
;
58 return PostThreadMessageA( tid
, msg
, wp
, lp
);
61 static LRESULT
get_message_callback( HWND16 hwnd
, UINT16 msg
, WPARAM16 wp
, LPARAM lp
,
62 LRESULT
*result
, void *arg
)
74 static LRESULT
defdlg_proc_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
75 LRESULT
*result
, void *arg
)
77 *result
= DefDlgProcA( hwnd
, msg
, wp
, lp
);
81 static LRESULT
call_window_proc_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
82 LRESULT
*result
, void *arg
)
85 *result
= CallWindowProcA( proc
, hwnd
, msg
, wp
, lp
);
90 /**********************************************************************
91 * Support for window procedure thunks
97 WORD popl_eax
; /* popl %eax (return address) */
98 WORD pushl_func
; /* pushl $proc */
100 WORD pushl_eax
; /* pushl %eax */
101 BYTE ljmp
; /* ljmp relay*/
102 FARPROC16 relay
; /* __wine_call_wndproc */
106 #define WINPROC_HANDLE (~0u >> 16)
107 #define MAX_WINPROCS32 4096
108 #define MAX_WINPROCS16 1024
110 static WNDPROC16 winproc16_array
[MAX_WINPROCS16
];
111 static unsigned int winproc16_used
;
113 static WINPROC_THUNK
*thunk_array
;
114 static UINT thunk_selector
;
116 /* return the window proc index for a given handle, or -1 for an invalid handle
117 * indices 0 .. MAX_WINPROCS32-1 are for 32-bit procs,
118 * indices MAX_WINPROCS32 .. MAX_WINPROCS32+MAX_WINPROCS16-1 for 16-bit procs */
119 static int winproc_to_index( WNDPROC16 handle
)
123 if (HIWORD(handle
) == thunk_selector
)
125 index
= LOWORD(handle
) / sizeof(WINPROC_THUNK
);
126 /* check alignment */
127 if (index
* sizeof(WINPROC_THUNK
) != LOWORD(handle
)) return -1;
128 /* check array limits */
129 if (index
>= MAX_WINPROCS32
) return -1;
133 index
= LOWORD(handle
);
134 if ((ULONG_PTR
)handle
>> 16 != WINPROC_HANDLE
) return -1;
135 /* check array limits */
136 if (index
>= winproc16_used
+ MAX_WINPROCS32
) return -1;
141 /* allocate a 16-bit thunk for an existing window proc */
142 static WNDPROC16
alloc_win16_thunk( WNDPROC handle
)
144 static FARPROC16 relay
;
145 WINPROC_THUNK
*thunk
;
146 UINT index
= LOWORD( handle
);
148 if (index
>= MAX_WINPROCS32
) /* already a 16-bit proc */
149 return winproc16_array
[index
- MAX_WINPROCS32
];
151 if (!thunk_array
) /* allocate the array and its selector */
153 assert( MAX_WINPROCS16
* sizeof(WINPROC_THUNK
) <= 0x10000 );
155 if (!(thunk_selector
= GlobalAlloc16( GMEM_FIXED
| GMEM_ZEROINIT
,
156 MAX_WINPROCS16
* sizeof(WINPROC_THUNK
) )))
158 PrestoChangoSelector16( thunk_selector
, thunk_selector
);
159 thunk_array
= GlobalLock16( thunk_selector
);
160 relay
= GetProcAddress16( GetModuleHandle16("user"), "__wine_call_wndproc" );
163 thunk
= &thunk_array
[index
];
164 thunk
->popl_eax
= 0x5866; /* popl %eax */
165 thunk
->pushl_func
= 0x6866; /* pushl $proc */
166 thunk
->proc
= handle
;
167 thunk
->pushl_eax
= 0x5066; /* pushl %eax */
168 thunk
->ljmp
= 0xea; /* ljmp relay*/
169 thunk
->relay
= relay
;
170 return (WNDPROC16
)MAKESEGPTR( thunk_selector
, index
* sizeof(WINPROC_THUNK
) );
173 /**********************************************************************
174 * WINPROC_AllocProc16
176 WNDPROC
WINPROC_AllocProc16( WNDPROC16 func
)
181 if (!func
) return NULL
;
183 /* check if the function is already a win proc */
184 if ((index
= winproc_to_index( func
)) != -1)
185 return (WNDPROC
)(ULONG_PTR
)(index
| (WINPROC_HANDLE
<< 16));
187 /* then check if we already have a winproc for that function */
188 for (index
= 0; index
< winproc16_used
; index
++)
189 if (winproc16_array
[index
] == func
) goto done
;
191 if (winproc16_used
>= MAX_WINPROCS16
)
193 FIXME( "too many winprocs, cannot allocate one for 16-bit %p\n", func
);
196 winproc16_array
[winproc16_used
++] = func
;
199 ret
= (WNDPROC
)(ULONG_PTR
)((index
+ MAX_WINPROCS32
) | (WINPROC_HANDLE
<< 16));
200 TRACE( "returning %p for %p/16-bit (%d/%d used)\n",
201 ret
, func
, winproc16_used
, MAX_WINPROCS16
);
205 /**********************************************************************
208 * Get a window procedure pointer that can be passed to the Windows program.
210 WNDPROC16
WINPROC_GetProc16( WNDPROC proc
, BOOL unicode
)
212 WNDPROC winproc
= wow_handlers32
.alloc_winproc( proc
, unicode
);
214 if ((ULONG_PTR
)winproc
>> 16 != WINPROC_HANDLE
) return (WNDPROC16
)winproc
;
215 return alloc_win16_thunk( winproc
);
218 /* call a 16-bit window procedure */
219 static LRESULT
call_window_proc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
220 LRESULT
*result
, void *arg
)
222 DPI_AWARENESS_CONTEXT awareness
;
223 WNDPROC16 func
= arg
;
224 int index
= winproc_to_index( func
);
233 DRAWITEMSTRUCT16 dis16
;
234 COMPAREITEMSTRUCT16 cis16
;
238 if (index
>= MAX_WINPROCS32
) func
= winproc16_array
[index
- MAX_WINPROCS32
];
240 /* Window procedures want ax = hInstance, ds = es = ss */
242 memset(&context
, 0, sizeof(context
));
243 context
.SegDs
= context
.SegEs
= SELECTOROF(NtCurrentTeb()->WOW32Reserved
);
244 if (!(context
.Eax
= GetWindowWord( HWND_32(hwnd
), GWLP_HINSTANCE
))) context
.Eax
= context
.SegDs
;
245 context
.SegCs
= SELECTOROF(func
);
246 context
.Eip
= OFFSETOF(func
);
247 context
.Ebp
= OFFSETOF(NtCurrentTeb()->WOW32Reserved
) + FIELD_OFFSET(STACK16FRAME
, bp
);
251 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
252 work if structures passed in lParam are placed in the stack/data
253 segment. Programmers easily make the mistake of converting lParam
254 to a near rather than a far pointer, since Windows apparently
255 allows this. We copy the structures to the 16 bit stack; this is
256 ugly but makes these programs work. */
261 size
= sizeof(CREATESTRUCT16
); break;
263 size
= sizeof(DRAWITEMSTRUCT16
); break;
265 size
= sizeof(COMPAREITEMSTRUCT16
); break;
269 memcpy( &args
.u
, MapSL(lParam
), size
);
270 lParam
= PtrToUlong(NtCurrentTeb()->WOW32Reserved
) - size
;
274 awareness
= SetThreadDpiAwarenessContext( GetWindowDpiAwarenessContext( HWND_32(hwnd
) ));
275 args
.params
[4] = hwnd
;
276 args
.params
[3] = msg
;
277 args
.params
[2] = wParam
;
278 args
.params
[1] = HIWORD(lParam
);
279 args
.params
[0] = LOWORD(lParam
);
280 WOWCallback16Ex( 0, WCB16_REGS
, sizeof(args
.params
) + size
, &args
, (DWORD
*)&context
);
281 *result
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
282 SetThreadDpiAwarenessContext( awareness
);
286 static LRESULT
call_dialog_proc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wp
, LPARAM lp
,
287 LRESULT
*result
, void *arg
)
289 LRESULT ret
= call_window_proc16( hwnd
, msg
, wp
, lp
, result
, arg
);
290 *result
= GetWindowLongPtrW( WIN_Handle32(hwnd
), DWLP_MSGRESULT
);
294 static LRESULT
call_window_proc_Ato16( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
295 LRESULT
*result
, void *arg
)
297 return WINPROC_CallProc32ATo16( call_window_proc16
, hwnd
, msg
, wp
, lp
, result
, arg
);
300 static LRESULT
call_dialog_proc_Ato16( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
301 LRESULT
*result
, void *arg
)
303 return WINPROC_CallProc32ATo16( call_dialog_proc16
, hwnd
, msg
, wp
, lp
, result
, arg
);
308 /**********************************************************************
309 * Support for Edit word break proc thunks
312 #define MAX_THUNKS 32
314 #include <pshpack1.h>
315 static struct word_break_thunk
317 BYTE popl_eax
; /* popl %eax (return address) */
318 BYTE pushl_proc16
; /* pushl proc16 */
319 EDITWORDBREAKPROC16 proc16
;
320 BYTE pushl_eax
; /* pushl %eax */
321 BYTE jmp
; /* ljmp call_word_break_proc16 */
323 } *word_break_thunks
;
326 /**********************************************************************
327 * call_word_break_proc16
329 static INT16 CALLBACK
call_word_break_proc16( SEGPTR proc16
, LPSTR text
, INT index
, INT count
, INT action
)
335 segptr
= MapLS( text
);
336 args
[4] = SELECTOROF(segptr
);
337 args
[3] = OFFSETOF(segptr
);
341 WOWCallback16Ex( proc16
, WCB16_PASCAL
, sizeof(args
), args
, &result
);
343 return LOWORD(result
);
346 /******************************************************************
347 * add_word_break_thunk
349 static struct word_break_thunk
*add_word_break_thunk( EDITWORDBREAKPROC16 proc16
)
351 struct word_break_thunk
*thunk
;
353 if (!word_break_thunks
)
355 word_break_thunks
= VirtualAlloc( NULL
, MAX_THUNKS
* sizeof(*thunk
),
356 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
357 if (!word_break_thunks
) return NULL
;
359 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
361 thunk
->popl_eax
= 0x58; /* popl %eax */
362 thunk
->pushl_proc16
= 0x68; /* pushl proc16 */
363 thunk
->pushl_eax
= 0x50; /* pushl %eax */
364 thunk
->jmp
= 0xe9; /* jmp call_word_break_proc16 */
365 thunk
->callback
= (char *)call_word_break_proc16
- (char *)(&thunk
->callback
+ 1);
368 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
369 if (thunk
->proc16
== proc16
) return thunk
;
371 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
373 if (thunk
->proc16
) continue;
374 thunk
->proc16
= proc16
;
377 FIXME("Out of word break thunks\n");
381 /******************************************************************
382 * get_word_break_thunk
384 static EDITWORDBREAKPROC16
get_word_break_thunk( EDITWORDBREAKPROCA proc
)
386 struct word_break_thunk
*thunk
= (struct word_break_thunk
*)proc
;
387 if (word_break_thunks
&& thunk
>= word_break_thunks
&& thunk
< &word_break_thunks
[MAX_THUNKS
])
388 return thunk
->proc16
;
393 /***********************************************************************
394 * Support for 16<->32 message mapping
397 static inline void *get_buffer( void *static_buffer
, size_t size
, size_t need
)
399 if (size
>= need
) return static_buffer
;
400 return HeapAlloc( GetProcessHeap(), 0, need
);
403 static inline void free_buffer( void *static_buffer
, void *buffer
)
405 if (buffer
!= static_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
408 static void RECT16to32( const RECT16
*from
, RECT
*to
)
410 to
->left
= from
->left
;
412 to
->right
= from
->right
;
413 to
->bottom
= from
->bottom
;
416 static void RECT32to16( const RECT
*from
, RECT16
*to
)
418 to
->left
= from
->left
;
420 to
->right
= from
->right
;
421 to
->bottom
= from
->bottom
;
424 static void MINMAXINFO32to16( const MINMAXINFO
*from
, MINMAXINFO16
*to
)
426 to
->ptReserved
.x
= from
->ptReserved
.x
;
427 to
->ptReserved
.y
= from
->ptReserved
.y
;
428 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
429 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
430 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
431 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
432 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
433 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
434 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
435 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
438 static void MINMAXINFO16to32( const MINMAXINFO16
*from
, MINMAXINFO
*to
)
440 to
->ptReserved
.x
= from
->ptReserved
.x
;
441 to
->ptReserved
.y
= from
->ptReserved
.y
;
442 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
443 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
444 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
445 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
446 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
447 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
448 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
449 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
452 static void WINDOWPOS32to16( const WINDOWPOS
* from
, WINDOWPOS16
* to
)
454 to
->hwnd
= HWND_16(from
->hwnd
);
455 to
->hwndInsertAfter
= HWND_16(from
->hwndInsertAfter
);
460 to
->flags
= from
->flags
;
463 static void WINDOWPOS16to32( const WINDOWPOS16
* from
, WINDOWPOS
* to
)
465 to
->hwnd
= WIN_Handle32(from
->hwnd
);
466 to
->hwndInsertAfter
= (from
->hwndInsertAfter
== (HWND16
)-1) ?
467 HWND_TOPMOST
: WIN_Handle32(from
->hwndInsertAfter
);
472 to
->flags
= from
->flags
;
475 /* The strings are not copied */
476 static void CREATESTRUCT32Ato16( const CREATESTRUCTA
* from
, CREATESTRUCT16
* to
)
478 to
->lpCreateParams
= (SEGPTR
)from
->lpCreateParams
;
479 to
->hInstance
= HINSTANCE_16(from
->hInstance
);
480 to
->hMenu
= HMENU_16(from
->hMenu
);
481 to
->hwndParent
= HWND_16(from
->hwndParent
);
486 to
->style
= from
->style
;
487 to
->dwExStyle
= from
->dwExStyle
;
490 static void CREATESTRUCT16to32A( const CREATESTRUCT16
* from
, CREATESTRUCTA
*to
)
493 to
->lpCreateParams
= (LPVOID
)from
->lpCreateParams
;
494 to
->hInstance
= HINSTANCE_32(from
->hInstance
);
495 to
->hMenu
= HMENU_32(from
->hMenu
);
496 to
->hwndParent
= WIN_Handle32(from
->hwndParent
);
501 to
->style
= from
->style
;
502 to
->dwExStyle
= from
->dwExStyle
;
503 to
->lpszName
= MapSL(from
->lpszName
);
504 to
->lpszClass
= MapSL(from
->lpszClass
);
507 /* The strings are not copied */
508 static void MDICREATESTRUCT32Ato16( const MDICREATESTRUCTA
* from
, MDICREATESTRUCT16
* to
)
510 to
->hOwner
= HINSTANCE_16(from
->hOwner
);
515 to
->style
= from
->style
;
516 to
->lParam
= from
->lParam
;
519 static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16
* from
, MDICREATESTRUCTA
*to
)
521 to
->hOwner
= HINSTANCE_32(from
->hOwner
);
526 to
->style
= from
->style
;
527 to
->lParam
= from
->lParam
;
528 to
->szTitle
= MapSL(from
->szTitle
);
529 to
->szClass
= MapSL(from
->szClass
);
532 static UINT_PTR
convert_handle_16_to_32(HANDLE16 src
, unsigned int flags
)
535 UINT sz
= GlobalSize16(src
);
538 if (!(dst
= GlobalAlloc(flags
, sz
)))
540 ptr16
= GlobalLock16(src
);
541 ptr32
= GlobalLock(dst
);
542 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr32
, ptr16
, sz
);
546 return (UINT_PTR
)dst
;
549 static HANDLE16
convert_handle_32_to_16(UINT_PTR src
, unsigned int flags
)
552 UINT sz
= GlobalSize((HANDLE
)src
);
555 if (!(dst
= GlobalAlloc16(flags
, sz
)))
557 ptr32
= GlobalLock((HANDLE
)src
);
558 ptr16
= GlobalLock16(dst
);
559 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr16
, ptr32
, sz
);
560 GlobalUnlock((HANDLE
)src
);
566 static BOOL
is_old_app( HWND hwnd
)
568 HINSTANCE inst
= (HINSTANCE
)GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
569 return inst
&& !((ULONG_PTR
)inst
>> 16) && (GetExpWinVer16(LOWORD(inst
)) & 0xFF00) == 0x0300;
572 static int find_sub_menu( HMENU
*hmenu
, HMENU16 target
)
574 int i
, pos
, count
= GetMenuItemCount( *hmenu
);
576 for (i
= 0; i
< count
; i
++)
578 HMENU sub
= GetSubMenu( *hmenu
, i
);
580 if (HMENU_16(sub
) == target
) return i
;
581 if ((pos
= find_sub_menu( &sub
, target
)) != -1)
590 /**********************************************************************
591 * WINPROC_CallProc16To32A
593 LRESULT
WINPROC_CallProc16To32A( winproc_callback_t callback
, HWND16 hwnd
, UINT16 msg
,
594 WPARAM16 wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
597 HWND hwnd32
= WIN_Handle32( hwnd
);
604 CREATESTRUCT16
*cs16
= MapSL(lParam
);
606 MDICREATESTRUCTA mdi_cs
;
608 CREATESTRUCT16to32A( cs16
, &cs
);
609 if (GetWindowLongW(hwnd32
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
611 MDICREATESTRUCT16
*mdi_cs16
= MapSL(cs16
->lpCreateParams
);
612 MDICREATESTRUCT16to32A(mdi_cs16
, &mdi_cs
);
613 cs
.lpCreateParams
= &mdi_cs
;
615 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cs
, result
, arg
);
616 CREATESTRUCT32Ato16( &cs
, cs16
);
621 MDICREATESTRUCT16
*cs16
= MapSL(lParam
);
624 MDICREATESTRUCT16to32A( cs16
, &cs
);
625 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cs
, result
, arg
);
626 MDICREATESTRUCT32Ato16( &cs
, cs16
);
631 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32( HIWORD(lParam
) ),
632 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
633 else /* message sent to MDI client */
634 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
636 case WM_MDIGETACTIVE
:
638 BOOL maximized
= FALSE
;
639 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&maximized
, result
, arg
);
640 *result
= MAKELRESULT( LOWORD(*result
), maximized
);
644 ret
= callback( hwnd32
, wParam
? WM_MDIREFRESHMENU
: WM_MDISETMENU
,
645 (WPARAM
)HMENU_32(LOWORD(lParam
)), (LPARAM
)HMENU_32(HIWORD(lParam
)),
648 case WM_GETMINMAXINFO
:
650 MINMAXINFO16
*mmi16
= MapSL(lParam
);
653 MINMAXINFO16to32( mmi16
, &mmi
);
654 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&mmi
, result
, arg
);
655 MINMAXINFO32to16( &mmi
, mmi16
);
658 case WM_WINDOWPOSCHANGING
:
659 case WM_WINDOWPOSCHANGED
:
661 WINDOWPOS16
*winpos16
= MapSL(lParam
);
664 WINDOWPOS16to32( winpos16
, &winpos
);
665 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&winpos
, result
, arg
);
666 WINDOWPOS32to16( &winpos
, winpos16
);
671 NCCALCSIZE_PARAMS16
*nc16
= MapSL(lParam
);
672 NCCALCSIZE_PARAMS nc
;
675 RECT16to32( &nc16
->rgrc
[0], &nc
.rgrc
[0] );
678 RECT16to32( &nc16
->rgrc
[1], &nc
.rgrc
[1] );
679 RECT16to32( &nc16
->rgrc
[2], &nc
.rgrc
[2] );
680 WINDOWPOS16to32( MapSL(nc16
->lppos
), &winpos
);
683 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&nc
, result
, arg
);
684 RECT32to16( &nc
.rgrc
[0], &nc16
->rgrc
[0] );
687 RECT32to16( &nc
.rgrc
[1], &nc16
->rgrc
[1] );
688 RECT32to16( &nc
.rgrc
[2], &nc16
->rgrc
[2] );
689 WINDOWPOS32to16( &winpos
, MapSL(nc16
->lppos
) );
695 COMPAREITEMSTRUCT16
* cis16
= MapSL(lParam
);
696 COMPAREITEMSTRUCT cis
;
697 cis
.CtlType
= cis16
->CtlType
;
698 cis
.CtlID
= cis16
->CtlID
;
699 cis
.hwndItem
= WIN_Handle32( cis16
->hwndItem
);
700 cis
.itemID1
= cis16
->itemID1
;
701 cis
.itemData1
= cis16
->itemData1
;
702 cis
.itemID2
= cis16
->itemID2
;
703 cis
.itemData2
= cis16
->itemData2
;
704 cis
.dwLocaleId
= 0; /* FIXME */
705 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cis
, result
, arg
);
710 DELETEITEMSTRUCT16
* dis16
= MapSL(lParam
);
711 DELETEITEMSTRUCT dis
;
712 dis
.CtlType
= dis16
->CtlType
;
713 dis
.CtlID
= dis16
->CtlID
;
714 dis
.hwndItem
= WIN_Handle32( dis16
->hwndItem
);
715 dis
.itemData
= dis16
->itemData
;
716 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&dis
, result
, arg
);
721 MEASUREITEMSTRUCT16
* mis16
= MapSL(lParam
);
722 MEASUREITEMSTRUCT mis
;
723 mis
.CtlType
= mis16
->CtlType
;
724 mis
.CtlID
= mis16
->CtlID
;
725 mis
.itemID
= mis16
->itemID
;
726 mis
.itemWidth
= mis16
->itemWidth
;
727 mis
.itemHeight
= mis16
->itemHeight
;
728 mis
.itemData
= mis16
->itemData
;
729 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&mis
, result
, arg
);
730 mis16
->itemWidth
= (UINT16
)mis
.itemWidth
;
731 mis16
->itemHeight
= (UINT16
)mis
.itemHeight
;
736 DRAWITEMSTRUCT16
* dis16
= MapSL(lParam
);
738 dis
.CtlType
= dis16
->CtlType
;
739 dis
.CtlID
= dis16
->CtlID
;
740 dis
.itemID
= dis16
->itemID
;
741 dis
.itemAction
= dis16
->itemAction
;
742 dis
.itemState
= dis16
->itemState
;
743 dis
.hwndItem
= (dis
.CtlType
== ODT_MENU
) ? (HWND
)HMENU_32(dis16
->hwndItem
)
744 : WIN_Handle32( dis16
->hwndItem
);
745 dis
.hDC
= HDC_32(dis16
->hDC
);
746 dis
.itemData
= dis16
->itemData
;
747 dis
.rcItem
.left
= dis16
->rcItem
.left
;
748 dis
.rcItem
.top
= dis16
->rcItem
.top
;
749 dis
.rcItem
.right
= dis16
->rcItem
.right
;
750 dis
.rcItem
.bottom
= dis16
->rcItem
.bottom
;
751 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&dis
, result
, arg
);
756 COPYDATASTRUCT16
*cds16
= MapSL(lParam
);
758 cds
.dwData
= cds16
->dwData
;
759 cds
.cbData
= cds16
->cbData
;
760 cds
.lpData
= MapSL(cds16
->lpData
);
761 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cds
, result
, arg
);
767 MSG16
*msg16
= MapSL(lParam
);
769 msg32
.hwnd
= WIN_Handle32( msg16
->hwnd
);
770 msg32
.message
= msg16
->message
;
771 msg32
.wParam
= msg16
->wParam
;
772 msg32
.lParam
= msg16
->lParam
;
773 msg32
.time
= msg16
->time
;
774 msg32
.pt
.x
= msg16
->pt
.x
;
775 msg32
.pt
.y
= msg16
->pt
.y
;
776 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&msg32
, result
, arg
);
779 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
784 next
.hmenuIn
= (HMENU
)lParam
;
787 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&next
, result
, arg
);
788 *result
= MAKELONG( HMENU_16(next
.hmenuNext
), HWND_16(next
.hwndNext
) );
795 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, HIWORD(lParam
) ),
796 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
800 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
801 (LPARAM
)WIN_Handle32( HIWORD(lParam
) ), result
, arg
);
804 if (HIWORD(lParam
) <= CTLCOLOR_STATIC
)
805 ret
= callback( hwnd32
, WM_CTLCOLORMSGBOX
+ HIWORD(lParam
),
806 (WPARAM
)HDC_32(wParam
), (LPARAM
)WIN_Handle32( LOWORD(lParam
) ),
811 case WM_WININICHANGE
:
812 case WM_DEVMODECHANGE
:
813 case WM_ASKCBFORMATNAME
:
815 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)MapSL(lParam
), result
, arg
);
818 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
819 (LPARAM
)HMENU_32(HIWORD(lParam
)), result
, arg
);
822 if((LOWORD(lParam
) & MF_POPUP
) && (LOWORD(lParam
) != 0xFFFF))
824 HMENU hmenu
= HMENU_32(HIWORD(lParam
));
825 int pos
= find_sub_menu( &hmenu
, wParam
);
826 if (pos
== -1) pos
= 0;
829 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
830 (LPARAM
)HMENU_32(HIWORD(lParam
)), result
, arg
);
832 case WM_PARENTNOTIFY
:
833 if ((wParam
== WM_CREATE
) || (wParam
== WM_DESTROY
))
834 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, HIWORD(lParam
) ),
835 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
837 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
840 /* We need this when SetActiveWindow sends a Sendmessage16() to
841 * a 32-bit window. Might be superfluous with 32-bit interprocess
843 if (lParam
) lParam
= HTASK_32(lParam
);
844 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
846 case WM_DDE_INITIATE
:
847 case WM_DDE_TERMINATE
:
848 case WM_DDE_UNADVISE
:
850 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
856 HANDLE16 lo16
= LOWORD(lParam
);
858 if (lo16
&& !(lo32
= convert_handle_16_to_32(lo16
, GMEM_DDESHARE
))) break;
859 lParam
= PackDDElParam( msg
, lo32
, HIWORD(lParam
) );
860 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
862 break; /* FIXME don't know how to free allocated memory (handle) !! */
865 UINT_PTR lo
= LOWORD(lParam
);
866 UINT_PTR hi
= HIWORD(lParam
);
870 if (GlobalGetAtomNameA(hi
, buf
, 2) > 0) flag
|= 1;
871 if (GlobalSize16(hi
) != 0) flag
|= 2;
877 WARN("DDE_ACK: neither atom nor handle!!!\n");
882 break; /* atom, nothing to do */
884 WARN("DDE_ACK: %lx both atom and handle... choosing handle\n", hi
);
887 hi
= convert_handle_16_to_32(hi
, GMEM_DDESHARE
);
890 lParam
= PackDDElParam( WM_DDE_ACK
, lo
, hi
);
891 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
893 break; /* FIXME don't know how to free allocated memory (handle) !! */
895 lParam
= convert_handle_16_to_32( HIWORD(lParam
), GMEM_DDESHARE
);
896 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
897 break; /* FIXME don't know how to free allocated memory (handle) !! */
898 case WM_PAINTCLIPBOARD
:
899 case WM_SIZECLIPBOARD
:
900 FIXME_(msg
)( "message %04x needs translation\n", msg
);
903 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
910 /**********************************************************************
911 * WINPROC_CallProc32ATo16
913 * Call a 16-bit window procedure, translating the 32-bit args.
915 LRESULT
WINPROC_CallProc32ATo16( winproc_callback16_t callback
, HWND hwnd
, UINT msg
,
916 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
925 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)lParam
;
927 MDICREATESTRUCT16 mdi_cs16
;
928 BOOL mdi_child
= (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
);
930 CREATESTRUCT32Ato16( cs32
, &cs
);
931 cs
.lpszName
= MapLS( cs32
->lpszName
);
932 cs
.lpszClass
= MapLS( cs32
->lpszClass
);
936 MDICREATESTRUCTA
*mdi_cs
= cs32
->lpCreateParams
;
937 MDICREATESTRUCT32Ato16( mdi_cs
, &mdi_cs16
);
938 mdi_cs16
.szTitle
= MapLS( mdi_cs
->szTitle
);
939 mdi_cs16
.szClass
= MapLS( mdi_cs
->szClass
);
940 cs
.lpCreateParams
= MapLS( &mdi_cs16
);
942 lParam
= MapLS( &cs
);
943 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
945 UnMapLS( cs
.lpszName
);
946 UnMapLS( cs
.lpszClass
);
949 UnMapLS( cs
.lpCreateParams
);
950 UnMapLS( mdi_cs16
.szTitle
);
951 UnMapLS( mdi_cs16
.szClass
);
957 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)lParam
;
958 MDICREATESTRUCT16 cs
;
960 MDICREATESTRUCT32Ato16( cs32
, &cs
);
961 cs
.szTitle
= MapLS( cs32
->szTitle
);
962 cs
.szClass
= MapLS( cs32
->szClass
);
963 lParam
= MapLS( &cs
);
964 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
966 UnMapLS( cs
.szTitle
);
967 UnMapLS( cs
.szClass
);
971 if (GetWindowLongW( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
972 ret
= callback( HWND_16(hwnd
), msg
, ((HWND
)lParam
== hwnd
),
973 MAKELPARAM( LOWORD(lParam
), LOWORD(wParam
) ), result
, arg
);
975 ret
= callback( HWND_16(hwnd
), msg
, HWND_16( wParam
), 0, result
, arg
);
977 case WM_MDIGETACTIVE
:
978 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
979 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(*result
);
980 *result
= (LRESULT
)WIN_Handle32( LOWORD(*result
) );
983 ret
= callback( HWND_16(hwnd
), msg
, (lParam
== 0),
984 MAKELPARAM( LOWORD(wParam
), LOWORD(lParam
) ), result
, arg
);
986 case WM_GETMINMAXINFO
:
988 MINMAXINFO
*mmi32
= (MINMAXINFO
*)lParam
;
991 MINMAXINFO32to16( mmi32
, &mmi
);
992 lParam
= MapLS( &mmi
);
993 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
995 MINMAXINFO16to32( &mmi
, mmi32
);
1000 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)lParam
;
1001 NCCALCSIZE_PARAMS16 nc
;
1004 RECT32to16( &nc32
->rgrc
[0], &nc
.rgrc
[0] );
1007 RECT32to16( &nc32
->rgrc
[1], &nc
.rgrc
[1] );
1008 RECT32to16( &nc32
->rgrc
[2], &nc
.rgrc
[2] );
1009 WINDOWPOS32to16( nc32
->lppos
, &winpos
);
1010 nc
.lppos
= MapLS( &winpos
);
1012 lParam
= MapLS( &nc
);
1013 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1015 RECT16to32( &nc
.rgrc
[0], &nc32
->rgrc
[0] );
1018 RECT16to32( &nc
.rgrc
[1], &nc32
->rgrc
[1] );
1019 RECT16to32( &nc
.rgrc
[2], &nc32
->rgrc
[2] );
1020 WINDOWPOS16to32( &winpos
, nc32
->lppos
);
1021 UnMapLS( nc
.lppos
);
1025 case WM_WINDOWPOSCHANGING
:
1026 case WM_WINDOWPOSCHANGED
:
1028 WINDOWPOS
*winpos32
= (WINDOWPOS
*)lParam
;
1031 WINDOWPOS32to16( winpos32
, &winpos
);
1032 lParam
= MapLS( &winpos
);
1033 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1035 WINDOWPOS16to32( &winpos
, winpos32
);
1038 case WM_COMPAREITEM
:
1040 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)lParam
;
1041 COMPAREITEMSTRUCT16 cis
;
1042 cis
.CtlType
= cis32
->CtlType
;
1043 cis
.CtlID
= cis32
->CtlID
;
1044 cis
.hwndItem
= HWND_16( cis32
->hwndItem
);
1045 cis
.itemID1
= cis32
->itemID1
;
1046 cis
.itemData1
= cis32
->itemData1
;
1047 cis
.itemID2
= cis32
->itemID2
;
1048 cis
.itemData2
= cis32
->itemData2
;
1049 lParam
= MapLS( &cis
);
1050 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1056 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)lParam
;
1057 DELETEITEMSTRUCT16 dis
;
1058 dis
.CtlType
= dis32
->CtlType
;
1059 dis
.CtlID
= dis32
->CtlID
;
1060 dis
.itemID
= dis32
->itemID
;
1061 dis
.hwndItem
= (dis
.CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
1062 : HWND_16( dis32
->hwndItem
);
1063 dis
.itemData
= dis32
->itemData
;
1064 lParam
= MapLS( &dis
);
1065 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1071 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)lParam
;
1072 DRAWITEMSTRUCT16 dis
;
1073 dis
.CtlType
= dis32
->CtlType
;
1074 dis
.CtlID
= dis32
->CtlID
;
1075 dis
.itemID
= dis32
->itemID
;
1076 dis
.itemAction
= dis32
->itemAction
;
1077 dis
.itemState
= dis32
->itemState
;
1078 dis
.hwndItem
= HWND_16( dis32
->hwndItem
);
1079 dis
.hDC
= HDC_16(dis32
->hDC
);
1080 dis
.itemData
= dis32
->itemData
;
1081 dis
.rcItem
.left
= dis32
->rcItem
.left
;
1082 dis
.rcItem
.top
= dis32
->rcItem
.top
;
1083 dis
.rcItem
.right
= dis32
->rcItem
.right
;
1084 dis
.rcItem
.bottom
= dis32
->rcItem
.bottom
;
1085 lParam
= MapLS( &dis
);
1086 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1090 case WM_MEASUREITEM
:
1092 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)lParam
;
1093 MEASUREITEMSTRUCT16 mis
;
1094 mis
.CtlType
= mis32
->CtlType
;
1095 mis
.CtlID
= mis32
->CtlID
;
1096 mis
.itemID
= mis32
->itemID
;
1097 mis
.itemWidth
= mis32
->itemWidth
;
1098 mis
.itemHeight
= mis32
->itemHeight
;
1099 mis
.itemData
= mis32
->itemData
;
1100 lParam
= MapLS( &mis
);
1101 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1103 mis32
->itemWidth
= mis
.itemWidth
;
1104 mis32
->itemHeight
= mis
.itemHeight
;
1109 COPYDATASTRUCT
*cds32
= (COPYDATASTRUCT
*)lParam
;
1110 COPYDATASTRUCT16 cds
;
1112 cds
.dwData
= cds32
->dwData
;
1113 cds
.cbData
= cds32
->cbData
;
1114 cds
.lpData
= MapLS( cds32
->lpData
);
1115 lParam
= MapLS( &cds
);
1116 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1118 UnMapLS( cds
.lpData
);
1124 MSG
*msg32
= (MSG
*)lParam
;
1127 msg16
.hwnd
= HWND_16( msg32
->hwnd
);
1128 msg16
.message
= msg32
->message
;
1129 msg16
.wParam
= msg32
->wParam
;
1130 msg16
.lParam
= msg32
->lParam
;
1131 msg16
.time
= msg32
->time
;
1132 msg16
.pt
.x
= msg32
->pt
.x
;
1133 msg16
.pt
.y
= msg32
->pt
.y
;
1134 lParam
= MapLS( &msg16
);
1135 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1139 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1143 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1144 ret
= callback( HWND_16(hwnd
), msg
, wParam
, (LPARAM
)next
->hmenuIn
, result
, arg
);
1145 next
->hmenuNext
= HMENU_32( LOWORD(*result
) );
1146 next
->hwndNext
= WIN_Handle32( HIWORD(*result
) );
1151 case WM_ASKCBFORMATNAME
:
1152 wParam
= min( wParam
, 0xff80 ); /* Must be < 64K */
1156 case WM_WININICHANGE
:
1157 case WM_DEVMODECHANGE
:
1158 lParam
= MapLS( (void *)lParam
);
1159 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1166 ret
= callback( HWND_16(hwnd
), msg
, wParam
, MAKELPARAM( (HWND16
)lParam
, HIWORD(wParam
) ),
1171 ret
= callback( HWND_16(hwnd
), msg
, wParam
, MAKELPARAM( HIWORD(wParam
), (HWND16
)lParam
),
1174 case WM_CTLCOLORMSGBOX
:
1175 case WM_CTLCOLOREDIT
:
1176 case WM_CTLCOLORLISTBOX
:
1177 case WM_CTLCOLORBTN
:
1178 case WM_CTLCOLORDLG
:
1179 case WM_CTLCOLORSCROLLBAR
:
1180 case WM_CTLCOLORSTATIC
:
1181 ret
= callback( HWND_16(hwnd
), WM_CTLCOLOR
, wParam
,
1182 MAKELPARAM( (HWND16
)lParam
, msg
- WM_CTLCOLORMSGBOX
), result
, arg
);
1185 if(HIWORD(wParam
) & MF_POPUP
)
1188 if ((HIWORD(wParam
) != 0xffff) || lParam
)
1190 if ((hmenu
= GetSubMenu( (HMENU
)lParam
, LOWORD(wParam
) )))
1192 ret
= callback( HWND_16(hwnd
), msg
, HMENU_16(hmenu
),
1193 MAKELPARAM( HIWORD(wParam
), (HMENU16
)lParam
), result
, arg
);
1200 ret
= callback( HWND_16(hwnd
), msg
, wParam
,
1201 MAKELPARAM( HIWORD(wParam
), (HMENU16
)lParam
), result
, arg
);
1203 case WM_PARENTNOTIFY
:
1204 if ((LOWORD(wParam
) == WM_CREATE
) || (LOWORD(wParam
) == WM_DESTROY
))
1205 ret
= callback( HWND_16(hwnd
), msg
, wParam
,
1206 MAKELPARAM( (HWND16
)lParam
, HIWORD(wParam
) ), result
, arg
);
1208 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1210 case WM_ACTIVATEAPP
:
1211 ret
= callback( HWND_16(hwnd
), msg
, wParam
, HTASK_16( lParam
), result
, arg
);
1214 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
))
1215 ret
= callback( HWND_16(hwnd
), WM_PAINTICON
, 1, lParam
, result
, arg
);
1217 ret
= callback( HWND_16(hwnd
), WM_PAINT
, wParam
, lParam
, result
, arg
);
1220 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
)) msg
= WM_ICONERASEBKGND
;
1221 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1223 case WM_DDE_INITIATE
:
1224 case WM_DDE_TERMINATE
:
1225 case WM_DDE_UNADVISE
:
1226 case WM_DDE_REQUEST
:
1227 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
), lParam
, result
, arg
);
1236 UnpackDDElParam( msg
, lParam
, &lo32
, &hi
);
1237 if (lo32
&& !(lo16
= convert_handle_32_to_16(lo32
, GMEM_DDESHARE
))) break;
1238 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
),
1239 MAKELPARAM(lo16
, hi
), result
, arg
);
1241 break; /* FIXME don't know how to free allocated memory (handle) !! */
1248 UnpackDDElParam( msg
, lParam
, &lo
, &hi
);
1250 if (GlobalGetAtomNameA((ATOM
)hi
, buf
, sizeof(buf
)) > 0) flag
|= 1;
1251 if (GlobalSize((HANDLE
)hi
) != 0) flag
|= 2;
1257 WARN("DDE_ACK: neither atom nor handle!!!\n");
1262 break; /* atom, nothing to do */
1264 WARN("DDE_ACK: %lx both atom and handle... choosing handle\n", hi
);
1267 hi
= convert_handle_32_to_16(hi
, GMEM_DDESHARE
);
1270 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
),
1271 MAKELPARAM(lo
, hi
), result
, arg
);
1273 break; /* FIXME don't know how to free allocated memory (handle) !! */
1274 case WM_DDE_EXECUTE
:
1275 lParam
= MAKELPARAM( 0, convert_handle_32_to_16( lParam
, GMEM_DDESHARE
));
1276 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1277 break; /* FIXME don't know how to free allocated memory (handle) !! */
1279 ret
= callback( HWND_16(hwnd
), SBM_SETRANGE16
, 0, MAKELPARAM(wParam
, lParam
), result
, arg
);
1282 ret
= callback( HWND_16(hwnd
), SBM_GETRANGE16
, wParam
, lParam
, result
, arg
);
1283 *(LPINT
)wParam
= LOWORD(*result
);
1284 *(LPINT
)lParam
= HIWORD(*result
);
1291 ret
= callback( HWND_16(hwnd
), msg
+ BM_GETCHECK16
- BM_GETCHECK
, wParam
, lParam
, result
, arg
);
1299 case EM_SCROLLCARET
:
1302 case EM_GETLINECOUNT
:
1314 case EM_LINEFROMCHAR
:
1315 case EM_SETTABSTOPS
:
1316 case EM_SETPASSWORDCHAR
:
1317 case EM_EMPTYUNDOBUFFER
:
1318 case EM_GETFIRSTVISIBLELINE
:
1319 case EM_SETREADONLY
:
1320 case EM_SETWORDBREAKPROC
:
1321 case EM_GETWORDBREAKPROC
:
1322 case EM_GETPASSWORDCHAR
:
1323 ret
= callback( HWND_16(hwnd
), msg
+ EM_GETSEL16
- EM_GETSEL
, wParam
, lParam
, result
, arg
);
1326 ret
= callback( HWND_16(hwnd
), EM_SETSEL16
, 0, MAKELPARAM( wParam
, lParam
), result
, arg
);
1330 case LB_DELETESTRING
:
1331 case LB_GETANCHORINDEX
:
1332 case LB_GETCARETINDEX
:
1335 case LB_GETHORIZONTALEXTENT
:
1336 case LB_GETITEMDATA
:
1337 case LB_GETITEMHEIGHT
:
1339 case LB_GETSELCOUNT
:
1341 case LB_GETTOPINDEX
:
1342 case LB_RESETCONTENT
:
1343 case LB_SELITEMRANGE
:
1344 case LB_SELITEMRANGEEX
:
1345 case LB_SETANCHORINDEX
:
1346 case LB_SETCARETINDEX
:
1347 case LB_SETCOLUMNWIDTH
:
1349 case LB_SETHORIZONTALEXTENT
:
1350 case LB_SETITEMDATA
:
1351 case LB_SETITEMHEIGHT
:
1353 case LB_SETTOPINDEX
:
1354 ret
= callback( HWND_16(hwnd
), msg
+ LB_ADDSTRING16
- LB_ADDSTRING
, wParam
, lParam
, result
, arg
);
1358 case LB_FINDSTRINGEXACT
:
1359 case LB_INSERTSTRING
:
1360 case LB_SELECTSTRING
:
1364 lParam
= MapLS( (LPSTR
)lParam
);
1365 ret
= callback( HWND_16(hwnd
), msg
+ LB_ADDSTRING16
- LB_ADDSTRING
, wParam
, lParam
, result
, arg
);
1368 case LB_GETSELITEMS
:
1370 INT
*items32
= (INT
*)lParam
;
1371 INT16
*items
, buffer
[512];
1374 wParam
= min( wParam
, 0x7f80 ); /* Must be < 64K */
1375 if (!(items
= get_buffer( buffer
, sizeof(buffer
), wParam
* sizeof(INT16
) ))) break;
1376 lParam
= MapLS( items
);
1377 ret
= callback( HWND_16(hwnd
), LB_GETSELITEMS16
, wParam
, lParam
, result
, arg
);
1379 for (i
= 0; i
< wParam
; i
++) items32
[i
] = items
[i
];
1380 free_buffer( buffer
, items
);
1383 case LB_SETTABSTOPS
:
1386 INT
*stops32
= (INT
*)lParam
;
1387 INT16
*stops
, buffer
[512];
1390 wParam
= min( wParam
, 0x7f80 ); /* Must be < 64K */
1391 if (!(stops
= get_buffer( buffer
, sizeof(buffer
), wParam
* sizeof(INT16
) ))) break;
1392 for (i
= 0; i
< wParam
; i
++) stops
[i
] = stops32
[i
];
1393 lParam
= MapLS( stops
);
1394 ret
= callback( HWND_16(hwnd
), LB_SETTABSTOPS16
, wParam
, lParam
, result
, arg
);
1396 free_buffer( buffer
, stops
);
1398 else ret
= callback( HWND_16(hwnd
), LB_SETTABSTOPS16
, wParam
, lParam
, result
, arg
);
1400 case CB_DELETESTRING
:
1402 case CB_GETLBTEXTLEN
:
1404 case CB_RESETCONTENT
:
1408 case CB_SHOWDROPDOWN
:
1409 case CB_SETITEMDATA
:
1410 case CB_SETITEMHEIGHT
:
1411 case CB_GETITEMHEIGHT
:
1412 case CB_SETEXTENDEDUI
:
1413 case CB_GETEXTENDEDUI
:
1414 case CB_GETDROPPEDSTATE
:
1415 ret
= callback( HWND_16(hwnd
), msg
+ CB_GETEDITSEL16
- CB_GETEDITSEL
, wParam
, lParam
, result
, arg
);
1418 ret
= callback( HWND_16(hwnd
), CB_GETEDITSEL16
, wParam
, lParam
, result
, arg
);
1419 if (wParam
) *((PUINT
)(wParam
)) = LOWORD(*result
);
1420 if (lParam
) *((PUINT
)(lParam
)) = HIWORD(*result
); /* FIXME: subtract 1? */
1424 case CB_FINDSTRINGEXACT
:
1425 case CB_INSERTSTRING
:
1426 case CB_SELECTSTRING
:
1429 lParam
= MapLS( (LPSTR
)lParam
);
1430 ret
= callback( HWND_16(hwnd
), msg
+ CB_GETEDITSEL16
- CB_GETEDITSEL
, wParam
, lParam
, result
, arg
);
1433 case LB_GETITEMRECT
:
1434 case CB_GETDROPPEDCONTROLRECT
:
1436 RECT
*r32
= (RECT
*)lParam
;
1438 lParam
= MapLS( &rect
);
1439 ret
= callback( HWND_16(hwnd
),
1440 (msg
== LB_GETITEMRECT
) ? LB_GETITEMRECT16
: CB_GETDROPPEDCONTROLRECT16
,
1441 wParam
, lParam
, result
, arg
);
1443 RECT16to32( &rect
, r32
);
1446 case WM_PAINTCLIPBOARD
:
1447 case WM_SIZECLIPBOARD
:
1448 FIXME_(msg
)( "message %04x needs translation\n", msg
);
1450 /* the following messages should not be sent to 16-bit apps */
1453 case WM_CAPTURECHANGED
:
1454 case WM_STYLECHANGING
:
1455 case WM_STYLECHANGED
:
1458 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1465 /***********************************************************************
1466 * SendMessage (USER.111)
1468 LRESULT WINAPI
SendMessage16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1471 HWND hwnd
= WIN_Handle32( hwnd16
);
1473 if (hwnd
!= HWND_BROADCAST
&&
1474 GetWindowThreadProcessId( hwnd
, NULL
) == GetCurrentThreadId())
1476 /* call 16-bit window proc directly */
1479 /* first the WH_CALLWNDPROC hook */
1480 call_WH_CALLWNDPROC_hook( hwnd16
, msg
, wparam
, lparam
);
1482 if (!(winproc
= (WNDPROC16
)GetWindowLong16( hwnd16
, GWLP_WNDPROC
))) return 0;
1484 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx\n", hwnd16
, msg
, wparam
, lparam
);
1485 result
= CallWindowProc16( winproc
, hwnd16
, msg
, wparam
, lparam
);
1486 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx returned %08lx\n",
1487 hwnd16
, msg
, wparam
, lparam
, result
);
1489 else /* map to 32-bit unicode for inter-thread/process message */
1491 WINPROC_CallProc16To32A( send_message_callback
, hwnd16
, msg
, wparam
, lparam
, &result
, NULL
);
1497 /***********************************************************************
1498 * PostMessage (USER.110)
1500 BOOL16 WINAPI
PostMessage16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1503 return WINPROC_CallProc16To32A( post_message_callback
, hwnd
, msg
, wparam
, lparam
, &unused
, NULL
);
1507 /***********************************************************************
1508 * PostAppMessage (USER.116)
1510 BOOL16 WINAPI
PostAppMessage16( HTASK16 hTask
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1513 DWORD_PTR tid
= HTASK_32( hTask
);
1515 if (!tid
) return FALSE
;
1516 return WINPROC_CallProc16To32A( post_thread_message_callback
, 0, msg
, wparam
, lparam
,
1517 &unused
, (void *)tid
);
1521 /**********************************************************************
1522 * CallWindowProc (USER.122)
1524 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
1525 WPARAM16 wParam
, LPARAM lParam
)
1527 int index
= winproc_to_index( func
);
1530 if (!func
) return 0;
1532 if (index
== -1 || index
>= MAX_WINPROCS32
)
1533 call_window_proc16( hwnd
, msg
, wParam
, lParam
, &result
, func
);
1536 WNDPROC proc
= (WNDPROC
)func
;
1537 if (thunk_array
&& thunk_array
[index
].proc
) proc
= thunk_array
[index
].proc
;
1538 WINPROC_CallProc16To32A( call_window_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, proc
);
1544 /**********************************************************************
1545 * __wine_call_wndproc (USER.1010)
1547 LRESULT WINAPI
__wine_call_wndproc( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
, WNDPROC proc
)
1550 WINPROC_CallProc16To32A( call_window_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, proc
);
1555 /***********************************************************************
1556 * InSendMessage (USER.192)
1558 BOOL16 WINAPI
InSendMessage16(void)
1560 return InSendMessage();
1564 /***********************************************************************
1565 * ReplyMessage (USER.115)
1567 void WINAPI
ReplyMessage16( LRESULT result
)
1569 ReplyMessage( result
);
1573 /***********************************************************************
1574 * PeekMessage32 (USER.819)
1576 BOOL16 WINAPI
PeekMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
,
1577 UINT16 first
, UINT16 last
, UINT16 flags
,
1578 BOOL16 wHaveParamHigh
)
1582 HWND hwnd
= WIN_Handle32( hwnd16
);
1584 if(USER16_AlertableWait
)
1585 MsgWaitForMultipleObjectsEx( 0, NULL
, 0, 0, MWMO_ALERTABLE
);
1586 if (!PeekMessageA( &msg
, hwnd
, first
, last
, flags
)) return FALSE
;
1588 msg16
->msg
.time
= msg
.time
;
1589 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
1590 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
1591 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
1592 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
1593 &unused
, &msg16
->msg
);
1598 /***********************************************************************
1599 * DefWindowProc (USER.107)
1601 LRESULT WINAPI
DefWindowProc16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
1604 HWND hwnd
= WIN_Handle32( hwnd16
);
1610 CREATESTRUCT16
*cs16
= MapSL(lParam
);
1613 cs32
.lpCreateParams
= ULongToPtr(cs16
->lpCreateParams
);
1614 cs32
.hInstance
= HINSTANCE_32(cs16
->hInstance
);
1615 cs32
.hMenu
= HMENU_32(cs16
->hMenu
);
1616 cs32
.hwndParent
= WIN_Handle32(cs16
->hwndParent
);
1621 cs32
.style
= cs16
->style
;
1622 cs32
.dwExStyle
= cs16
->dwExStyle
;
1623 cs32
.lpszName
= MapSL(cs16
->lpszName
);
1624 cs32
.lpszClass
= MapSL(cs16
->lpszClass
);
1625 return DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&cs32
);
1629 RECT16
*rect16
= MapSL(lParam
);
1632 rect32
.left
= rect16
->left
;
1633 rect32
.top
= rect16
->top
;
1634 rect32
.right
= rect16
->right
;
1635 rect32
.bottom
= rect16
->bottom
;
1637 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&rect32
);
1639 rect16
->left
= rect32
.left
;
1640 rect16
->top
= rect32
.top
;
1641 rect16
->right
= rect32
.right
;
1642 rect16
->bottom
= rect32
.bottom
;
1645 case WM_WINDOWPOSCHANGING
:
1646 case WM_WINDOWPOSCHANGED
:
1648 WINDOWPOS16
*pos16
= MapSL(lParam
);
1651 pos32
.hwnd
= WIN_Handle32(pos16
->hwnd
);
1652 pos32
.hwndInsertAfter
= WIN_Handle32(pos16
->hwndInsertAfter
);
1655 pos32
.cx
= pos16
->cx
;
1656 pos32
.cy
= pos16
->cy
;
1657 pos32
.flags
= pos16
->flags
;
1659 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&pos32
);
1661 pos16
->hwnd
= HWND_16(pos32
.hwnd
);
1662 pos16
->hwndInsertAfter
= HWND_16(pos32
.hwndInsertAfter
);
1665 pos16
->cx
= pos32
.cx
;
1666 pos16
->cy
= pos32
.cy
;
1667 pos16
->flags
= pos32
.flags
;
1672 return DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)MapSL(lParam
) );
1674 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
1679 /***********************************************************************
1680 * DefDlgProc (USER.308)
1682 LRESULT WINAPI
DefDlgProc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
1685 WINPROC_CallProc16To32A( defdlg_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, 0 );
1690 /***********************************************************************
1691 * PeekMessage (USER.109)
1693 BOOL16 WINAPI
PeekMessage16( MSG16
*msg
, HWND16 hwnd
,
1694 UINT16 first
, UINT16 last
, UINT16 flags
)
1696 return PeekMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, flags
, FALSE
);
1700 /***********************************************************************
1701 * GetMessage32 (USER.820)
1703 BOOL16 WINAPI
GetMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
, UINT16 first
,
1704 UINT16 last
, BOOL16 wHaveParamHigh
)
1708 HWND hwnd
= WIN_Handle32( hwnd16
);
1710 if(USER16_AlertableWait
)
1711 MsgWaitForMultipleObjectsEx( 0, NULL
, INFINITE
, 0, MWMO_ALERTABLE
);
1712 GetMessageA( &msg
, hwnd
, first
, last
);
1713 msg16
->msg
.time
= msg
.time
;
1714 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
1715 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
1716 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
1717 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
1718 &unused
, &msg16
->msg
);
1720 TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
1721 msg16
->msg
.message
, hwnd
, first
, last
);
1723 return msg16
->msg
.message
!= WM_QUIT
;
1727 /***********************************************************************
1728 * GetMessage (USER.108)
1730 BOOL16 WINAPI
GetMessage16( MSG16
*msg
, HWND16 hwnd
, UINT16 first
, UINT16 last
)
1732 return GetMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, FALSE
);
1736 /***********************************************************************
1737 * TranslateMessage32 (USER.821)
1739 BOOL16 WINAPI
TranslateMessage32_16( const MSG32_16
*msg
, BOOL16 wHaveParamHigh
)
1743 msg32
.hwnd
= WIN_Handle32( msg
->msg
.hwnd
);
1744 msg32
.message
= msg
->msg
.message
;
1745 msg32
.wParam
= MAKEWPARAM( msg
->msg
.wParam
, wHaveParamHigh
? msg
->wParamHigh
: 0 );
1746 msg32
.lParam
= msg
->msg
.lParam
;
1747 return TranslateMessage( &msg32
);
1751 /***********************************************************************
1752 * TranslateMessage (USER.113)
1754 BOOL16 WINAPI
TranslateMessage16( const MSG16
*msg
)
1756 return TranslateMessage32_16( (const MSG32_16
*)msg
, FALSE
);
1760 /***********************************************************************
1761 * DispatchMessage (USER.114)
1763 LONG WINAPI
DispatchMessage16( const MSG16
* msg
)
1768 /* Process timer messages */
1769 if ((msg
->message
== WM_TIMER
) || (msg
->message
== WM_SYSTIMER
))
1772 return CallWindowProc16( (WNDPROC16
)msg
->lParam
, msg
->hwnd
,
1773 msg
->message
, msg
->wParam
, GetTickCount() );
1776 if (!(winproc
= (WNDPROC16
)GetWindowLong16( msg
->hwnd
, GWLP_WNDPROC
)))
1778 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
1781 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx\n", msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1782 retval
= CallWindowProc16( winproc
, msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1783 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx returned %08lx\n",
1784 msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
, retval
);
1789 /***********************************************************************
1790 * DispatchMessage32 (USER.822)
1792 LONG WINAPI
DispatchMessage32_16( const MSG32_16
*msg16
, BOOL16 wHaveParamHigh
)
1794 if (wHaveParamHigh
== FALSE
)
1795 return DispatchMessage16( &msg16
->msg
);
1800 msg
.hwnd
= WIN_Handle32( msg16
->msg
.hwnd
);
1801 msg
.message
= msg16
->msg
.message
;
1802 msg
.wParam
= MAKEWPARAM( msg16
->msg
.wParam
, msg16
->wParamHigh
);
1803 msg
.lParam
= msg16
->msg
.lParam
;
1804 msg
.time
= msg16
->msg
.time
;
1805 msg
.pt
.x
= msg16
->msg
.pt
.x
;
1806 msg
.pt
.y
= msg16
->msg
.pt
.y
;
1807 return DispatchMessageA( &msg
);
1812 /***********************************************************************
1813 * IsDialogMessage (USER.90)
1815 BOOL16 WINAPI
IsDialogMessage16( HWND16 hwndDlg
, MSG16
*msg16
)
1820 msg
.hwnd
= WIN_Handle32(msg16
->hwnd
);
1821 hwndDlg32
= WIN_Handle32(hwndDlg
);
1823 switch(msg16
->message
)
1828 msg
.message
= msg16
->message
;
1829 msg
.wParam
= msg16
->wParam
;
1830 msg
.lParam
= msg16
->lParam
;
1831 msg
.time
= msg16
->time
;
1832 msg
.pt
.x
= msg16
->pt
.x
;
1833 msg
.pt
.y
= msg16
->pt
.y
;
1834 return IsDialogMessageA( hwndDlg32
, &msg
);
1837 if ((hwndDlg32
!= msg
.hwnd
) && !IsChild( hwndDlg32
, msg
.hwnd
)) return FALSE
;
1838 TranslateMessage16( msg16
);
1839 DispatchMessage16( msg16
);
1844 /***********************************************************************
1845 * MsgWaitForMultipleObjects (USER.640)
1847 DWORD WINAPI
MsgWaitForMultipleObjects16( DWORD count
, const HANDLE
*handles
,
1848 BOOL wait_all
, DWORD timeout
, DWORD mask
)
1850 return MsgWaitForMultipleObjectsEx( count
, handles
, timeout
, mask
,
1851 wait_all
? MWMO_WAITALL
: 0 );
1855 /**********************************************************************
1856 * SetDoubleClickTime (USER.20)
1858 void WINAPI
SetDoubleClickTime16( UINT16 interval
)
1860 SetDoubleClickTime( interval
);
1864 /**********************************************************************
1865 * GetDoubleClickTime (USER.21)
1867 UINT16 WINAPI
GetDoubleClickTime16(void)
1869 return GetDoubleClickTime();
1873 /***********************************************************************
1874 * PostQuitMessage (USER.6)
1876 void WINAPI
PostQuitMessage16( INT16 exitCode
)
1878 PostQuitMessage( exitCode
);
1882 /**********************************************************************
1883 * GetKeyState (USER.106)
1885 INT16 WINAPI
GetKeyState16(INT16 vkey
)
1887 return GetKeyState(vkey
);
1891 /**********************************************************************
1892 * GetKeyboardState (USER.222)
1894 BOOL WINAPI
GetKeyboardState16( LPBYTE state
)
1896 return GetKeyboardState( state
);
1900 /**********************************************************************
1901 * SetKeyboardState (USER.223)
1903 BOOL WINAPI
SetKeyboardState16( LPBYTE state
)
1905 return SetKeyboardState( state
);
1909 /***********************************************************************
1910 * SetMessageQueue (USER.266)
1912 BOOL16 WINAPI
SetMessageQueue16( INT16 size
)
1914 return SetMessageQueue( size
);
1918 /***********************************************************************
1919 * UserYield (USER.332)
1921 void WINAPI
UserYield16(void)
1924 PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
| PM_QS_SENDMESSAGE
);
1928 /***********************************************************************
1929 * GetQueueStatus (USER.334)
1931 DWORD WINAPI
GetQueueStatus16( UINT16 flags
)
1933 return GetQueueStatus( flags
);
1937 /***********************************************************************
1938 * GetInputState (USER.335)
1940 BOOL16 WINAPI
GetInputState16(void)
1942 return GetInputState();
1946 /**********************************************************************
1947 * TranslateAccelerator (USER.178)
1949 INT16 WINAPI
TranslateAccelerator16( HWND16 hwnd
, HACCEL16 hAccel
, LPMSG16 msg
)
1954 msg32
.message
= msg
->message
;
1955 /* msg32.hwnd not used */
1956 msg32
.wParam
= msg
->wParam
;
1957 msg32
.lParam
= msg
->lParam
;
1958 return TranslateAcceleratorW( WIN_Handle32(hwnd
), HACCEL_32(hAccel
), &msg32
);
1962 /**********************************************************************
1963 * TranslateMDISysAccel (USER.451)
1965 BOOL16 WINAPI
TranslateMDISysAccel16( HWND16 hwndClient
, LPMSG16 msg
)
1967 if (msg
->message
== WM_KEYDOWN
|| msg
->message
== WM_SYSKEYDOWN
)
1970 msg32
.hwnd
= WIN_Handle32(msg
->hwnd
);
1971 msg32
.message
= msg
->message
;
1972 msg32
.wParam
= msg
->wParam
;
1973 msg32
.lParam
= msg
->lParam
;
1974 /* MDICLIENTINFO is still the same for win32 and win16 ... */
1975 return TranslateMDISysAccel( WIN_Handle32(hwndClient
), &msg32
);
1981 /***********************************************************************
1984 static LRESULT
button_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
1986 static const UINT msg16_offset
= BM_GETCHECK16
- BM_GETCHECK
;
1995 return wow_handlers32
.button_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
1997 return wow_handlers32
.button_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2002 /***********************************************************************
2005 static LRESULT
combo_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2007 static const UINT msg16_offset
= CB_GETEDITSEL16
- CB_GETEDITSEL
;
2011 case CB_INSERTSTRING16
:
2012 case CB_SELECTSTRING16
:
2013 case CB_FINDSTRING16
:
2014 case CB_FINDSTRINGEXACT16
:
2015 wParam
= (INT
)(INT16
)wParam
;
2017 case CB_ADDSTRING16
:
2019 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2020 if ((style
& CBS_HASSTRINGS
) || !(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)))
2021 lParam
= (LPARAM
)MapSL(lParam
);
2022 msg
-= msg16_offset
;
2025 case CB_SETITEMHEIGHT16
:
2026 case CB_GETITEMHEIGHT16
:
2027 case CB_SETCURSEL16
:
2028 case CB_GETLBTEXTLEN16
:
2029 case CB_GETITEMDATA16
:
2030 case CB_SETITEMDATA16
:
2031 wParam
= (INT
)(INT16
)wParam
; /* signed integer */
2032 msg
-= msg16_offset
;
2034 case CB_GETDROPPEDCONTROLRECT16
:
2035 lParam
= (LPARAM
)MapSL(lParam
);
2039 RECT16
*r16
= (RECT16
*)lParam
;
2040 wow_handlers32
.combo_proc( hwnd
, CB_GETDROPPEDCONTROLRECT
, wParam
, (LPARAM
)&r
, FALSE
);
2043 r16
->right
= r
.right
;
2044 r16
->bottom
= r
.bottom
;
2048 if (wParam
& DDL_DRIVES
) wParam
|= DDL_EXCLUSIVE
;
2049 lParam
= (LPARAM
)MapSL(lParam
);
2050 msg
-= msg16_offset
;
2052 case CB_GETLBTEXT16
:
2053 wParam
= (INT
)(INT16
)wParam
;
2054 lParam
= (LPARAM
)MapSL(lParam
);
2055 msg
-= msg16_offset
;
2057 case CB_GETEDITSEL16
:
2058 wParam
= lParam
= 0; /* just in case */
2059 msg
-= msg16_offset
;
2061 case CB_LIMITTEXT16
:
2062 case CB_SETEDITSEL16
:
2063 case CB_DELETESTRING16
:
2064 case CB_RESETCONTENT16
:
2065 case CB_GETDROPPEDSTATE16
:
2066 case CB_SHOWDROPDOWN16
:
2068 case CB_GETCURSEL16
:
2069 case CB_SETEXTENDEDUI16
:
2070 case CB_GETEXTENDEDUI16
:
2071 msg
-= msg16_offset
;
2074 return wow_handlers32
.combo_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2076 return wow_handlers32
.combo_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2079 /*********************************************************************
2080 * edit_lock_buffer (internal)
2082 * A 16 bit application might send an EM_GETHANDLE message and expect a HLOCAL16
2083 * (16 bit SEG:OFF handler). From that moment on we have to keep using this
2084 * 16 bit memory handler, because it is supposed to be valid at all times after
2086 * We create a HLOCAL16 buffer in edit_get_handle and copy the text from the
2087 * HLOCAL buffer, when needed
2091 #define GWW_HANDLE16 sizeof(void*)
2093 static void edit_lock_buffer( HWND hwnd
)
2095 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2096 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2101 if (!hloc16
) return;
2102 if (!(hloc32
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return;
2104 oldDS
= stack16
->ds
;
2105 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2106 size
= LocalSize16(hloc16
);
2107 if (LocalReAlloc( hloc32
, size
, LMEM_MOVEABLE
))
2109 char *text
= MapSL( LocalLock16( hloc16
));
2110 char *dest
= LocalLock( hloc32
);
2111 memcpy( dest
, text
, size
);
2112 LocalUnlock( hloc32
);
2113 LocalUnlock16( hloc16
);
2115 stack16
->ds
= oldDS
;
2119 static void edit_unlock_buffer( HWND hwnd
)
2121 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2122 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2127 if (!hloc16
) return;
2128 if (!(hloc32
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return;
2129 size
= LocalSize( hloc32
);
2131 oldDS
= stack16
->ds
;
2132 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2133 if (LocalReAlloc16( hloc16
, size
, LMEM_MOVEABLE
))
2135 char *text
= LocalLock( hloc32
);
2136 char *dest
= MapSL( LocalLock16( hloc16
));
2137 memcpy( dest
, text
, size
);
2138 LocalUnlock( hloc32
);
2139 LocalUnlock16( hloc16
);
2141 stack16
->ds
= oldDS
;
2144 static HLOCAL16
edit_get_handle( HWND hwnd
)
2149 STACK16FRAME
* stack16
;
2151 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2153 if (hloc16
) return hloc16
;
2155 if (!(hloc
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return 0;
2156 alloc_size
= LocalSize( hloc
);
2158 stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2159 oldDS
= stack16
->ds
;
2160 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2162 if (!LocalHeapSize16())
2164 if (!LocalInit16(stack16
->ds
, 0, GlobalSize16(stack16
->ds
)))
2166 ERR("could not initialize local heap\n");
2171 if (!(hloc16
= LocalAlloc16(LMEM_MOVEABLE
| LMEM_ZEROINIT
, alloc_size
)))
2173 ERR("could not allocate new 16 bit buffer\n");
2177 if (!(textA
= MapSL(LocalLock16( hloc16
))))
2179 ERR("could not lock new 16 bit buffer\n");
2180 LocalFree16(hloc16
);
2184 memcpy( textA
, LocalLock( hloc
), alloc_size
);
2185 LocalUnlock( hloc
);
2186 LocalUnlock16( hloc16
);
2187 SetWindowWord( hwnd
, GWW_HANDLE16
, hloc16
);
2190 stack16
->ds
= oldDS
;
2194 static void edit_set_handle( HWND hwnd
, HLOCAL16 hloc16
)
2196 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2197 HINSTANCE16 hInstance
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2198 HANDLE16 oldDS
= stack16
->ds
;
2203 if (!(GetWindowLongW( hwnd
, GWL_STYLE
) & ES_MULTILINE
)) return;
2204 if (!hloc16
) return;
2206 stack16
->ds
= hInstance
;
2207 count
= LocalSize16(hloc16
);
2208 text
= MapSL(LocalLock16(hloc16
));
2209 if ((hloc32
= LocalAlloc(LMEM_MOVEABLE
, count
)))
2211 memcpy( LocalLock(hloc32
), text
, count
);
2212 LocalUnlock(hloc32
);
2213 LocalUnlock16(hloc16
);
2214 SetWindowWord( hwnd
, GWW_HANDLE16
, hloc16
);
2216 stack16
->ds
= oldDS
;
2218 if (hloc32
) wow_handlers32
.edit_proc( hwnd
, EM_SETHANDLE
, (WPARAM
)hloc32
, 0, FALSE
);
2221 static void edit_destroy_handle( HWND hwnd
)
2223 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2226 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2227 HANDLE16 oldDS
= stack16
->ds
;
2229 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2230 while (LocalUnlock16(hloc16
)) ;
2231 LocalFree16(hloc16
);
2232 stack16
->ds
= oldDS
;
2233 SetWindowWord( hwnd
, GWW_HANDLE16
, 0 );
2237 /*********************************************************************
2240 static LRESULT
edit_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2242 static const UINT msg16_offset
= EM_GETSEL16
- EM_GETSEL
;
2245 edit_lock_buffer( hwnd
);
2249 case EM_SCROLLCARET16
:
2250 case EM_GETMODIFY16
:
2251 case EM_SETMODIFY16
:
2252 case EM_GETLINECOUNT16
:
2254 case EM_LINELENGTH16
:
2255 case EM_LIMITTEXT16
:
2259 case EM_LINEFROMCHAR16
:
2260 case EM_SETPASSWORDCHAR16
:
2261 case EM_EMPTYUNDOBUFFER16
:
2262 case EM_SETREADONLY16
:
2263 case EM_GETPASSWORDCHAR16
:
2264 /* these messages missing from specs */
2269 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2272 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, 0, 0, FALSE
);
2274 case EM_REPLACESEL16
:
2276 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)MapSL(lParam
), FALSE
);
2278 case EM_LINESCROLL16
:
2279 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, (INT
)(SHORT
)HIWORD(lParam
),
2280 (INT
)(SHORT
)LOWORD(lParam
), FALSE
);
2282 case EM_LINEINDEX16
:
2283 if ((INT16
)wParam
== -1) wParam
= -1;
2284 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2287 if ((short)LOWORD(lParam
) == -1)
2294 wParam
= LOWORD(lParam
);
2295 lParam
= HIWORD(lParam
);
2297 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2303 RECT16
*r16
= MapSL(lParam
);
2304 wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)&rect
, FALSE
);
2305 r16
->left
= rect
.left
;
2306 r16
->top
= rect
.top
;
2307 r16
->right
= rect
.right
;
2308 r16
->bottom
= rect
.bottom
;
2312 case EM_SETRECTNP16
:
2316 RECT16
*r16
= MapSL(lParam
);
2317 rect
.left
= r16
->left
;
2318 rect
.top
= r16
->top
;
2319 rect
.right
= r16
->right
;
2320 rect
.bottom
= r16
->bottom
;
2321 wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)&rect
, FALSE
);
2324 case EM_SETHANDLE16
:
2325 edit_set_handle( hwnd
, (HLOCAL16
)wParam
);
2327 case EM_GETHANDLE16
:
2328 result
= edit_get_handle( hwnd
);
2330 case EM_SETTABSTOPS16
:
2332 INT16
*tabs16
= MapSL(lParam
);
2333 INT i
, count
= wParam
, *tabs
= NULL
;
2336 if (!(tabs
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*tabs
) ))) return 0;
2337 for (i
= 0; i
< count
; i
++) tabs
[i
] = tabs16
[i
];
2339 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, count
, (LPARAM
)tabs
, FALSE
);
2340 HeapFree( GetProcessHeap(), 0, tabs
);
2343 case EM_GETFIRSTVISIBLELINE16
:
2344 if (!(GetWindowLongW( hwnd
, GWL_STYLE
) & ES_MULTILINE
)) break;
2345 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2347 case EM_SETWORDBREAKPROC16
:
2349 struct word_break_thunk
*thunk
= add_word_break_thunk( (EDITWORDBREAKPROC16
)lParam
);
2350 result
= wow_handlers32
.edit_proc( hwnd
, EM_SETWORDBREAKPROC
, wParam
, (LPARAM
)thunk
, FALSE
);
2353 case EM_GETWORDBREAKPROC16
:
2354 result
= wow_handlers32
.edit_proc( hwnd
, EM_GETWORDBREAKPROC
, wParam
, lParam
, FALSE
);
2355 result
= (LRESULT
)get_word_break_thunk( (EDITWORDBREAKPROCA
)result
);
2358 edit_destroy_handle( hwnd
);
2359 return wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
); /* no unlock on destroy */
2362 if (LOWORD(wParam
) == EM_GETTHUMB16
|| LOWORD(wParam
) == EM_LINESCROLL16
) wParam
-= msg16_offset
;
2363 result
= wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2366 result
= wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2369 edit_unlock_buffer( hwnd
);
2374 /***********************************************************************
2377 static LRESULT
listbox_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2379 static const UINT msg16_offset
= LB_ADDSTRING16
- LB_ADDSTRING
;
2385 if (is_old_app( hwnd
))
2387 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2388 int height
, remaining
, item_height
;
2391 /* give a margin for error to old 16 bits programs - if we need
2392 less than the height of the nonclient area, round to the
2393 *next* number of items */
2395 if (!(style
& LBS_NOINTEGRALHEIGHT
) && !(style
& LBS_OWNERDRAWVARIABLE
))
2397 GetClientRect( hwnd
, &rect
);
2398 height
= rect
.bottom
- rect
.top
;
2399 item_height
= wow_handlers32
.listbox_proc( hwnd
, LB_GETITEMHEIGHT
, 0, 0, FALSE
);
2400 remaining
= item_height
? (height
% item_height
) : 0;
2401 if ((height
> item_height
) && remaining
)
2403 GetWindowRect( hwnd
, &rect
);
2404 if ((item_height
- remaining
) <= rect
.bottom
- rect
.top
- height
)
2405 remaining
= remaining
- item_height
;
2406 TRACE( "[%p]: changing height %d -> %d\n", hwnd
, height
, height
- remaining
);
2407 SetWindowPos( hwnd
, 0, 0, 0, rect
.right
- rect
.left
,
2408 rect
.bottom
- rect
.top
- remaining
,
2409 SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOMOVE
);
2414 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2416 case LB_RESETCONTENT16
:
2417 case LB_DELETESTRING16
:
2418 case LB_GETITEMDATA16
:
2419 case LB_SETITEMDATA16
:
2421 case LB_GETTEXTLEN16
:
2422 case LB_GETCURSEL16
:
2423 case LB_GETTOPINDEX16
:
2424 case LB_GETITEMHEIGHT16
:
2425 case LB_SETCARETINDEX16
:
2426 case LB_GETCARETINDEX16
:
2427 case LB_SETTOPINDEX16
:
2428 case LB_SETCOLUMNWIDTH16
:
2429 case LB_GETSELCOUNT16
:
2430 case LB_SELITEMRANGE16
:
2431 case LB_SELITEMRANGEEX16
:
2432 case LB_GETHORIZONTALEXTENT16
:
2433 case LB_SETHORIZONTALEXTENT16
:
2434 case LB_GETANCHORINDEX16
:
2437 msg
-= msg16_offset
;
2441 case LB_SETCURSEL16
:
2442 case LB_SETANCHORINDEX16
:
2443 wParam
= (INT
)(INT16
)wParam
;
2444 msg
-= msg16_offset
;
2446 case LB_INSERTSTRING16
:
2447 case LB_FINDSTRING16
:
2448 case LB_FINDSTRINGEXACT16
:
2449 case LB_SELECTSTRING16
:
2450 wParam
= (INT
)(INT16
)wParam
;
2452 case LB_ADDSTRING16
:
2455 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2456 if ((style
& LBS_HASSTRINGS
) || !(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)))
2457 lParam
= (LPARAM
)MapSL(lParam
);
2458 msg
-= msg16_offset
;
2462 lParam
= (LPARAM
)MapSL(lParam
);
2463 msg
-= msg16_offset
;
2465 case LB_SETITEMHEIGHT16
:
2466 lParam
= LOWORD(lParam
);
2467 msg
-= msg16_offset
;
2469 case LB_GETITEMRECT16
:
2472 RECT16
*r16
= MapSL(lParam
);
2473 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_GETITEMRECT
, (INT16
)wParam
, (LPARAM
)&rect
, FALSE
);
2474 r16
->left
= rect
.left
;
2475 r16
->top
= rect
.top
;
2476 r16
->right
= rect
.right
;
2477 r16
->bottom
= rect
.bottom
;
2480 case LB_GETSELITEMS16
:
2482 INT16
*array16
= MapSL( lParam
);
2483 INT i
, count
= (INT16
)wParam
, *array
;
2484 if (!(array
= HeapAlloc( GetProcessHeap(), 0, wParam
* sizeof(*array
) ))) return LB_ERRSPACE
;
2485 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_GETSELITEMS
, count
, (LPARAM
)array
, FALSE
);
2486 for (i
= 0; i
< ret
; i
++) array16
[i
] = array
[i
];
2487 HeapFree( GetProcessHeap(), 0, array
);
2491 /* according to Win16 docs, DDL_DRIVES should make DDL_EXCLUSIVE
2492 * be set automatically (this is different in Win32) */
2493 if (wParam
& DDL_DRIVES
) wParam
|= DDL_EXCLUSIVE
;
2494 lParam
= (LPARAM
)MapSL(lParam
);
2495 msg
-= msg16_offset
;
2497 case LB_SETTABSTOPS16
:
2499 INT i
, count
, *tabs
= NULL
;
2500 INT16
*tabs16
= MapSL( lParam
);
2502 if ((count
= (INT16
)wParam
) > 0)
2504 if (!(tabs
= HeapAlloc( GetProcessHeap(), 0, wParam
* sizeof(*tabs
) ))) return LB_ERRSPACE
;
2505 for (i
= 0; i
< count
; i
++) tabs
[i
] = tabs16
[i
] << 1; /* FIXME */
2507 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_SETTABSTOPS
, count
, (LPARAM
)tabs
, FALSE
);
2508 HeapFree( GetProcessHeap(), 0, tabs
);
2512 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2514 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2518 /***********************************************************************
2521 static LRESULT
mdiclient_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2523 if (msg
== WM_CREATE
)
2525 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
2526 HINSTANCE instance
= (HINSTANCE
)GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2527 BOOL is_win32
= !instance
|| ((ULONG_PTR
)instance
>> 16);
2529 /* Translation layer doesn't know what's in the cs->lpCreateParams
2530 * so we have to keep track of what environment we're in. */
2533 void *orig
= cs
->lpCreateParams
;
2535 CLIENTCREATESTRUCT ccs
;
2536 CLIENTCREATESTRUCT16
*ccs16
= MapSL( PtrToUlong( orig
));
2538 ccs
.hWindowMenu
= HMENU_32(ccs16
->hWindowMenu
);
2539 ccs
.idFirstChild
= ccs16
->idFirstChild
;
2540 cs
->lpCreateParams
= &ccs
;
2541 ret
= wow_handlers32
.mdiclient_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2542 cs
->lpCreateParams
= orig
;
2546 return wow_handlers32
.mdiclient_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2550 /***********************************************************************
2553 static LRESULT
scrollbar_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2555 static const UINT msg16_offset
= SBM_SETPOS16
- SBM_SETPOS
;
2561 case SBM_ENABLE_ARROWS16
:
2562 msg
-= msg16_offset
;
2564 case SBM_SETRANGE16
:
2565 msg
= wParam
? SBM_SETRANGEREDRAW
: SBM_SETRANGE
;
2566 wParam
= LOWORD(lParam
);
2567 lParam
= HIWORD(lParam
);
2569 case SBM_GETRANGE16
:
2572 wow_handlers32
.scrollbar_proc( hwnd
, SBM_GETRANGE
, (WPARAM
)&min
, (LPARAM
)&max
, FALSE
);
2573 return MAKELRESULT(min
, max
);
2576 return wow_handlers32
.scrollbar_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2578 return wow_handlers32
.scrollbar_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2582 /***********************************************************************
2585 static LRESULT
static_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2591 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
2592 LRESULT ret
= wow_handlers32
.static_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2595 if (((ULONG_PTR
)cs
->hInstance
>> 16)) return ret
; /* 32-bit instance, nothing to do */
2596 switch (cs
->style
& SS_TYPEMASK
)
2600 HICON16 icon
= LoadIcon16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2601 if (!icon
) icon
= LoadCursor16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2602 if (icon
) wow_handlers32
.static_proc( hwnd
, STM_SETIMAGE
, IMAGE_ICON
,
2603 (LPARAM
)get_icon_32(icon
), FALSE
);
2608 HBITMAP16 bitmap
= LoadBitmap16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2609 if (bitmap
) wow_handlers32
.static_proc( hwnd
, STM_SETIMAGE
, IMAGE_BITMAP
,
2610 (LPARAM
)HBITMAP_32(bitmap
), FALSE
);
2617 wParam
= (WPARAM
)get_icon_32( (HICON16
)wParam
);
2618 return wow_handlers32
.static_proc( hwnd
, STM_SETICON
, wParam
, lParam
, FALSE
);
2620 return get_icon_16( (HICON
)wow_handlers32
.static_proc( hwnd
, STM_GETICON
, wParam
, lParam
, FALSE
));
2622 return wow_handlers32
.static_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2627 /***********************************************************************
2630 static DWORD
wait_message16( DWORD count
, const HANDLE
*handles
, DWORD timeout
, DWORD mask
, DWORD flags
)
2634 ReleaseThunkLock( &lock
);
2635 ret
= wow_handlers32
.wait_message( count
, handles
, timeout
, mask
, flags
);
2636 RestoreThunkLock( lock
);
2641 /***********************************************************************
2644 HWND
create_window16( CREATESTRUCTW
*cs
, LPCWSTR className
, HINSTANCE instance
, BOOL unicode
)
2646 /* map to module handle */
2647 if (instance
&& !((ULONG_PTR
)instance
>> 16))
2648 instance
= HINSTANCE_32( GetExePtr( HINSTANCE_16(instance
) ));
2650 return wow_handlers32
.create_window( cs
, className
, instance
, unicode
);
2654 /***********************************************************************
2657 static void free_icon_param( ULONG_PTR param
)
2659 GlobalFree16( LOWORD(param
) );
2663 void register_wow_handlers(void)
2665 static const struct wow_handlers16 handlers16
=
2676 call_window_proc_Ato16
,
2677 call_dialog_proc_Ato16
,
2681 UserRegisterWowHandlers( &handlers16
, &wow_handlers32
);