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
22 #include "wine/port.h"
28 #include "wine/winuser16.h"
32 #include "user_private.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(msg
);
36 WINE_DECLARE_DEBUG_CHANNEL(message
);
38 DWORD USER16_AlertableWait
= 0;
40 struct wow_handlers32 wow_handlers32
;
42 static LRESULT
cwp_hook_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
43 LRESULT
*result
, void *arg
)
52 return HOOK_CallHooks( WH_CALLWNDPROC
, HC_ACTION
, 1, (LPARAM
)&cwp
, FALSE
);
55 static LRESULT
send_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
56 LRESULT
*result
, void *arg
)
58 *result
= SendMessageA( hwnd
, msg
, wp
, lp
);
62 static LRESULT
post_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
63 LRESULT
*result
, void *arg
)
66 return PostMessageA( hwnd
, msg
, wp
, lp
);
69 static LRESULT
post_thread_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
70 LRESULT
*result
, void *arg
)
72 DWORD_PTR tid
= (DWORD_PTR
)arg
;
74 return PostThreadMessageA( tid
, msg
, wp
, lp
);
77 static LRESULT
get_message_callback( HWND16 hwnd
, UINT16 msg
, WPARAM16 wp
, LPARAM lp
,
78 LRESULT
*result
, void *arg
)
90 static LRESULT
defdlg_proc_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
91 LRESULT
*result
, void *arg
)
93 *result
= DefDlgProcA( hwnd
, msg
, wp
, lp
);
97 static LRESULT
call_window_proc_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
98 LRESULT
*result
, void *arg
)
101 *result
= CallWindowProcA( proc
, hwnd
, msg
, wp
, lp
);
106 /**********************************************************************
107 * Support for window procedure thunks
110 #include "pshpack1.h"
113 BYTE popl_eax
; /* popl %eax (return address) */
114 BYTE pushl_func
; /* pushl $proc */
116 BYTE pushl_eax
; /* pushl %eax */
117 BYTE ljmp
; /* ljmp relay*/
118 DWORD relay_offset
; /* __wine_call_wndproc */
123 #define WINPROC_HANDLE (~0u >> 16)
124 #define MAX_WINPROCS32 4096
125 #define MAX_WINPROCS16 1024
127 static WNDPROC16 winproc16_array
[MAX_WINPROCS16
];
128 static unsigned int winproc16_used
;
130 static WINPROC_THUNK
*thunk_array
;
131 static UINT thunk_selector
;
133 /* return the window proc index for a given handle, or -1 for an invalid handle
134 * indices 0 .. MAX_WINPROCS32-1 are for 32-bit procs,
135 * indices MAX_WINPROCS32 .. MAX_WINPROCS32+MAX_WINPROCS16-1 for 16-bit procs */
136 static int winproc_to_index( WNDPROC16 handle
)
140 if (HIWORD(handle
) == thunk_selector
)
142 index
= LOWORD(handle
) / sizeof(WINPROC_THUNK
);
143 /* check alignment */
144 if (index
* sizeof(WINPROC_THUNK
) != LOWORD(handle
)) return -1;
145 /* check array limits */
146 if (index
>= MAX_WINPROCS32
) return -1;
150 index
= LOWORD(handle
);
151 if ((ULONG_PTR
)handle
>> 16 != WINPROC_HANDLE
) return -1;
152 /* check array limits */
153 if (index
>= winproc16_used
+ MAX_WINPROCS32
) return -1;
158 /* allocate a 16-bit thunk for an existing window proc */
159 static WNDPROC16
alloc_win16_thunk( WNDPROC handle
)
161 static FARPROC16 relay
;
162 WINPROC_THUNK
*thunk
;
163 UINT index
= LOWORD( handle
);
165 if (index
>= MAX_WINPROCS32
) /* already a 16-bit proc */
166 return winproc16_array
[index
- MAX_WINPROCS32
];
168 if (!thunk_array
) /* allocate the array and its selector */
172 assert( MAX_WINPROCS16
* sizeof(WINPROC_THUNK
) <= 0x10000 );
174 if (!(thunk_selector
= wine_ldt_alloc_entries(1))) return NULL
;
175 if (!(thunk_array
= VirtualAlloc( NULL
, MAX_WINPROCS16
* sizeof(WINPROC_THUNK
), MEM_COMMIT
,
176 PAGE_EXECUTE_READWRITE
))) return NULL
;
177 wine_ldt_set_base( &entry
, thunk_array
);
178 wine_ldt_set_limit( &entry
, MAX_WINPROCS16
* sizeof(WINPROC_THUNK
) - 1 );
179 wine_ldt_set_flags( &entry
, WINE_LDT_FLAGS_CODE
| WINE_LDT_FLAGS_32BIT
);
180 wine_ldt_set_entry( thunk_selector
, &entry
);
181 relay
= GetProcAddress16( GetModuleHandle16("user"), "__wine_call_wndproc" );
184 thunk
= &thunk_array
[index
];
185 thunk
->popl_eax
= 0x58; /* popl %eax */
186 thunk
->pushl_func
= 0x68; /* pushl $proc */
187 thunk
->proc
= handle
;
188 thunk
->pushl_eax
= 0x50; /* pushl %eax */
189 thunk
->ljmp
= 0xea; /* ljmp relay*/
190 thunk
->relay_offset
= OFFSETOF(relay
);
191 thunk
->relay_sel
= SELECTOROF(relay
);
192 return (WNDPROC16
)MAKESEGPTR( thunk_selector
, index
* sizeof(WINPROC_THUNK
) );
195 /**********************************************************************
196 * WINPROC_AllocProc16
198 WNDPROC
WINPROC_AllocProc16( WNDPROC16 func
)
203 if (!func
) return NULL
;
205 /* check if the function is already a win proc */
206 if ((index
= winproc_to_index( func
)) != -1)
207 return (WNDPROC
)(ULONG_PTR
)(index
| (WINPROC_HANDLE
<< 16));
209 /* then check if we already have a winproc for that function */
210 for (index
= 0; index
< winproc16_used
; index
++)
211 if (winproc16_array
[index
] == func
) goto done
;
213 if (winproc16_used
>= MAX_WINPROCS16
)
215 FIXME( "too many winprocs, cannot allocate one for 16-bit %p\n", func
);
218 winproc16_array
[winproc16_used
++] = func
;
221 ret
= (WNDPROC
)(ULONG_PTR
)((index
+ MAX_WINPROCS32
) | (WINPROC_HANDLE
<< 16));
222 TRACE( "returning %p for %p/16-bit (%d/%d used)\n",
223 ret
, func
, winproc16_used
, MAX_WINPROCS16
);
227 /**********************************************************************
230 * Get a window procedure pointer that can be passed to the Windows program.
232 WNDPROC16
WINPROC_GetProc16( WNDPROC proc
, BOOL unicode
)
234 WNDPROC winproc
= wow_handlers32
.alloc_winproc( proc
, unicode
);
236 if ((ULONG_PTR
)winproc
>> 16 != WINPROC_HANDLE
) return (WNDPROC16
)winproc
;
237 return alloc_win16_thunk( winproc
);
240 /* call a 16-bit window procedure */
241 static LRESULT
call_window_proc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
242 LRESULT
*result
, void *arg
)
244 WNDPROC16 func
= arg
;
245 int index
= winproc_to_index( func
);
254 DRAWITEMSTRUCT16 dis16
;
255 COMPAREITEMSTRUCT16 cis16
;
259 if (index
>= MAX_WINPROCS32
) func
= winproc16_array
[index
- MAX_WINPROCS32
];
261 /* Window procedures want ax = hInstance, ds = es = ss */
263 memset(&context
, 0, sizeof(context
));
264 context
.SegDs
= context
.SegEs
= SELECTOROF(NtCurrentTeb()->WOW32Reserved
);
265 context
.SegFs
= wine_get_fs();
266 context
.SegGs
= wine_get_gs();
267 if (!(context
.Eax
= GetWindowWord( HWND_32(hwnd
), GWLP_HINSTANCE
))) context
.Eax
= context
.SegDs
;
268 context
.SegCs
= SELECTOROF(func
);
269 context
.Eip
= OFFSETOF(func
);
270 context
.Ebp
= OFFSETOF(NtCurrentTeb()->WOW32Reserved
) + FIELD_OFFSET(STACK16FRAME
, bp
);
274 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
275 work if structures passed in lParam are placed in the stack/data
276 segment. Programmers easily make the mistake of converting lParam
277 to a near rather than a far pointer, since Windows apparently
278 allows this. We copy the structures to the 16 bit stack; this is
279 ugly but makes these programs work. */
284 size
= sizeof(CREATESTRUCT16
); break;
286 size
= sizeof(DRAWITEMSTRUCT16
); break;
288 size
= sizeof(COMPAREITEMSTRUCT16
); break;
292 memcpy( &args
.u
, MapSL(lParam
), size
);
293 lParam
= PtrToUlong(NtCurrentTeb()->WOW32Reserved
) - size
;
297 args
.params
[4] = hwnd
;
298 args
.params
[3] = msg
;
299 args
.params
[2] = wParam
;
300 args
.params
[1] = HIWORD(lParam
);
301 args
.params
[0] = LOWORD(lParam
);
302 WOWCallback16Ex( 0, WCB16_REGS
, sizeof(args
.params
) + size
, &args
, (DWORD
*)&context
);
303 *result
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
307 static LRESULT
call_dialog_proc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wp
, LPARAM lp
,
308 LRESULT
*result
, void *arg
)
310 LRESULT ret
= call_window_proc16( hwnd
, msg
, wp
, lp
, result
, arg
);
311 *result
= GetWindowLongPtrW( WIN_Handle32(hwnd
), DWLP_MSGRESULT
);
315 static LRESULT
call_window_proc_Ato16( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
316 LRESULT
*result
, void *arg
)
318 return WINPROC_CallProc32ATo16( call_window_proc16
, hwnd
, msg
, wp
, lp
, result
, arg
);
321 static LRESULT
call_dialog_proc_Ato16( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
322 LRESULT
*result
, void *arg
)
324 return WINPROC_CallProc32ATo16( call_dialog_proc16
, hwnd
, msg
, wp
, lp
, result
, arg
);
329 /**********************************************************************
330 * Support for Edit word break proc thunks
333 #define MAX_THUNKS 32
335 #include <pshpack1.h>
336 static struct word_break_thunk
338 BYTE popl_eax
; /* popl %eax (return address) */
339 BYTE pushl_proc16
; /* pushl proc16 */
340 EDITWORDBREAKPROC16 proc16
;
341 BYTE pushl_eax
; /* pushl %eax */
342 BYTE jmp
; /* ljmp call_word_break_proc16 */
344 } *word_break_thunks
;
347 /**********************************************************************
348 * call_word_break_proc16
350 static INT16 CALLBACK
call_word_break_proc16( SEGPTR proc16
, LPSTR text
, INT index
, INT count
, INT action
)
356 segptr
= MapLS( text
);
357 args
[4] = SELECTOROF(segptr
);
358 args
[3] = OFFSETOF(segptr
);
362 WOWCallback16Ex( proc16
, WCB16_PASCAL
, sizeof(args
), args
, &result
);
364 return LOWORD(result
);
367 /******************************************************************
368 * add_word_break_thunk
370 static struct word_break_thunk
*add_word_break_thunk( EDITWORDBREAKPROC16 proc16
)
372 struct word_break_thunk
*thunk
;
374 if (!word_break_thunks
)
376 word_break_thunks
= VirtualAlloc( NULL
, MAX_THUNKS
* sizeof(*thunk
),
377 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
378 if (!word_break_thunks
) return NULL
;
380 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
382 thunk
->popl_eax
= 0x58; /* popl %eax */
383 thunk
->pushl_proc16
= 0x68; /* pushl proc16 */
384 thunk
->pushl_eax
= 0x50; /* pushl %eax */
385 thunk
->jmp
= 0xe9; /* jmp call_word_break_proc16 */
386 thunk
->callback
= (char *)call_word_break_proc16
- (char *)(&thunk
->callback
+ 1);
389 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
390 if (thunk
->proc16
== proc16
) return thunk
;
392 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
394 if (thunk
->proc16
) continue;
395 thunk
->proc16
= proc16
;
398 FIXME("Out of word break thunks\n");
402 /******************************************************************
403 * get_word_break_thunk
405 static EDITWORDBREAKPROC16
get_word_break_thunk( EDITWORDBREAKPROCA proc
)
407 struct word_break_thunk
*thunk
= (struct word_break_thunk
*)proc
;
408 if (word_break_thunks
&& thunk
>= word_break_thunks
&& thunk
< &word_break_thunks
[MAX_THUNKS
])
409 return thunk
->proc16
;
414 /***********************************************************************
415 * Support for 16<->32 message mapping
418 static inline void *get_buffer( void *static_buffer
, size_t size
, size_t need
)
420 if (size
>= need
) return static_buffer
;
421 return HeapAlloc( GetProcessHeap(), 0, need
);
424 static inline void free_buffer( void *static_buffer
, void *buffer
)
426 if (buffer
!= static_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
429 static void RECT16to32( const RECT16
*from
, RECT
*to
)
431 to
->left
= from
->left
;
433 to
->right
= from
->right
;
434 to
->bottom
= from
->bottom
;
437 static void RECT32to16( const RECT
*from
, RECT16
*to
)
439 to
->left
= from
->left
;
441 to
->right
= from
->right
;
442 to
->bottom
= from
->bottom
;
445 static void MINMAXINFO32to16( const MINMAXINFO
*from
, MINMAXINFO16
*to
)
447 to
->ptReserved
.x
= from
->ptReserved
.x
;
448 to
->ptReserved
.y
= from
->ptReserved
.y
;
449 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
450 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
451 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
452 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
453 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
454 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
455 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
456 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
459 static void MINMAXINFO16to32( const MINMAXINFO16
*from
, MINMAXINFO
*to
)
461 to
->ptReserved
.x
= from
->ptReserved
.x
;
462 to
->ptReserved
.y
= from
->ptReserved
.y
;
463 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
464 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
465 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
466 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
467 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
468 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
469 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
470 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
473 static void WINDOWPOS32to16( const WINDOWPOS
* from
, WINDOWPOS16
* to
)
475 to
->hwnd
= HWND_16(from
->hwnd
);
476 to
->hwndInsertAfter
= HWND_16(from
->hwndInsertAfter
);
481 to
->flags
= from
->flags
;
484 static void WINDOWPOS16to32( const WINDOWPOS16
* from
, WINDOWPOS
* to
)
486 to
->hwnd
= WIN_Handle32(from
->hwnd
);
487 to
->hwndInsertAfter
= (from
->hwndInsertAfter
== (HWND16
)-1) ?
488 HWND_TOPMOST
: WIN_Handle32(from
->hwndInsertAfter
);
493 to
->flags
= from
->flags
;
496 /* The strings are not copied */
497 static void CREATESTRUCT32Ato16( const CREATESTRUCTA
* from
, CREATESTRUCT16
* to
)
499 to
->lpCreateParams
= (SEGPTR
)from
->lpCreateParams
;
500 to
->hInstance
= HINSTANCE_16(from
->hInstance
);
501 to
->hMenu
= HMENU_16(from
->hMenu
);
502 to
->hwndParent
= HWND_16(from
->hwndParent
);
507 to
->style
= from
->style
;
508 to
->dwExStyle
= from
->dwExStyle
;
511 static void CREATESTRUCT16to32A( const CREATESTRUCT16
* from
, CREATESTRUCTA
*to
)
514 to
->lpCreateParams
= (LPVOID
)from
->lpCreateParams
;
515 to
->hInstance
= HINSTANCE_32(from
->hInstance
);
516 to
->hMenu
= HMENU_32(from
->hMenu
);
517 to
->hwndParent
= WIN_Handle32(from
->hwndParent
);
522 to
->style
= from
->style
;
523 to
->dwExStyle
= from
->dwExStyle
;
524 to
->lpszName
= MapSL(from
->lpszName
);
525 to
->lpszClass
= MapSL(from
->lpszClass
);
528 /* The strings are not copied */
529 static void MDICREATESTRUCT32Ato16( const MDICREATESTRUCTA
* from
, MDICREATESTRUCT16
* to
)
531 to
->hOwner
= HINSTANCE_16(from
->hOwner
);
536 to
->style
= from
->style
;
537 to
->lParam
= from
->lParam
;
540 static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16
* from
, MDICREATESTRUCTA
*to
)
542 to
->hOwner
= HINSTANCE_32(from
->hOwner
);
547 to
->style
= from
->style
;
548 to
->lParam
= from
->lParam
;
549 to
->szTitle
= MapSL(from
->szTitle
);
550 to
->szClass
= MapSL(from
->szClass
);
553 static UINT_PTR
convert_handle_16_to_32(HANDLE16 src
, unsigned int flags
)
556 UINT sz
= GlobalSize16(src
);
559 if (!(dst
= GlobalAlloc(flags
, sz
)))
561 ptr16
= GlobalLock16(src
);
562 ptr32
= GlobalLock(dst
);
563 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr32
, ptr16
, sz
);
567 return (UINT_PTR
)dst
;
570 static HANDLE16
convert_handle_32_to_16(UINT_PTR src
, unsigned int flags
)
573 UINT sz
= GlobalSize((HANDLE
)src
);
576 if (!(dst
= GlobalAlloc16(flags
, sz
)))
578 ptr32
= GlobalLock((HANDLE
)src
);
579 ptr16
= GlobalLock16(dst
);
580 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr16
, ptr32
, sz
);
581 GlobalUnlock((HANDLE
)src
);
587 static BOOL
is_old_app( HWND hwnd
)
589 HINSTANCE inst
= (HINSTANCE
)GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
590 return inst
&& !((ULONG_PTR
)inst
>> 16) && (GetExpWinVer16(LOWORD(inst
)) & 0xFF00) == 0x0300;
593 static int find_sub_menu( HMENU
*hmenu
, HMENU16 target
)
595 int i
, pos
, count
= GetMenuItemCount( *hmenu
);
597 for (i
= 0; i
< count
; i
++)
599 HMENU sub
= GetSubMenu( *hmenu
, i
);
601 if (HMENU_16(sub
) == target
) return i
;
602 if ((pos
= find_sub_menu( &sub
, target
)) != -1)
611 /**********************************************************************
612 * WINPROC_CallProc16To32A
614 LRESULT
WINPROC_CallProc16To32A( winproc_callback_t callback
, HWND16 hwnd
, UINT16 msg
,
615 WPARAM16 wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
618 HWND hwnd32
= WIN_Handle32( hwnd
);
625 CREATESTRUCT16
*cs16
= MapSL(lParam
);
627 MDICREATESTRUCTA mdi_cs
;
629 CREATESTRUCT16to32A( cs16
, &cs
);
630 if (GetWindowLongW(hwnd32
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
632 MDICREATESTRUCT16
*mdi_cs16
= MapSL(cs16
->lpCreateParams
);
633 MDICREATESTRUCT16to32A(mdi_cs16
, &mdi_cs
);
634 cs
.lpCreateParams
= &mdi_cs
;
636 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cs
, result
, arg
);
637 CREATESTRUCT32Ato16( &cs
, cs16
);
642 MDICREATESTRUCT16
*cs16
= MapSL(lParam
);
645 MDICREATESTRUCT16to32A( cs16
, &cs
);
646 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cs
, result
, arg
);
647 MDICREATESTRUCT32Ato16( &cs
, cs16
);
652 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32( HIWORD(lParam
) ),
653 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
654 else /* message sent to MDI client */
655 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
657 case WM_MDIGETACTIVE
:
659 BOOL maximized
= FALSE
;
660 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&maximized
, result
, arg
);
661 *result
= MAKELRESULT( LOWORD(*result
), maximized
);
665 ret
= callback( hwnd32
, wParam
? WM_MDIREFRESHMENU
: WM_MDISETMENU
,
666 (WPARAM
)HMENU_32(LOWORD(lParam
)), (LPARAM
)HMENU_32(HIWORD(lParam
)),
669 case WM_GETMINMAXINFO
:
671 MINMAXINFO16
*mmi16
= MapSL(lParam
);
674 MINMAXINFO16to32( mmi16
, &mmi
);
675 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&mmi
, result
, arg
);
676 MINMAXINFO32to16( &mmi
, mmi16
);
679 case WM_WINDOWPOSCHANGING
:
680 case WM_WINDOWPOSCHANGED
:
682 WINDOWPOS16
*winpos16
= MapSL(lParam
);
685 WINDOWPOS16to32( winpos16
, &winpos
);
686 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&winpos
, result
, arg
);
687 WINDOWPOS32to16( &winpos
, winpos16
);
692 NCCALCSIZE_PARAMS16
*nc16
= MapSL(lParam
);
693 NCCALCSIZE_PARAMS nc
;
696 RECT16to32( &nc16
->rgrc
[0], &nc
.rgrc
[0] );
699 RECT16to32( &nc16
->rgrc
[1], &nc
.rgrc
[1] );
700 RECT16to32( &nc16
->rgrc
[2], &nc
.rgrc
[2] );
701 WINDOWPOS16to32( MapSL(nc16
->lppos
), &winpos
);
704 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&nc
, result
, arg
);
705 RECT32to16( &nc
.rgrc
[0], &nc16
->rgrc
[0] );
708 RECT32to16( &nc
.rgrc
[1], &nc16
->rgrc
[1] );
709 RECT32to16( &nc
.rgrc
[2], &nc16
->rgrc
[2] );
710 WINDOWPOS32to16( &winpos
, MapSL(nc16
->lppos
) );
716 COMPAREITEMSTRUCT16
* cis16
= MapSL(lParam
);
717 COMPAREITEMSTRUCT cis
;
718 cis
.CtlType
= cis16
->CtlType
;
719 cis
.CtlID
= cis16
->CtlID
;
720 cis
.hwndItem
= WIN_Handle32( cis16
->hwndItem
);
721 cis
.itemID1
= cis16
->itemID1
;
722 cis
.itemData1
= cis16
->itemData1
;
723 cis
.itemID2
= cis16
->itemID2
;
724 cis
.itemData2
= cis16
->itemData2
;
725 cis
.dwLocaleId
= 0; /* FIXME */
726 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cis
, result
, arg
);
731 DELETEITEMSTRUCT16
* dis16
= MapSL(lParam
);
732 DELETEITEMSTRUCT dis
;
733 dis
.CtlType
= dis16
->CtlType
;
734 dis
.CtlID
= dis16
->CtlID
;
735 dis
.hwndItem
= WIN_Handle32( dis16
->hwndItem
);
736 dis
.itemData
= dis16
->itemData
;
737 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&dis
, result
, arg
);
742 MEASUREITEMSTRUCT16
* mis16
= MapSL(lParam
);
743 MEASUREITEMSTRUCT mis
;
744 mis
.CtlType
= mis16
->CtlType
;
745 mis
.CtlID
= mis16
->CtlID
;
746 mis
.itemID
= mis16
->itemID
;
747 mis
.itemWidth
= mis16
->itemWidth
;
748 mis
.itemHeight
= mis16
->itemHeight
;
749 mis
.itemData
= mis16
->itemData
;
750 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&mis
, result
, arg
);
751 mis16
->itemWidth
= (UINT16
)mis
.itemWidth
;
752 mis16
->itemHeight
= (UINT16
)mis
.itemHeight
;
757 DRAWITEMSTRUCT16
* dis16
= MapSL(lParam
);
759 dis
.CtlType
= dis16
->CtlType
;
760 dis
.CtlID
= dis16
->CtlID
;
761 dis
.itemID
= dis16
->itemID
;
762 dis
.itemAction
= dis16
->itemAction
;
763 dis
.itemState
= dis16
->itemState
;
764 dis
.hwndItem
= (dis
.CtlType
== ODT_MENU
) ? (HWND
)HMENU_32(dis16
->hwndItem
)
765 : WIN_Handle32( dis16
->hwndItem
);
766 dis
.hDC
= HDC_32(dis16
->hDC
);
767 dis
.itemData
= dis16
->itemData
;
768 dis
.rcItem
.left
= dis16
->rcItem
.left
;
769 dis
.rcItem
.top
= dis16
->rcItem
.top
;
770 dis
.rcItem
.right
= dis16
->rcItem
.right
;
771 dis
.rcItem
.bottom
= dis16
->rcItem
.bottom
;
772 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&dis
, result
, arg
);
777 COPYDATASTRUCT16
*cds16
= MapSL(lParam
);
779 cds
.dwData
= cds16
->dwData
;
780 cds
.cbData
= cds16
->cbData
;
781 cds
.lpData
= MapSL(cds16
->lpData
);
782 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cds
, result
, arg
);
788 MSG16
*msg16
= MapSL(lParam
);
790 msg32
.hwnd
= WIN_Handle32( msg16
->hwnd
);
791 msg32
.message
= msg16
->message
;
792 msg32
.wParam
= msg16
->wParam
;
793 msg32
.lParam
= msg16
->lParam
;
794 msg32
.time
= msg16
->time
;
795 msg32
.pt
.x
= msg16
->pt
.x
;
796 msg32
.pt
.y
= msg16
->pt
.y
;
797 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&msg32
, result
, arg
);
800 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
805 next
.hmenuIn
= (HMENU
)lParam
;
808 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&next
, result
, arg
);
809 *result
= MAKELONG( HMENU_16(next
.hmenuNext
), HWND_16(next
.hwndNext
) );
816 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, HIWORD(lParam
) ),
817 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
821 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
822 (LPARAM
)WIN_Handle32( HIWORD(lParam
) ), result
, arg
);
825 if (HIWORD(lParam
) <= CTLCOLOR_STATIC
)
826 ret
= callback( hwnd32
, WM_CTLCOLORMSGBOX
+ HIWORD(lParam
),
827 (WPARAM
)HDC_32(wParam
), (LPARAM
)WIN_Handle32( LOWORD(lParam
) ),
832 case WM_WININICHANGE
:
833 case WM_DEVMODECHANGE
:
834 case WM_ASKCBFORMATNAME
:
836 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)MapSL(lParam
), result
, arg
);
839 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
840 (LPARAM
)HMENU_32(HIWORD(lParam
)), result
, arg
);
843 if((LOWORD(lParam
) & MF_POPUP
) && (LOWORD(lParam
) != 0xFFFF))
845 HMENU hmenu
= HMENU_32(HIWORD(lParam
));
846 int pos
= find_sub_menu( &hmenu
, wParam
);
847 if (pos
== -1) pos
= 0;
850 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
851 (LPARAM
)HMENU_32(HIWORD(lParam
)), result
, arg
);
853 case WM_PARENTNOTIFY
:
854 if ((wParam
== WM_CREATE
) || (wParam
== WM_DESTROY
))
855 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, HIWORD(lParam
) ),
856 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
858 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
861 /* We need this when SetActiveWindow sends a Sendmessage16() to
862 * a 32-bit window. Might be superfluous with 32-bit interprocess
864 if (lParam
) lParam
= HTASK_32(lParam
);
865 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
867 case WM_DDE_INITIATE
:
868 case WM_DDE_TERMINATE
:
869 case WM_DDE_UNADVISE
:
871 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
877 HANDLE16 lo16
= LOWORD(lParam
);
879 if (lo16
&& !(lo32
= convert_handle_16_to_32(lo16
, GMEM_DDESHARE
))) break;
880 lParam
= PackDDElParam( msg
, lo32
, HIWORD(lParam
) );
881 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
883 break; /* FIXME don't know how to free allocated memory (handle) !! */
886 UINT_PTR lo
= LOWORD(lParam
);
887 UINT_PTR hi
= HIWORD(lParam
);
891 if (GlobalGetAtomNameA(hi
, buf
, 2) > 0) flag
|= 1;
892 if (GlobalSize16(hi
) != 0) flag
|= 2;
898 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
903 break; /* atom, nothing to do */
905 MESSAGE("DDE_ACK: %lx both atom and handle... choosing handle\n", hi
);
908 hi
= convert_handle_16_to_32(hi
, GMEM_DDESHARE
);
911 lParam
= PackDDElParam( WM_DDE_ACK
, lo
, hi
);
912 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
914 break; /* FIXME don't know how to free allocated memory (handle) !! */
916 lParam
= convert_handle_16_to_32( lParam
, GMEM_DDESHARE
);
917 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
918 break; /* FIXME don't know how to free allocated memory (handle) !! */
919 case WM_PAINTCLIPBOARD
:
920 case WM_SIZECLIPBOARD
:
921 FIXME_(msg
)( "message %04x needs translation\n", msg
);
924 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
931 /**********************************************************************
932 * WINPROC_CallProc32ATo16
934 * Call a 16-bit window procedure, translating the 32-bit args.
936 LRESULT
WINPROC_CallProc32ATo16( winproc_callback16_t callback
, HWND hwnd
, UINT msg
,
937 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
946 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)lParam
;
948 MDICREATESTRUCT16 mdi_cs16
;
949 BOOL mdi_child
= (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
);
951 CREATESTRUCT32Ato16( cs32
, &cs
);
952 cs
.lpszName
= MapLS( cs32
->lpszName
);
953 cs
.lpszClass
= MapLS( cs32
->lpszClass
);
957 MDICREATESTRUCTA
*mdi_cs
= cs32
->lpCreateParams
;
958 MDICREATESTRUCT32Ato16( mdi_cs
, &mdi_cs16
);
959 mdi_cs16
.szTitle
= MapLS( mdi_cs
->szTitle
);
960 mdi_cs16
.szClass
= MapLS( mdi_cs
->szClass
);
961 cs
.lpCreateParams
= MapLS( &mdi_cs16
);
963 lParam
= MapLS( &cs
);
964 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
966 UnMapLS( cs
.lpszName
);
967 UnMapLS( cs
.lpszClass
);
970 UnMapLS( cs
.lpCreateParams
);
971 UnMapLS( mdi_cs16
.szTitle
);
972 UnMapLS( mdi_cs16
.szClass
);
978 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)lParam
;
979 MDICREATESTRUCT16 cs
;
981 MDICREATESTRUCT32Ato16( cs32
, &cs
);
982 cs
.szTitle
= MapLS( cs32
->szTitle
);
983 cs
.szClass
= MapLS( cs32
->szClass
);
984 lParam
= MapLS( &cs
);
985 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
987 UnMapLS( cs
.szTitle
);
988 UnMapLS( cs
.szClass
);
992 if (GetWindowLongW( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
993 ret
= callback( HWND_16(hwnd
), msg
, ((HWND
)lParam
== hwnd
),
994 MAKELPARAM( LOWORD(lParam
), LOWORD(wParam
) ), result
, arg
);
996 ret
= callback( HWND_16(hwnd
), msg
, HWND_16( wParam
), 0, result
, arg
);
998 case WM_MDIGETACTIVE
:
999 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1000 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(*result
);
1001 *result
= (LRESULT
)WIN_Handle32( LOWORD(*result
) );
1004 ret
= callback( HWND_16(hwnd
), msg
, (lParam
== 0),
1005 MAKELPARAM( LOWORD(wParam
), LOWORD(lParam
) ), result
, arg
);
1007 case WM_GETMINMAXINFO
:
1009 MINMAXINFO
*mmi32
= (MINMAXINFO
*)lParam
;
1012 MINMAXINFO32to16( mmi32
, &mmi
);
1013 lParam
= MapLS( &mmi
);
1014 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1016 MINMAXINFO16to32( &mmi
, mmi32
);
1021 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)lParam
;
1022 NCCALCSIZE_PARAMS16 nc
;
1025 RECT32to16( &nc32
->rgrc
[0], &nc
.rgrc
[0] );
1028 RECT32to16( &nc32
->rgrc
[1], &nc
.rgrc
[1] );
1029 RECT32to16( &nc32
->rgrc
[2], &nc
.rgrc
[2] );
1030 WINDOWPOS32to16( nc32
->lppos
, &winpos
);
1031 nc
.lppos
= MapLS( &winpos
);
1033 lParam
= MapLS( &nc
);
1034 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1036 RECT16to32( &nc
.rgrc
[0], &nc32
->rgrc
[0] );
1039 RECT16to32( &nc
.rgrc
[1], &nc32
->rgrc
[1] );
1040 RECT16to32( &nc
.rgrc
[2], &nc32
->rgrc
[2] );
1041 WINDOWPOS16to32( &winpos
, nc32
->lppos
);
1042 UnMapLS( nc
.lppos
);
1046 case WM_WINDOWPOSCHANGING
:
1047 case WM_WINDOWPOSCHANGED
:
1049 WINDOWPOS
*winpos32
= (WINDOWPOS
*)lParam
;
1052 WINDOWPOS32to16( winpos32
, &winpos
);
1053 lParam
= MapLS( &winpos
);
1054 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1056 WINDOWPOS16to32( &winpos
, winpos32
);
1059 case WM_COMPAREITEM
:
1061 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)lParam
;
1062 COMPAREITEMSTRUCT16 cis
;
1063 cis
.CtlType
= cis32
->CtlType
;
1064 cis
.CtlID
= cis32
->CtlID
;
1065 cis
.hwndItem
= HWND_16( cis32
->hwndItem
);
1066 cis
.itemID1
= cis32
->itemID1
;
1067 cis
.itemData1
= cis32
->itemData1
;
1068 cis
.itemID2
= cis32
->itemID2
;
1069 cis
.itemData2
= cis32
->itemData2
;
1070 lParam
= MapLS( &cis
);
1071 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1077 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)lParam
;
1078 DELETEITEMSTRUCT16 dis
;
1079 dis
.CtlType
= dis32
->CtlType
;
1080 dis
.CtlID
= dis32
->CtlID
;
1081 dis
.itemID
= dis32
->itemID
;
1082 dis
.hwndItem
= (dis
.CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
1083 : HWND_16( dis32
->hwndItem
);
1084 dis
.itemData
= dis32
->itemData
;
1085 lParam
= MapLS( &dis
);
1086 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1092 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)lParam
;
1093 DRAWITEMSTRUCT16 dis
;
1094 dis
.CtlType
= dis32
->CtlType
;
1095 dis
.CtlID
= dis32
->CtlID
;
1096 dis
.itemID
= dis32
->itemID
;
1097 dis
.itemAction
= dis32
->itemAction
;
1098 dis
.itemState
= dis32
->itemState
;
1099 dis
.hwndItem
= HWND_16( dis32
->hwndItem
);
1100 dis
.hDC
= HDC_16(dis32
->hDC
);
1101 dis
.itemData
= dis32
->itemData
;
1102 dis
.rcItem
.left
= dis32
->rcItem
.left
;
1103 dis
.rcItem
.top
= dis32
->rcItem
.top
;
1104 dis
.rcItem
.right
= dis32
->rcItem
.right
;
1105 dis
.rcItem
.bottom
= dis32
->rcItem
.bottom
;
1106 lParam
= MapLS( &dis
);
1107 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1111 case WM_MEASUREITEM
:
1113 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)lParam
;
1114 MEASUREITEMSTRUCT16 mis
;
1115 mis
.CtlType
= mis32
->CtlType
;
1116 mis
.CtlID
= mis32
->CtlID
;
1117 mis
.itemID
= mis32
->itemID
;
1118 mis
.itemWidth
= mis32
->itemWidth
;
1119 mis
.itemHeight
= mis32
->itemHeight
;
1120 mis
.itemData
= mis32
->itemData
;
1121 lParam
= MapLS( &mis
);
1122 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1124 mis32
->itemWidth
= mis
.itemWidth
;
1125 mis32
->itemHeight
= mis
.itemHeight
;
1130 COPYDATASTRUCT
*cds32
= (COPYDATASTRUCT
*)lParam
;
1131 COPYDATASTRUCT16 cds
;
1133 cds
.dwData
= cds32
->dwData
;
1134 cds
.cbData
= cds32
->cbData
;
1135 cds
.lpData
= MapLS( cds32
->lpData
);
1136 lParam
= MapLS( &cds
);
1137 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1139 UnMapLS( cds
.lpData
);
1145 MSG
*msg32
= (MSG
*)lParam
;
1148 msg16
.hwnd
= HWND_16( msg32
->hwnd
);
1149 msg16
.message
= msg32
->message
;
1150 msg16
.wParam
= msg32
->wParam
;
1151 msg16
.lParam
= msg32
->lParam
;
1152 msg16
.time
= msg32
->time
;
1153 msg16
.pt
.x
= msg32
->pt
.x
;
1154 msg16
.pt
.y
= msg32
->pt
.y
;
1155 lParam
= MapLS( &msg16
);
1156 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1160 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1164 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1165 ret
= callback( HWND_16(hwnd
), msg
, wParam
, (LPARAM
)next
->hmenuIn
, result
, arg
);
1166 next
->hmenuNext
= HMENU_32( LOWORD(*result
) );
1167 next
->hwndNext
= WIN_Handle32( HIWORD(*result
) );
1172 case WM_ASKCBFORMATNAME
:
1173 wParam
= min( wParam
, 0xff80 ); /* Must be < 64K */
1177 case WM_WININICHANGE
:
1178 case WM_DEVMODECHANGE
:
1179 lParam
= MapLS( (void *)lParam
);
1180 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1187 ret
= callback( HWND_16(hwnd
), msg
, wParam
, MAKELPARAM( (HWND16
)lParam
, HIWORD(wParam
) ),
1192 ret
= callback( HWND_16(hwnd
), msg
, wParam
, MAKELPARAM( HIWORD(wParam
), (HWND16
)lParam
),
1195 case WM_CTLCOLORMSGBOX
:
1196 case WM_CTLCOLOREDIT
:
1197 case WM_CTLCOLORLISTBOX
:
1198 case WM_CTLCOLORBTN
:
1199 case WM_CTLCOLORDLG
:
1200 case WM_CTLCOLORSCROLLBAR
:
1201 case WM_CTLCOLORSTATIC
:
1202 ret
= callback( HWND_16(hwnd
), WM_CTLCOLOR
, wParam
,
1203 MAKELPARAM( (HWND16
)lParam
, msg
- WM_CTLCOLORMSGBOX
), result
, arg
);
1206 if(HIWORD(wParam
) & MF_POPUP
)
1209 if ((HIWORD(wParam
) != 0xffff) || lParam
)
1211 if ((hmenu
= GetSubMenu( (HMENU
)lParam
, LOWORD(wParam
) )))
1213 ret
= callback( HWND_16(hwnd
), msg
, HMENU_16(hmenu
),
1214 MAKELPARAM( HIWORD(wParam
), (HMENU16
)lParam
), result
, arg
);
1221 ret
= callback( HWND_16(hwnd
), msg
, wParam
,
1222 MAKELPARAM( HIWORD(wParam
), (HMENU16
)lParam
), result
, arg
);
1224 case WM_PARENTNOTIFY
:
1225 if ((LOWORD(wParam
) == WM_CREATE
) || (LOWORD(wParam
) == WM_DESTROY
))
1226 ret
= callback( HWND_16(hwnd
), msg
, wParam
,
1227 MAKELPARAM( (HWND16
)lParam
, HIWORD(wParam
) ), result
, arg
);
1229 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1231 case WM_ACTIVATEAPP
:
1232 ret
= callback( HWND_16(hwnd
), msg
, wParam
, HTASK_16( lParam
), result
, arg
);
1235 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
))
1236 ret
= callback( HWND_16(hwnd
), WM_PAINTICON
, 1, lParam
, result
, arg
);
1238 ret
= callback( HWND_16(hwnd
), WM_PAINT
, wParam
, lParam
, result
, arg
);
1241 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
)) msg
= WM_ICONERASEBKGND
;
1242 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1244 case WM_DDE_INITIATE
:
1245 case WM_DDE_TERMINATE
:
1246 case WM_DDE_UNADVISE
:
1247 case WM_DDE_REQUEST
:
1248 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
), lParam
, result
, arg
);
1257 UnpackDDElParam( msg
, lParam
, &lo32
, &hi
);
1258 if (lo32
&& !(lo16
= convert_handle_32_to_16(lo32
, GMEM_DDESHARE
))) break;
1259 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
),
1260 MAKELPARAM(lo16
, hi
), result
, arg
);
1262 break; /* FIXME don't know how to free allocated memory (handle) !! */
1269 UnpackDDElParam( msg
, lParam
, &lo
, &hi
);
1271 if (GlobalGetAtomNameA((ATOM
)hi
, buf
, sizeof(buf
)) > 0) flag
|= 1;
1272 if (GlobalSize((HANDLE
)hi
) != 0) flag
|= 2;
1278 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1283 break; /* atom, nothing to do */
1285 MESSAGE("DDE_ACK: %lx both atom and handle... choosing handle\n", hi
);
1288 hi
= convert_handle_32_to_16(hi
, GMEM_DDESHARE
);
1291 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
),
1292 MAKELPARAM(lo
, hi
), result
, arg
);
1294 break; /* FIXME don't know how to free allocated memory (handle) !! */
1295 case WM_DDE_EXECUTE
:
1296 lParam
= convert_handle_32_to_16(lParam
, GMEM_DDESHARE
);
1297 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1298 break; /* FIXME don't know how to free allocated memory (handle) !! */
1300 ret
= callback( HWND_16(hwnd
), SBM_SETRANGE16
, 0, MAKELPARAM(wParam
, lParam
), result
, arg
);
1303 ret
= callback( HWND_16(hwnd
), SBM_GETRANGE16
, wParam
, lParam
, result
, arg
);
1304 *(LPINT
)wParam
= LOWORD(*result
);
1305 *(LPINT
)lParam
= HIWORD(*result
);
1312 ret
= callback( HWND_16(hwnd
), msg
+ BM_GETCHECK16
- BM_GETCHECK
, wParam
, lParam
, result
, arg
);
1320 case EM_SCROLLCARET
:
1323 case EM_GETLINECOUNT
:
1335 case EM_LINEFROMCHAR
:
1336 case EM_SETTABSTOPS
:
1337 case EM_SETPASSWORDCHAR
:
1338 case EM_EMPTYUNDOBUFFER
:
1339 case EM_GETFIRSTVISIBLELINE
:
1340 case EM_SETREADONLY
:
1341 case EM_SETWORDBREAKPROC
:
1342 case EM_GETWORDBREAKPROC
:
1343 case EM_GETPASSWORDCHAR
:
1344 ret
= callback( HWND_16(hwnd
), msg
+ EM_GETSEL16
- EM_GETSEL
, wParam
, lParam
, result
, arg
);
1347 ret
= callback( HWND_16(hwnd
), EM_SETSEL16
, 0, MAKELPARAM( wParam
, lParam
), result
, arg
);
1351 case LB_DELETESTRING
:
1352 case LB_GETANCHORINDEX
:
1353 case LB_GETCARETINDEX
:
1356 case LB_GETHORIZONTALEXTENT
:
1357 case LB_GETITEMDATA
:
1358 case LB_GETITEMHEIGHT
:
1360 case LB_GETSELCOUNT
:
1362 case LB_GETTOPINDEX
:
1363 case LB_RESETCONTENT
:
1364 case LB_SELITEMRANGE
:
1365 case LB_SELITEMRANGEEX
:
1366 case LB_SETANCHORINDEX
:
1367 case LB_SETCARETINDEX
:
1368 case LB_SETCOLUMNWIDTH
:
1370 case LB_SETHORIZONTALEXTENT
:
1371 case LB_SETITEMDATA
:
1372 case LB_SETITEMHEIGHT
:
1374 case LB_SETTOPINDEX
:
1375 ret
= callback( HWND_16(hwnd
), msg
+ LB_ADDSTRING16
- LB_ADDSTRING
, wParam
, lParam
, result
, arg
);
1379 case LB_FINDSTRINGEXACT
:
1380 case LB_INSERTSTRING
:
1381 case LB_SELECTSTRING
:
1385 lParam
= MapLS( (LPSTR
)lParam
);
1386 ret
= callback( HWND_16(hwnd
), msg
+ LB_ADDSTRING16
- LB_ADDSTRING
, wParam
, lParam
, result
, arg
);
1389 case LB_GETSELITEMS
:
1391 INT
*items32
= (INT
*)lParam
;
1392 INT16
*items
, buffer
[512];
1395 wParam
= min( wParam
, 0x7f80 ); /* Must be < 64K */
1396 if (!(items
= get_buffer( buffer
, sizeof(buffer
), wParam
* sizeof(INT16
) ))) break;
1397 lParam
= MapLS( items
);
1398 ret
= callback( HWND_16(hwnd
), LB_GETSELITEMS16
, wParam
, lParam
, result
, arg
);
1400 for (i
= 0; i
< wParam
; i
++) items32
[i
] = items
[i
];
1401 free_buffer( buffer
, items
);
1404 case LB_SETTABSTOPS
:
1407 INT
*stops32
= (INT
*)lParam
;
1408 INT16
*stops
, buffer
[512];
1411 wParam
= min( wParam
, 0x7f80 ); /* Must be < 64K */
1412 if (!(stops
= get_buffer( buffer
, sizeof(buffer
), wParam
* sizeof(INT16
) ))) break;
1413 for (i
= 0; i
< wParam
; i
++) stops
[i
] = stops32
[i
];
1414 lParam
= MapLS( stops
);
1415 ret
= callback( HWND_16(hwnd
), LB_SETTABSTOPS16
, wParam
, lParam
, result
, arg
);
1417 free_buffer( buffer
, stops
);
1419 else ret
= callback( HWND_16(hwnd
), LB_SETTABSTOPS16
, wParam
, lParam
, result
, arg
);
1421 case CB_DELETESTRING
:
1423 case CB_GETLBTEXTLEN
:
1425 case CB_RESETCONTENT
:
1429 case CB_SHOWDROPDOWN
:
1430 case CB_SETITEMDATA
:
1431 case CB_SETITEMHEIGHT
:
1432 case CB_GETITEMHEIGHT
:
1433 case CB_SETEXTENDEDUI
:
1434 case CB_GETEXTENDEDUI
:
1435 case CB_GETDROPPEDSTATE
:
1436 ret
= callback( HWND_16(hwnd
), msg
+ CB_GETEDITSEL16
- CB_GETEDITSEL
, wParam
, lParam
, result
, arg
);
1439 ret
= callback( HWND_16(hwnd
), CB_GETEDITSEL16
, wParam
, lParam
, result
, arg
);
1440 if (wParam
) *((PUINT
)(wParam
)) = LOWORD(*result
);
1441 if (lParam
) *((PUINT
)(lParam
)) = HIWORD(*result
); /* FIXME: substract 1? */
1445 case CB_FINDSTRINGEXACT
:
1446 case CB_INSERTSTRING
:
1447 case CB_SELECTSTRING
:
1450 lParam
= MapLS( (LPSTR
)lParam
);
1451 ret
= callback( HWND_16(hwnd
), msg
+ CB_GETEDITSEL16
- CB_GETEDITSEL
, wParam
, lParam
, result
, arg
);
1454 case LB_GETITEMRECT
:
1455 case CB_GETDROPPEDCONTROLRECT
:
1457 RECT
*r32
= (RECT
*)lParam
;
1459 lParam
= MapLS( &rect
);
1460 ret
= callback( HWND_16(hwnd
),
1461 (msg
== LB_GETITEMRECT
) ? LB_GETITEMRECT16
: CB_GETDROPPEDCONTROLRECT16
,
1462 wParam
, lParam
, result
, arg
);
1464 RECT16to32( &rect
, r32
);
1467 case WM_PAINTCLIPBOARD
:
1468 case WM_SIZECLIPBOARD
:
1469 FIXME_(msg
)( "message %04x needs translation\n", msg
);
1471 /* the following messages should not be sent to 16-bit apps */
1474 case WM_CAPTURECHANGED
:
1475 case WM_STYLECHANGING
:
1476 case WM_STYLECHANGED
:
1479 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1486 /***********************************************************************
1487 * SendMessage (USER.111)
1489 LRESULT WINAPI
SendMessage16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1492 HWND hwnd
= WIN_Handle32( hwnd16
);
1494 if (hwnd
!= HWND_BROADCAST
&&
1495 GetWindowThreadProcessId( hwnd
, NULL
) == GetCurrentThreadId())
1497 /* call 16-bit window proc directly */
1500 /* first the WH_CALLWNDPROC hook */
1501 WINPROC_CallProc16To32A( cwp_hook_callback
, hwnd16
, msg
, wparam
, lparam
, &result
, NULL
);
1503 if (!(winproc
= (WNDPROC16
)GetWindowLong16( hwnd16
, GWLP_WNDPROC
))) return 0;
1505 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx\n", hwnd16
, msg
, wparam
, lparam
);
1506 result
= CallWindowProc16( winproc
, hwnd16
, msg
, wparam
, lparam
);
1507 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx returned %08lx\n",
1508 hwnd16
, msg
, wparam
, lparam
, result
);
1510 else /* map to 32-bit unicode for inter-thread/process message */
1512 WINPROC_CallProc16To32A( send_message_callback
, hwnd16
, msg
, wparam
, lparam
, &result
, NULL
);
1518 /***********************************************************************
1519 * PostMessage (USER.110)
1521 BOOL16 WINAPI
PostMessage16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1524 return WINPROC_CallProc16To32A( post_message_callback
, hwnd
, msg
, wparam
, lparam
, &unused
, NULL
);
1528 /***********************************************************************
1529 * PostAppMessage (USER.116)
1531 BOOL16 WINAPI
PostAppMessage16( HTASK16 hTask
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1534 DWORD_PTR tid
= HTASK_32( hTask
);
1536 if (!tid
) return FALSE
;
1537 return WINPROC_CallProc16To32A( post_thread_message_callback
, 0, msg
, wparam
, lparam
,
1538 &unused
, (void *)tid
);
1542 /**********************************************************************
1543 * CallWindowProc (USER.122)
1545 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
1546 WPARAM16 wParam
, LPARAM lParam
)
1548 int index
= winproc_to_index( func
);
1551 if (!func
) return 0;
1553 if (index
== -1 || index
>= MAX_WINPROCS32
)
1554 call_window_proc16( hwnd
, msg
, wParam
, lParam
, &result
, func
);
1557 WNDPROC proc
= (WNDPROC
)func
;
1558 if (thunk_array
&& thunk_array
[index
].proc
) proc
= thunk_array
[index
].proc
;
1559 WINPROC_CallProc16To32A( call_window_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, proc
);
1565 /**********************************************************************
1566 * __wine_call_wndproc (USER.1010)
1568 LRESULT WINAPI
__wine_call_wndproc( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
, WNDPROC proc
)
1571 WINPROC_CallProc16To32A( call_window_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, proc
);
1576 /***********************************************************************
1577 * InSendMessage (USER.192)
1579 BOOL16 WINAPI
InSendMessage16(void)
1581 return InSendMessage();
1585 /***********************************************************************
1586 * ReplyMessage (USER.115)
1588 void WINAPI
ReplyMessage16( LRESULT result
)
1590 ReplyMessage( result
);
1594 /***********************************************************************
1595 * PeekMessage32 (USER.819)
1597 BOOL16 WINAPI
PeekMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
,
1598 UINT16 first
, UINT16 last
, UINT16 flags
,
1599 BOOL16 wHaveParamHigh
)
1603 HWND hwnd
= WIN_Handle32( hwnd16
);
1605 if(USER16_AlertableWait
)
1606 MsgWaitForMultipleObjectsEx( 0, NULL
, 0, 0, MWMO_ALERTABLE
);
1607 if (!PeekMessageA( &msg
, hwnd
, first
, last
, flags
)) return FALSE
;
1609 msg16
->msg
.time
= msg
.time
;
1610 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
1611 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
1612 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
1613 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
1614 &unused
, &msg16
->msg
);
1619 /***********************************************************************
1620 * DefWindowProc (USER.107)
1622 LRESULT WINAPI
DefWindowProc16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
1625 HWND hwnd
= WIN_Handle32( hwnd16
);
1631 CREATESTRUCT16
*cs16
= MapSL(lParam
);
1634 cs32
.lpCreateParams
= ULongToPtr(cs16
->lpCreateParams
);
1635 cs32
.hInstance
= HINSTANCE_32(cs16
->hInstance
);
1636 cs32
.hMenu
= HMENU_32(cs16
->hMenu
);
1637 cs32
.hwndParent
= WIN_Handle32(cs16
->hwndParent
);
1642 cs32
.style
= cs16
->style
;
1643 cs32
.dwExStyle
= cs16
->dwExStyle
;
1644 cs32
.lpszName
= MapSL(cs16
->lpszName
);
1645 cs32
.lpszClass
= MapSL(cs16
->lpszClass
);
1646 return DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&cs32
);
1650 RECT16
*rect16
= MapSL(lParam
);
1653 rect32
.left
= rect16
->left
;
1654 rect32
.top
= rect16
->top
;
1655 rect32
.right
= rect16
->right
;
1656 rect32
.bottom
= rect16
->bottom
;
1658 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&rect32
);
1660 rect16
->left
= rect32
.left
;
1661 rect16
->top
= rect32
.top
;
1662 rect16
->right
= rect32
.right
;
1663 rect16
->bottom
= rect32
.bottom
;
1666 case WM_WINDOWPOSCHANGING
:
1667 case WM_WINDOWPOSCHANGED
:
1669 WINDOWPOS16
*pos16
= MapSL(lParam
);
1672 pos32
.hwnd
= WIN_Handle32(pos16
->hwnd
);
1673 pos32
.hwndInsertAfter
= WIN_Handle32(pos16
->hwndInsertAfter
);
1676 pos32
.cx
= pos16
->cx
;
1677 pos32
.cy
= pos16
->cy
;
1678 pos32
.flags
= pos16
->flags
;
1680 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&pos32
);
1682 pos16
->hwnd
= HWND_16(pos32
.hwnd
);
1683 pos16
->hwndInsertAfter
= HWND_16(pos32
.hwndInsertAfter
);
1686 pos16
->cx
= pos32
.cx
;
1687 pos16
->cy
= pos32
.cy
;
1688 pos16
->flags
= pos32
.flags
;
1693 return DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)MapSL(lParam
) );
1695 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
1700 /***********************************************************************
1701 * DefDlgProc (USER.308)
1703 LRESULT WINAPI
DefDlgProc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
1706 WINPROC_CallProc16To32A( defdlg_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, 0 );
1711 /***********************************************************************
1712 * PeekMessage (USER.109)
1714 BOOL16 WINAPI
PeekMessage16( MSG16
*msg
, HWND16 hwnd
,
1715 UINT16 first
, UINT16 last
, UINT16 flags
)
1717 return PeekMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, flags
, FALSE
);
1721 /***********************************************************************
1722 * GetMessage32 (USER.820)
1724 BOOL16 WINAPI
GetMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
, UINT16 first
,
1725 UINT16 last
, BOOL16 wHaveParamHigh
)
1729 HWND hwnd
= WIN_Handle32( hwnd16
);
1731 if(USER16_AlertableWait
)
1732 MsgWaitForMultipleObjectsEx( 0, NULL
, INFINITE
, 0, MWMO_ALERTABLE
);
1733 GetMessageA( &msg
, hwnd
, first
, last
);
1734 msg16
->msg
.time
= msg
.time
;
1735 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
1736 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
1737 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
1738 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
1739 &unused
, &msg16
->msg
);
1741 TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
1742 msg16
->msg
.message
, hwnd
, first
, last
);
1744 return msg16
->msg
.message
!= WM_QUIT
;
1748 /***********************************************************************
1749 * GetMessage (USER.108)
1751 BOOL16 WINAPI
GetMessage16( MSG16
*msg
, HWND16 hwnd
, UINT16 first
, UINT16 last
)
1753 return GetMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, FALSE
);
1757 /***********************************************************************
1758 * TranslateMessage32 (USER.821)
1760 BOOL16 WINAPI
TranslateMessage32_16( const MSG32_16
*msg
, BOOL16 wHaveParamHigh
)
1764 msg32
.hwnd
= WIN_Handle32( msg
->msg
.hwnd
);
1765 msg32
.message
= msg
->msg
.message
;
1766 msg32
.wParam
= MAKEWPARAM( msg
->msg
.wParam
, wHaveParamHigh
? msg
->wParamHigh
: 0 );
1767 msg32
.lParam
= msg
->msg
.lParam
;
1768 return TranslateMessage( &msg32
);
1772 /***********************************************************************
1773 * TranslateMessage (USER.113)
1775 BOOL16 WINAPI
TranslateMessage16( const MSG16
*msg
)
1777 return TranslateMessage32_16( (const MSG32_16
*)msg
, FALSE
);
1781 /***********************************************************************
1782 * DispatchMessage (USER.114)
1784 LONG WINAPI
DispatchMessage16( const MSG16
* msg
)
1789 /* Process timer messages */
1790 if ((msg
->message
== WM_TIMER
) || (msg
->message
== WM_SYSTIMER
))
1793 return CallWindowProc16( (WNDPROC16
)msg
->lParam
, msg
->hwnd
,
1794 msg
->message
, msg
->wParam
, GetTickCount() );
1797 if (!(winproc
= (WNDPROC16
)GetWindowLong16( msg
->hwnd
, GWLP_WNDPROC
)))
1799 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
1802 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx\n", msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1803 retval
= CallWindowProc16( winproc
, msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1804 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx returned %08lx\n",
1805 msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
, retval
);
1810 /***********************************************************************
1811 * DispatchMessage32 (USER.822)
1813 LONG WINAPI
DispatchMessage32_16( const MSG32_16
*msg16
, BOOL16 wHaveParamHigh
)
1815 if (wHaveParamHigh
== FALSE
)
1816 return DispatchMessage16( &msg16
->msg
);
1821 msg
.hwnd
= WIN_Handle32( msg16
->msg
.hwnd
);
1822 msg
.message
= msg16
->msg
.message
;
1823 msg
.wParam
= MAKEWPARAM( msg16
->msg
.wParam
, msg16
->wParamHigh
);
1824 msg
.lParam
= msg16
->msg
.lParam
;
1825 msg
.time
= msg16
->msg
.time
;
1826 msg
.pt
.x
= msg16
->msg
.pt
.x
;
1827 msg
.pt
.y
= msg16
->msg
.pt
.y
;
1828 return DispatchMessageA( &msg
);
1833 /***********************************************************************
1834 * IsDialogMessage (USER.90)
1836 BOOL16 WINAPI
IsDialogMessage16( HWND16 hwndDlg
, MSG16
*msg16
)
1841 msg
.hwnd
= WIN_Handle32(msg16
->hwnd
);
1842 hwndDlg32
= WIN_Handle32(hwndDlg
);
1844 switch(msg16
->message
)
1849 msg
.message
= msg16
->message
;
1850 msg
.wParam
= msg16
->wParam
;
1851 msg
.lParam
= msg16
->lParam
;
1852 return IsDialogMessageA( hwndDlg32
, &msg
);
1855 if ((hwndDlg32
!= msg
.hwnd
) && !IsChild( hwndDlg32
, msg
.hwnd
)) return FALSE
;
1856 TranslateMessage16( msg16
);
1857 DispatchMessage16( msg16
);
1862 /***********************************************************************
1863 * MsgWaitForMultipleObjects (USER.640)
1865 DWORD WINAPI
MsgWaitForMultipleObjects16( DWORD count
, CONST HANDLE
*handles
,
1866 BOOL wait_all
, DWORD timeout
, DWORD mask
)
1868 return MsgWaitForMultipleObjectsEx( count
, handles
, timeout
, mask
,
1869 wait_all
? MWMO_WAITALL
: 0 );
1873 /**********************************************************************
1874 * SetDoubleClickTime (USER.20)
1876 void WINAPI
SetDoubleClickTime16( UINT16 interval
)
1878 SetDoubleClickTime( interval
);
1882 /**********************************************************************
1883 * GetDoubleClickTime (USER.21)
1885 UINT16 WINAPI
GetDoubleClickTime16(void)
1887 return GetDoubleClickTime();
1891 /***********************************************************************
1892 * PostQuitMessage (USER.6)
1894 void WINAPI
PostQuitMessage16( INT16 exitCode
)
1896 PostQuitMessage( exitCode
);
1900 /**********************************************************************
1901 * GetKeyState (USER.106)
1903 INT16 WINAPI
GetKeyState16(INT16 vkey
)
1905 return GetKeyState(vkey
);
1909 /**********************************************************************
1910 * GetKeyboardState (USER.222)
1912 BOOL WINAPI
GetKeyboardState16( LPBYTE state
)
1914 return GetKeyboardState( state
);
1918 /**********************************************************************
1919 * SetKeyboardState (USER.223)
1921 BOOL WINAPI
SetKeyboardState16( LPBYTE state
)
1923 return SetKeyboardState( state
);
1927 /***********************************************************************
1928 * SetMessageQueue (USER.266)
1930 BOOL16 WINAPI
SetMessageQueue16( INT16 size
)
1932 return SetMessageQueue( size
);
1936 /***********************************************************************
1937 * UserYield (USER.332)
1939 void WINAPI
UserYield16(void)
1942 PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
| PM_QS_SENDMESSAGE
);
1946 /***********************************************************************
1947 * GetQueueStatus (USER.334)
1949 DWORD WINAPI
GetQueueStatus16( UINT16 flags
)
1951 return GetQueueStatus( flags
);
1955 /***********************************************************************
1956 * GetInputState (USER.335)
1958 BOOL16 WINAPI
GetInputState16(void)
1960 return GetInputState();
1964 /**********************************************************************
1965 * TranslateAccelerator (USER.178)
1967 INT16 WINAPI
TranslateAccelerator16( HWND16 hwnd
, HACCEL16 hAccel
, LPMSG16 msg
)
1972 msg32
.message
= msg
->message
;
1973 /* msg32.hwnd not used */
1974 msg32
.wParam
= msg
->wParam
;
1975 msg32
.lParam
= msg
->lParam
;
1976 return TranslateAcceleratorW( WIN_Handle32(hwnd
), HACCEL_32(hAccel
), &msg32
);
1980 /**********************************************************************
1981 * TranslateMDISysAccel (USER.451)
1983 BOOL16 WINAPI
TranslateMDISysAccel16( HWND16 hwndClient
, LPMSG16 msg
)
1985 if (msg
->message
== WM_KEYDOWN
|| msg
->message
== WM_SYSKEYDOWN
)
1988 msg32
.hwnd
= WIN_Handle32(msg
->hwnd
);
1989 msg32
.message
= msg
->message
;
1990 msg32
.wParam
= msg
->wParam
;
1991 msg32
.lParam
= msg
->lParam
;
1992 /* MDICLIENTINFO is still the same for win32 and win16 ... */
1993 return TranslateMDISysAccel( WIN_Handle32(hwndClient
), &msg32
);
1999 /***********************************************************************
2002 static LRESULT
button_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2004 static const UINT msg16_offset
= BM_GETCHECK16
- BM_GETCHECK
;
2013 return wow_handlers32
.button_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2015 return wow_handlers32
.button_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2020 /***********************************************************************
2023 static LRESULT
combo_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2025 static const UINT msg16_offset
= CB_GETEDITSEL16
- CB_GETEDITSEL
;
2029 case CB_INSERTSTRING16
:
2030 case CB_SELECTSTRING16
:
2031 case CB_FINDSTRING16
:
2032 case CB_FINDSTRINGEXACT16
:
2033 wParam
= (INT
)(INT16
)wParam
;
2035 case CB_ADDSTRING16
:
2037 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2038 if ((style
& CBS_HASSTRINGS
) || !(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)))
2039 lParam
= (LPARAM
)MapSL(lParam
);
2040 msg
-= msg16_offset
;
2043 case CB_SETITEMHEIGHT16
:
2044 case CB_GETITEMHEIGHT16
:
2045 case CB_SETCURSEL16
:
2046 case CB_GETLBTEXTLEN16
:
2047 case CB_GETITEMDATA16
:
2048 case CB_SETITEMDATA16
:
2049 wParam
= (INT
)(INT16
)wParam
; /* signed integer */
2050 msg
-= msg16_offset
;
2052 case CB_GETDROPPEDCONTROLRECT16
:
2053 lParam
= (LPARAM
)MapSL(lParam
);
2057 RECT16
*r16
= (RECT16
*)lParam
;
2058 wow_handlers32
.combo_proc( hwnd
, CB_GETDROPPEDCONTROLRECT
, wParam
, (LPARAM
)&r
, FALSE
);
2061 r16
->right
= r
.right
;
2062 r16
->bottom
= r
.bottom
;
2066 if (wParam
& DDL_DRIVES
) wParam
|= DDL_EXCLUSIVE
;
2067 lParam
= (LPARAM
)MapSL(lParam
);
2068 msg
-= msg16_offset
;
2070 case CB_GETLBTEXT16
:
2071 wParam
= (INT
)(INT16
)wParam
;
2072 lParam
= (LPARAM
)MapSL(lParam
);
2073 msg
-= msg16_offset
;
2075 case CB_GETEDITSEL16
:
2076 wParam
= lParam
= 0; /* just in case */
2077 msg
-= msg16_offset
;
2079 case CB_LIMITTEXT16
:
2080 case CB_SETEDITSEL16
:
2081 case CB_DELETESTRING16
:
2082 case CB_RESETCONTENT16
:
2083 case CB_GETDROPPEDSTATE16
:
2084 case CB_SHOWDROPDOWN16
:
2086 case CB_GETCURSEL16
:
2087 case CB_SETEXTENDEDUI16
:
2088 case CB_GETEXTENDEDUI16
:
2089 msg
-= msg16_offset
;
2092 return wow_handlers32
.combo_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2094 return wow_handlers32
.combo_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2097 /*********************************************************************
2098 * edit_lock_buffer (internal)
2100 * A 16 bit application might send an EM_GETHANDLE message and expect a HLOCAL16
2101 * (16 bit SEG:OFF handler). From that moment on we have to keep using this
2102 * 16 bit memory handler, because it is supposed to be valid at all times after
2104 * We create a HLOCAL16 buffer in edit_get_handle and copy the text from the
2105 * HLOCAL buffer, when needed
2109 #define GWW_HANDLE16 sizeof(void*)
2111 static void edit_lock_buffer( HWND hwnd
)
2113 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2114 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2119 if (!hloc16
) return;
2120 if (!(hloc32
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return;
2122 oldDS
= stack16
->ds
;
2123 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2124 size
= LocalSize16(hloc16
);
2125 if (LocalReAlloc( hloc32
, size
, LMEM_MOVEABLE
))
2127 char *text
= MapSL( LocalLock16( hloc16
));
2128 char *dest
= LocalLock( hloc32
);
2129 memcpy( dest
, text
, size
);
2130 LocalUnlock( hloc32
);
2131 LocalUnlock16( hloc16
);
2133 stack16
->ds
= oldDS
;
2137 static void edit_unlock_buffer( HWND hwnd
)
2139 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2140 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2145 if (!hloc16
) return;
2146 if (!(hloc32
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return;
2147 size
= LocalSize( hloc32
);
2149 oldDS
= stack16
->ds
;
2150 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2151 if (LocalReAlloc16( hloc16
, size
, LMEM_MOVEABLE
))
2153 char *text
= LocalLock( hloc32
);
2154 char *dest
= MapSL( LocalLock16( hloc16
));
2155 memcpy( dest
, text
, size
);
2156 LocalUnlock( hloc32
);
2157 LocalUnlock16( hloc16
);
2159 stack16
->ds
= oldDS
;
2162 static HLOCAL16
edit_get_handle( HWND hwnd
)
2167 STACK16FRAME
* stack16
;
2169 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2171 if (hloc16
) return hloc16
;
2173 if (!(hloc
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return 0;
2174 alloc_size
= LocalSize( hloc
);
2176 stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2177 oldDS
= stack16
->ds
;
2178 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2180 if (!LocalHeapSize16())
2182 if (!LocalInit16(stack16
->ds
, 0, GlobalSize16(stack16
->ds
)))
2184 ERR("could not initialize local heap\n");
2189 if (!(hloc16
= LocalAlloc16(LMEM_MOVEABLE
| LMEM_ZEROINIT
, alloc_size
)))
2191 ERR("could not allocate new 16 bit buffer\n");
2195 if (!(textA
= MapSL(LocalLock16( hloc16
))))
2197 ERR("could not lock new 16 bit buffer\n");
2198 LocalFree16(hloc16
);
2202 memcpy( textA
, LocalLock( hloc
), alloc_size
);
2203 LocalUnlock( hloc
);
2204 LocalUnlock16( hloc16
);
2205 SetWindowWord( hwnd
, GWW_HANDLE16
, hloc16
);
2208 stack16
->ds
= oldDS
;
2212 static void edit_set_handle( HWND hwnd
, HLOCAL16 hloc16
)
2214 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2215 HINSTANCE16 hInstance
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2216 HANDLE16 oldDS
= stack16
->ds
;
2221 if (!(GetWindowLongW( hwnd
, GWL_STYLE
) & ES_MULTILINE
)) return;
2222 if (!hloc16
) return;
2224 stack16
->ds
= hInstance
;
2225 count
= LocalSize16(hloc16
);
2226 text
= MapSL(LocalLock16(hloc16
));
2227 if ((hloc32
= LocalAlloc(LMEM_MOVEABLE
, count
)))
2229 memcpy( LocalLock(hloc32
), text
, count
);
2230 LocalUnlock(hloc32
);
2231 LocalUnlock16(hloc16
);
2232 SetWindowWord( hwnd
, GWW_HANDLE16
, hloc16
);
2234 stack16
->ds
= oldDS
;
2236 if (hloc32
) wow_handlers32
.edit_proc( hwnd
, EM_SETHANDLE
, (WPARAM
)hloc32
, 0, FALSE
);
2239 static void edit_destroy_handle( HWND hwnd
)
2241 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2244 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2245 HANDLE16 oldDS
= stack16
->ds
;
2247 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2248 while (LocalUnlock16(hloc16
)) ;
2249 LocalFree16(hloc16
);
2250 stack16
->ds
= oldDS
;
2251 SetWindowWord( hwnd
, GWW_HANDLE16
, 0 );
2255 /*********************************************************************
2258 static LRESULT
edit_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2260 static const UINT msg16_offset
= EM_GETSEL16
- EM_GETSEL
;
2263 edit_lock_buffer( hwnd
);
2267 case EM_SCROLLCARET16
:
2268 case EM_GETMODIFY16
:
2269 case EM_SETMODIFY16
:
2270 case EM_GETLINECOUNT16
:
2272 case EM_LINELENGTH16
:
2273 case EM_LIMITTEXT16
:
2277 case EM_LINEFROMCHAR16
:
2278 case EM_SETPASSWORDCHAR16
:
2279 case EM_EMPTYUNDOBUFFER16
:
2280 case EM_SETREADONLY16
:
2281 case EM_GETPASSWORDCHAR16
:
2282 /* these messages missing from specs */
2287 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2290 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, 0, 0, FALSE
);
2292 case EM_REPLACESEL16
:
2294 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)MapSL(lParam
), FALSE
);
2296 case EM_LINESCROLL16
:
2297 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, (INT
)(SHORT
)HIWORD(lParam
),
2298 (INT
)(SHORT
)LOWORD(lParam
), FALSE
);
2300 case EM_LINEINDEX16
:
2301 if ((INT16
)wParam
== -1) wParam
= -1;
2302 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2305 if ((short)LOWORD(lParam
) == -1)
2312 wParam
= LOWORD(lParam
);
2313 lParam
= HIWORD(lParam
);
2315 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2321 RECT16
*r16
= MapSL(lParam
);
2322 wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)&rect
, FALSE
);
2323 r16
->left
= rect
.left
;
2324 r16
->top
= rect
.top
;
2325 r16
->right
= rect
.right
;
2326 r16
->bottom
= rect
.bottom
;
2330 case EM_SETRECTNP16
:
2334 RECT16
*r16
= MapSL(lParam
);
2335 rect
.left
= r16
->left
;
2336 rect
.top
= r16
->top
;
2337 rect
.right
= r16
->right
;
2338 rect
.bottom
= r16
->bottom
;
2339 wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)&rect
, FALSE
);
2342 case EM_SETHANDLE16
:
2343 edit_set_handle( hwnd
, (HLOCAL16
)wParam
);
2345 case EM_GETHANDLE16
:
2346 result
= edit_get_handle( hwnd
);
2348 case EM_SETTABSTOPS16
:
2350 INT16
*tabs16
= MapSL(lParam
);
2351 INT i
, count
= wParam
, *tabs
= NULL
;
2354 if (!(tabs
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*tabs
) ))) return 0;
2355 for (i
= 0; i
< count
; i
++) tabs
[i
] = tabs16
[i
];
2357 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, count
, (LPARAM
)tabs
, FALSE
);
2358 HeapFree( GetProcessHeap(), 0, tabs
);
2361 case EM_GETFIRSTVISIBLELINE16
:
2362 if (!(GetWindowLongW( hwnd
, GWL_STYLE
) & ES_MULTILINE
)) break;
2363 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2365 case EM_SETWORDBREAKPROC16
:
2367 struct word_break_thunk
*thunk
= add_word_break_thunk( (EDITWORDBREAKPROC16
)lParam
);
2368 result
= wow_handlers32
.edit_proc( hwnd
, EM_SETWORDBREAKPROC
, wParam
, (LPARAM
)thunk
, FALSE
);
2371 case EM_GETWORDBREAKPROC16
:
2372 result
= wow_handlers32
.edit_proc( hwnd
, EM_GETWORDBREAKPROC
, wParam
, lParam
, FALSE
);
2373 result
= (LRESULT
)get_word_break_thunk( (EDITWORDBREAKPROCA
)result
);
2376 edit_destroy_handle( hwnd
);
2377 return wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
); /* no unlock on destroy */
2380 if (LOWORD(wParam
) == EM_GETTHUMB16
|| LOWORD(wParam
) == EM_LINESCROLL16
) wParam
-= msg16_offset
;
2381 result
= wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2384 result
= wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2387 edit_unlock_buffer( hwnd
);
2392 /***********************************************************************
2395 static LRESULT
listbox_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2397 static const UINT msg16_offset
= LB_ADDSTRING16
- LB_ADDSTRING
;
2403 if (is_old_app( hwnd
))
2405 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2406 int height
, remaining
, item_height
;
2409 /* give a margin for error to old 16 bits programs - if we need
2410 less than the height of the nonclient area, round to the
2411 *next* number of items */
2413 if (!(style
& LBS_NOINTEGRALHEIGHT
) && !(style
& LBS_OWNERDRAWVARIABLE
))
2415 GetClientRect( hwnd
, &rect
);
2416 height
= rect
.bottom
- rect
.top
;
2417 item_height
= wow_handlers32
.listbox_proc( hwnd
, LB_GETITEMHEIGHT
, 0, 0, FALSE
);
2418 remaining
= item_height
? (height
% item_height
) : 0;
2419 if ((height
> item_height
) && remaining
)
2421 GetWindowRect( hwnd
, &rect
);
2422 if ((item_height
- remaining
) <= rect
.bottom
- rect
.top
- height
)
2423 remaining
= remaining
- item_height
;
2424 TRACE( "[%p]: changing height %d -> %d\n", hwnd
, height
, height
- remaining
);
2425 SetWindowPos( hwnd
, 0, 0, 0, rect
.right
- rect
.left
,
2426 rect
.bottom
- rect
.top
- remaining
,
2427 SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOMOVE
);
2432 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2434 case LB_RESETCONTENT16
:
2435 case LB_DELETESTRING16
:
2436 case LB_GETITEMDATA16
:
2437 case LB_SETITEMDATA16
:
2439 case LB_GETTEXTLEN16
:
2440 case LB_GETCURSEL16
:
2441 case LB_GETTOPINDEX16
:
2442 case LB_GETITEMHEIGHT16
:
2443 case LB_SETCARETINDEX16
:
2444 case LB_GETCARETINDEX16
:
2445 case LB_SETTOPINDEX16
:
2446 case LB_SETCOLUMNWIDTH16
:
2447 case LB_GETSELCOUNT16
:
2448 case LB_SELITEMRANGE16
:
2449 case LB_SELITEMRANGEEX16
:
2450 case LB_GETHORIZONTALEXTENT16
:
2451 case LB_SETHORIZONTALEXTENT16
:
2452 case LB_GETANCHORINDEX16
:
2455 msg
-= msg16_offset
;
2459 case LB_SETCURSEL16
:
2460 case LB_SETANCHORINDEX16
:
2461 wParam
= (INT
)(INT16
)wParam
;
2462 msg
-= msg16_offset
;
2464 case LB_INSERTSTRING16
:
2465 case LB_FINDSTRING16
:
2466 case LB_FINDSTRINGEXACT16
:
2467 case LB_SELECTSTRING16
:
2468 wParam
= (INT
)(INT16
)wParam
;
2470 case LB_ADDSTRING16
:
2473 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2474 if ((style
& LBS_HASSTRINGS
) || !(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)))
2475 lParam
= (LPARAM
)MapSL(lParam
);
2476 msg
-= msg16_offset
;
2480 lParam
= (LPARAM
)MapSL(lParam
);
2481 msg
-= msg16_offset
;
2483 case LB_SETITEMHEIGHT16
:
2484 lParam
= LOWORD(lParam
);
2485 msg
-= msg16_offset
;
2487 case LB_GETITEMRECT16
:
2490 RECT16
*r16
= MapSL(lParam
);
2491 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_GETITEMRECT
, (INT16
)wParam
, (LPARAM
)&rect
, FALSE
);
2492 r16
->left
= rect
.left
;
2493 r16
->top
= rect
.top
;
2494 r16
->right
= rect
.right
;
2495 r16
->bottom
= rect
.bottom
;
2498 case LB_GETSELITEMS16
:
2500 INT16
*array16
= MapSL( lParam
);
2501 INT i
, count
= (INT16
)wParam
, *array
;
2502 if (!(array
= HeapAlloc( GetProcessHeap(), 0, wParam
* sizeof(*array
) ))) return LB_ERRSPACE
;
2503 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_GETSELITEMS
, count
, (LPARAM
)array
, FALSE
);
2504 for (i
= 0; i
< ret
; i
++) array16
[i
] = array
[i
];
2505 HeapFree( GetProcessHeap(), 0, array
);
2509 /* according to Win16 docs, DDL_DRIVES should make DDL_EXCLUSIVE
2510 * be set automatically (this is different in Win32) */
2511 if (wParam
& DDL_DRIVES
) wParam
|= DDL_EXCLUSIVE
;
2512 lParam
= (LPARAM
)MapSL(lParam
);
2513 msg
-= msg16_offset
;
2515 case LB_SETTABSTOPS16
:
2517 INT i
, count
, *tabs
= NULL
;
2518 INT16
*tabs16
= MapSL( lParam
);
2520 if ((count
= (INT16
)wParam
) > 0)
2522 if (!(tabs
= HeapAlloc( GetProcessHeap(), 0, wParam
* sizeof(*tabs
) ))) return LB_ERRSPACE
;
2523 for (i
= 0; i
< count
; i
++) tabs
[i
] = tabs16
[i
] << 1; /* FIXME */
2525 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_SETTABSTOPS
, count
, (LPARAM
)tabs
, FALSE
);
2526 HeapFree( GetProcessHeap(), 0, tabs
);
2530 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2532 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2536 /***********************************************************************
2539 static LRESULT
mdiclient_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2541 if (msg
== WM_CREATE
)
2543 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
2544 HINSTANCE instance
= (HINSTANCE
)GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2545 BOOL is_win32
= !instance
|| ((ULONG_PTR
)instance
>> 16);
2547 /* Translation layer doesn't know what's in the cs->lpCreateParams
2548 * so we have to keep track of what environment we're in. */
2551 void *orig
= cs
->lpCreateParams
;
2553 CLIENTCREATESTRUCT ccs
;
2554 CLIENTCREATESTRUCT16
*ccs16
= MapSL( PtrToUlong( orig
));
2556 ccs
.hWindowMenu
= HMENU_32(ccs16
->hWindowMenu
);
2557 ccs
.idFirstChild
= ccs16
->idFirstChild
;
2558 cs
->lpCreateParams
= &ccs
;
2559 ret
= wow_handlers32
.mdiclient_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2560 cs
->lpCreateParams
= orig
;
2564 return wow_handlers32
.mdiclient_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2568 /***********************************************************************
2571 static LRESULT
scrollbar_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2573 static const UINT msg16_offset
= SBM_SETPOS16
- SBM_SETPOS
;
2579 case SBM_ENABLE_ARROWS16
:
2580 msg
-= msg16_offset
;
2582 case SBM_SETRANGE16
:
2583 msg
= wParam
? SBM_SETRANGEREDRAW
: SBM_SETRANGE
;
2584 wParam
= LOWORD(lParam
);
2585 lParam
= HIWORD(lParam
);
2587 case SBM_GETRANGE16
:
2590 wow_handlers32
.scrollbar_proc( hwnd
, SBM_GETRANGE
, (WPARAM
)&min
, (LPARAM
)&max
, FALSE
);
2591 return MAKELRESULT(min
, max
);
2594 return wow_handlers32
.scrollbar_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2596 return wow_handlers32
.scrollbar_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2600 /***********************************************************************
2603 static LRESULT
static_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2609 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
2610 LRESULT ret
= wow_handlers32
.static_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2613 if (((ULONG_PTR
)cs
->hInstance
>> 16)) return ret
; /* 32-bit instance, nothing to do */
2614 switch (cs
->style
& SS_TYPEMASK
)
2618 HICON16 icon
= LoadIcon16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2619 if (!icon
) icon
= LoadCursor16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2620 if (icon
) wow_handlers32
.static_proc( hwnd
, STM_SETIMAGE
, IMAGE_ICON
,
2621 (LPARAM
)get_icon_32(icon
), FALSE
);
2626 HBITMAP16 bitmap
= LoadBitmap16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2627 if (bitmap
) wow_handlers32
.static_proc( hwnd
, STM_SETIMAGE
, IMAGE_BITMAP
,
2628 (LPARAM
)HBITMAP_32(bitmap
), FALSE
);
2635 wParam
= (WPARAM
)get_icon_32( (HICON16
)wParam
);
2636 return wow_handlers32
.static_proc( hwnd
, STM_SETICON
, wParam
, lParam
, FALSE
);
2638 return get_icon_16( (HICON
)wow_handlers32
.static_proc( hwnd
, STM_GETICON
, wParam
, lParam
, FALSE
));
2640 return wow_handlers32
.static_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2645 /***********************************************************************
2648 static DWORD
wait_message16( DWORD count
, CONST HANDLE
*handles
, DWORD timeout
, DWORD mask
, DWORD flags
)
2652 ReleaseThunkLock( &lock
);
2653 ret
= wow_handlers32
.wait_message( count
, handles
, timeout
, mask
, flags
);
2654 RestoreThunkLock( lock
);
2659 /***********************************************************************
2662 HWND
create_window16( CREATESTRUCTW
*cs
, LPCWSTR className
, HINSTANCE instance
, BOOL unicode
)
2664 /* map to module handle */
2665 if (instance
&& !((ULONG_PTR
)instance
>> 16))
2666 instance
= HINSTANCE_32( GetExePtr( HINSTANCE_16(instance
) ));
2668 return wow_handlers32
.create_window( cs
, className
, instance
, unicode
);
2672 /***********************************************************************
2675 static void free_icon_param( ULONG_PTR param
)
2677 GlobalFree16( LOWORD(param
) );
2681 void register_wow_handlers(void)
2683 static const struct wow_handlers16 handlers16
=
2694 call_window_proc_Ato16
,
2695 call_dialog_proc_Ato16
,
2699 UserRegisterWowHandlers( &handlers16
, &wow_handlers32
);