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
send_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
43 LRESULT
*result
, void *arg
)
45 *result
= SendMessageA( hwnd
, msg
, wp
, lp
);
49 static LRESULT
post_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
50 LRESULT
*result
, void *arg
)
53 return PostMessageA( hwnd
, msg
, wp
, lp
);
56 static LRESULT
post_thread_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
57 LRESULT
*result
, void *arg
)
59 DWORD_PTR tid
= (DWORD_PTR
)arg
;
61 return PostThreadMessageA( tid
, msg
, wp
, lp
);
64 static LRESULT
get_message_callback( HWND16 hwnd
, UINT16 msg
, WPARAM16 wp
, LPARAM lp
,
65 LRESULT
*result
, void *arg
)
77 static LRESULT
defdlg_proc_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
78 LRESULT
*result
, void *arg
)
80 *result
= DefDlgProcA( hwnd
, msg
, wp
, lp
);
84 static LRESULT
call_window_proc_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
85 LRESULT
*result
, void *arg
)
88 *result
= CallWindowProcA( proc
, hwnd
, msg
, wp
, lp
);
93 /**********************************************************************
94 * Support for window procedure thunks
100 BYTE popl_eax
; /* popl %eax (return address) */
101 BYTE pushl_func
; /* pushl $proc */
103 BYTE pushl_eax
; /* pushl %eax */
104 BYTE ljmp
; /* ljmp relay*/
105 DWORD relay_offset
; /* __wine_call_wndproc */
110 #define WINPROC_HANDLE (~0u >> 16)
111 #define MAX_WINPROCS32 4096
112 #define MAX_WINPROCS16 1024
114 static WNDPROC16 winproc16_array
[MAX_WINPROCS16
];
115 static unsigned int winproc16_used
;
117 static WINPROC_THUNK
*thunk_array
;
118 static UINT thunk_selector
;
120 /* return the window proc index for a given handle, or -1 for an invalid handle
121 * indices 0 .. MAX_WINPROCS32-1 are for 32-bit procs,
122 * indices MAX_WINPROCS32 .. MAX_WINPROCS32+MAX_WINPROCS16-1 for 16-bit procs */
123 static int winproc_to_index( WNDPROC16 handle
)
127 if (HIWORD(handle
) == thunk_selector
)
129 index
= LOWORD(handle
) / sizeof(WINPROC_THUNK
);
130 /* check alignment */
131 if (index
* sizeof(WINPROC_THUNK
) != LOWORD(handle
)) return -1;
132 /* check array limits */
133 if (index
>= MAX_WINPROCS32
) return -1;
137 index
= LOWORD(handle
);
138 if ((ULONG_PTR
)handle
>> 16 != WINPROC_HANDLE
) return -1;
139 /* check array limits */
140 if (index
>= winproc16_used
+ MAX_WINPROCS32
) return -1;
145 /* allocate a 16-bit thunk for an existing window proc */
146 static WNDPROC16
alloc_win16_thunk( WNDPROC handle
)
148 static FARPROC16 relay
;
149 WINPROC_THUNK
*thunk
;
150 UINT index
= LOWORD( handle
);
152 if (index
>= MAX_WINPROCS32
) /* already a 16-bit proc */
153 return winproc16_array
[index
- MAX_WINPROCS32
];
155 if (!thunk_array
) /* allocate the array and its selector */
159 assert( MAX_WINPROCS16
* sizeof(WINPROC_THUNK
) <= 0x10000 );
161 if (!(thunk_selector
= wine_ldt_alloc_entries(1))) return NULL
;
162 if (!(thunk_array
= VirtualAlloc( NULL
, MAX_WINPROCS16
* sizeof(WINPROC_THUNK
), MEM_COMMIT
,
163 PAGE_EXECUTE_READWRITE
))) return NULL
;
164 wine_ldt_set_base( &entry
, thunk_array
);
165 wine_ldt_set_limit( &entry
, MAX_WINPROCS16
* sizeof(WINPROC_THUNK
) - 1 );
166 wine_ldt_set_flags( &entry
, WINE_LDT_FLAGS_CODE
| WINE_LDT_FLAGS_32BIT
);
167 wine_ldt_set_entry( thunk_selector
, &entry
);
168 relay
= GetProcAddress16( GetModuleHandle16("user"), "__wine_call_wndproc" );
171 thunk
= &thunk_array
[index
];
172 thunk
->popl_eax
= 0x58; /* popl %eax */
173 thunk
->pushl_func
= 0x68; /* pushl $proc */
174 thunk
->proc
= handle
;
175 thunk
->pushl_eax
= 0x50; /* pushl %eax */
176 thunk
->ljmp
= 0xea; /* ljmp relay*/
177 thunk
->relay_offset
= OFFSETOF(relay
);
178 thunk
->relay_sel
= SELECTOROF(relay
);
179 return (WNDPROC16
)MAKESEGPTR( thunk_selector
, index
* sizeof(WINPROC_THUNK
) );
182 /**********************************************************************
183 * WINPROC_AllocProc16
185 WNDPROC
WINPROC_AllocProc16( WNDPROC16 func
)
190 if (!func
) return NULL
;
192 /* check if the function is already a win proc */
193 if ((index
= winproc_to_index( func
)) != -1)
194 return (WNDPROC
)(ULONG_PTR
)(index
| (WINPROC_HANDLE
<< 16));
196 /* then check if we already have a winproc for that function */
197 for (index
= 0; index
< winproc16_used
; index
++)
198 if (winproc16_array
[index
] == func
) goto done
;
200 if (winproc16_used
>= MAX_WINPROCS16
)
202 FIXME( "too many winprocs, cannot allocate one for 16-bit %p\n", func
);
205 winproc16_array
[winproc16_used
++] = func
;
208 ret
= (WNDPROC
)(ULONG_PTR
)((index
+ MAX_WINPROCS32
) | (WINPROC_HANDLE
<< 16));
209 TRACE( "returning %p for %p/16-bit (%d/%d used)\n",
210 ret
, func
, winproc16_used
, MAX_WINPROCS16
);
214 /**********************************************************************
217 * Get a window procedure pointer that can be passed to the Windows program.
219 WNDPROC16
WINPROC_GetProc16( WNDPROC proc
, BOOL unicode
)
221 WNDPROC winproc
= wow_handlers32
.alloc_winproc( proc
, unicode
);
223 if ((ULONG_PTR
)winproc
>> 16 != WINPROC_HANDLE
) return (WNDPROC16
)winproc
;
224 return alloc_win16_thunk( winproc
);
227 /* call a 16-bit window procedure */
228 static LRESULT
call_window_proc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
229 LRESULT
*result
, void *arg
)
231 DPI_AWARENESS_CONTEXT awareness
;
232 WNDPROC16 func
= arg
;
233 int index
= winproc_to_index( func
);
242 DRAWITEMSTRUCT16 dis16
;
243 COMPAREITEMSTRUCT16 cis16
;
247 if (index
>= MAX_WINPROCS32
) func
= winproc16_array
[index
- MAX_WINPROCS32
];
249 /* Window procedures want ax = hInstance, ds = es = ss */
251 memset(&context
, 0, sizeof(context
));
252 context
.SegDs
= context
.SegEs
= SELECTOROF(NtCurrentTeb()->WOW32Reserved
);
253 context
.SegFs
= wine_get_fs();
254 context
.SegGs
= wine_get_gs();
255 if (!(context
.Eax
= GetWindowWord( HWND_32(hwnd
), GWLP_HINSTANCE
))) context
.Eax
= context
.SegDs
;
256 context
.SegCs
= SELECTOROF(func
);
257 context
.Eip
= OFFSETOF(func
);
258 context
.Ebp
= OFFSETOF(NtCurrentTeb()->WOW32Reserved
) + FIELD_OFFSET(STACK16FRAME
, bp
);
262 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
263 work if structures passed in lParam are placed in the stack/data
264 segment. Programmers easily make the mistake of converting lParam
265 to a near rather than a far pointer, since Windows apparently
266 allows this. We copy the structures to the 16 bit stack; this is
267 ugly but makes these programs work. */
272 size
= sizeof(CREATESTRUCT16
); break;
274 size
= sizeof(DRAWITEMSTRUCT16
); break;
276 size
= sizeof(COMPAREITEMSTRUCT16
); break;
280 memcpy( &args
.u
, MapSL(lParam
), size
);
281 lParam
= PtrToUlong(NtCurrentTeb()->WOW32Reserved
) - size
;
285 awareness
= SetThreadDpiAwarenessContext( GetWindowDpiAwarenessContext( HWND_32(hwnd
) ));
286 args
.params
[4] = hwnd
;
287 args
.params
[3] = msg
;
288 args
.params
[2] = wParam
;
289 args
.params
[1] = HIWORD(lParam
);
290 args
.params
[0] = LOWORD(lParam
);
291 WOWCallback16Ex( 0, WCB16_REGS
, sizeof(args
.params
) + size
, &args
, (DWORD
*)&context
);
292 *result
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
293 SetThreadDpiAwarenessContext( awareness
);
297 static LRESULT
call_dialog_proc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wp
, LPARAM lp
,
298 LRESULT
*result
, void *arg
)
300 LRESULT ret
= call_window_proc16( hwnd
, msg
, wp
, lp
, result
, arg
);
301 *result
= GetWindowLongPtrW( WIN_Handle32(hwnd
), DWLP_MSGRESULT
);
305 static LRESULT
call_window_proc_Ato16( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
306 LRESULT
*result
, void *arg
)
308 return WINPROC_CallProc32ATo16( call_window_proc16
, hwnd
, msg
, wp
, lp
, result
, arg
);
311 static LRESULT
call_dialog_proc_Ato16( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
312 LRESULT
*result
, void *arg
)
314 return WINPROC_CallProc32ATo16( call_dialog_proc16
, hwnd
, msg
, wp
, lp
, result
, arg
);
319 /**********************************************************************
320 * Support for Edit word break proc thunks
323 #define MAX_THUNKS 32
325 #include <pshpack1.h>
326 static struct word_break_thunk
328 BYTE popl_eax
; /* popl %eax (return address) */
329 BYTE pushl_proc16
; /* pushl proc16 */
330 EDITWORDBREAKPROC16 proc16
;
331 BYTE pushl_eax
; /* pushl %eax */
332 BYTE jmp
; /* ljmp call_word_break_proc16 */
334 } *word_break_thunks
;
337 /**********************************************************************
338 * call_word_break_proc16
340 static INT16 CALLBACK
call_word_break_proc16( SEGPTR proc16
, LPSTR text
, INT index
, INT count
, INT action
)
346 segptr
= MapLS( text
);
347 args
[4] = SELECTOROF(segptr
);
348 args
[3] = OFFSETOF(segptr
);
352 WOWCallback16Ex( proc16
, WCB16_PASCAL
, sizeof(args
), args
, &result
);
354 return LOWORD(result
);
357 /******************************************************************
358 * add_word_break_thunk
360 static struct word_break_thunk
*add_word_break_thunk( EDITWORDBREAKPROC16 proc16
)
362 struct word_break_thunk
*thunk
;
364 if (!word_break_thunks
)
366 word_break_thunks
= VirtualAlloc( NULL
, MAX_THUNKS
* sizeof(*thunk
),
367 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
368 if (!word_break_thunks
) return NULL
;
370 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
372 thunk
->popl_eax
= 0x58; /* popl %eax */
373 thunk
->pushl_proc16
= 0x68; /* pushl proc16 */
374 thunk
->pushl_eax
= 0x50; /* pushl %eax */
375 thunk
->jmp
= 0xe9; /* jmp call_word_break_proc16 */
376 thunk
->callback
= (char *)call_word_break_proc16
- (char *)(&thunk
->callback
+ 1);
379 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
380 if (thunk
->proc16
== proc16
) return thunk
;
382 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
384 if (thunk
->proc16
) continue;
385 thunk
->proc16
= proc16
;
388 FIXME("Out of word break thunks\n");
392 /******************************************************************
393 * get_word_break_thunk
395 static EDITWORDBREAKPROC16
get_word_break_thunk( EDITWORDBREAKPROCA proc
)
397 struct word_break_thunk
*thunk
= (struct word_break_thunk
*)proc
;
398 if (word_break_thunks
&& thunk
>= word_break_thunks
&& thunk
< &word_break_thunks
[MAX_THUNKS
])
399 return thunk
->proc16
;
404 /***********************************************************************
405 * Support for 16<->32 message mapping
408 static inline void *get_buffer( void *static_buffer
, size_t size
, size_t need
)
410 if (size
>= need
) return static_buffer
;
411 return HeapAlloc( GetProcessHeap(), 0, need
);
414 static inline void free_buffer( void *static_buffer
, void *buffer
)
416 if (buffer
!= static_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
419 static void RECT16to32( const RECT16
*from
, RECT
*to
)
421 to
->left
= from
->left
;
423 to
->right
= from
->right
;
424 to
->bottom
= from
->bottom
;
427 static void RECT32to16( const RECT
*from
, RECT16
*to
)
429 to
->left
= from
->left
;
431 to
->right
= from
->right
;
432 to
->bottom
= from
->bottom
;
435 static void MINMAXINFO32to16( const MINMAXINFO
*from
, MINMAXINFO16
*to
)
437 to
->ptReserved
.x
= from
->ptReserved
.x
;
438 to
->ptReserved
.y
= from
->ptReserved
.y
;
439 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
440 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
441 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
442 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
443 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
444 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
445 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
446 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
449 static void MINMAXINFO16to32( const MINMAXINFO16
*from
, MINMAXINFO
*to
)
451 to
->ptReserved
.x
= from
->ptReserved
.x
;
452 to
->ptReserved
.y
= from
->ptReserved
.y
;
453 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
454 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
455 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
456 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
457 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
458 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
459 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
460 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
463 static void WINDOWPOS32to16( const WINDOWPOS
* from
, WINDOWPOS16
* to
)
465 to
->hwnd
= HWND_16(from
->hwnd
);
466 to
->hwndInsertAfter
= HWND_16(from
->hwndInsertAfter
);
471 to
->flags
= from
->flags
;
474 static void WINDOWPOS16to32( const WINDOWPOS16
* from
, WINDOWPOS
* to
)
476 to
->hwnd
= WIN_Handle32(from
->hwnd
);
477 to
->hwndInsertAfter
= (from
->hwndInsertAfter
== (HWND16
)-1) ?
478 HWND_TOPMOST
: WIN_Handle32(from
->hwndInsertAfter
);
483 to
->flags
= from
->flags
;
486 /* The strings are not copied */
487 static void CREATESTRUCT32Ato16( const CREATESTRUCTA
* from
, CREATESTRUCT16
* to
)
489 to
->lpCreateParams
= (SEGPTR
)from
->lpCreateParams
;
490 to
->hInstance
= HINSTANCE_16(from
->hInstance
);
491 to
->hMenu
= HMENU_16(from
->hMenu
);
492 to
->hwndParent
= HWND_16(from
->hwndParent
);
497 to
->style
= from
->style
;
498 to
->dwExStyle
= from
->dwExStyle
;
501 static void CREATESTRUCT16to32A( const CREATESTRUCT16
* from
, CREATESTRUCTA
*to
)
504 to
->lpCreateParams
= (LPVOID
)from
->lpCreateParams
;
505 to
->hInstance
= HINSTANCE_32(from
->hInstance
);
506 to
->hMenu
= HMENU_32(from
->hMenu
);
507 to
->hwndParent
= WIN_Handle32(from
->hwndParent
);
512 to
->style
= from
->style
;
513 to
->dwExStyle
= from
->dwExStyle
;
514 to
->lpszName
= MapSL(from
->lpszName
);
515 to
->lpszClass
= MapSL(from
->lpszClass
);
518 /* The strings are not copied */
519 static void MDICREATESTRUCT32Ato16( const MDICREATESTRUCTA
* from
, MDICREATESTRUCT16
* to
)
521 to
->hOwner
= HINSTANCE_16(from
->hOwner
);
526 to
->style
= from
->style
;
527 to
->lParam
= from
->lParam
;
530 static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16
* from
, MDICREATESTRUCTA
*to
)
532 to
->hOwner
= HINSTANCE_32(from
->hOwner
);
537 to
->style
= from
->style
;
538 to
->lParam
= from
->lParam
;
539 to
->szTitle
= MapSL(from
->szTitle
);
540 to
->szClass
= MapSL(from
->szClass
);
543 static UINT_PTR
convert_handle_16_to_32(HANDLE16 src
, unsigned int flags
)
546 UINT sz
= GlobalSize16(src
);
549 if (!(dst
= GlobalAlloc(flags
, sz
)))
551 ptr16
= GlobalLock16(src
);
552 ptr32
= GlobalLock(dst
);
553 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr32
, ptr16
, sz
);
557 return (UINT_PTR
)dst
;
560 static HANDLE16
convert_handle_32_to_16(UINT_PTR src
, unsigned int flags
)
563 UINT sz
= GlobalSize((HANDLE
)src
);
566 if (!(dst
= GlobalAlloc16(flags
, sz
)))
568 ptr32
= GlobalLock((HANDLE
)src
);
569 ptr16
= GlobalLock16(dst
);
570 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr16
, ptr32
, sz
);
571 GlobalUnlock((HANDLE
)src
);
577 static BOOL
is_old_app( HWND hwnd
)
579 HINSTANCE inst
= (HINSTANCE
)GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
580 return inst
&& !((ULONG_PTR
)inst
>> 16) && (GetExpWinVer16(LOWORD(inst
)) & 0xFF00) == 0x0300;
583 static int find_sub_menu( HMENU
*hmenu
, HMENU16 target
)
585 int i
, pos
, count
= GetMenuItemCount( *hmenu
);
587 for (i
= 0; i
< count
; i
++)
589 HMENU sub
= GetSubMenu( *hmenu
, i
);
591 if (HMENU_16(sub
) == target
) return i
;
592 if ((pos
= find_sub_menu( &sub
, target
)) != -1)
601 /**********************************************************************
602 * WINPROC_CallProc16To32A
604 LRESULT
WINPROC_CallProc16To32A( winproc_callback_t callback
, HWND16 hwnd
, UINT16 msg
,
605 WPARAM16 wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
608 HWND hwnd32
= WIN_Handle32( hwnd
);
615 CREATESTRUCT16
*cs16
= MapSL(lParam
);
617 MDICREATESTRUCTA mdi_cs
;
619 CREATESTRUCT16to32A( cs16
, &cs
);
620 if (GetWindowLongW(hwnd32
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
622 MDICREATESTRUCT16
*mdi_cs16
= MapSL(cs16
->lpCreateParams
);
623 MDICREATESTRUCT16to32A(mdi_cs16
, &mdi_cs
);
624 cs
.lpCreateParams
= &mdi_cs
;
626 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cs
, result
, arg
);
627 CREATESTRUCT32Ato16( &cs
, cs16
);
632 MDICREATESTRUCT16
*cs16
= MapSL(lParam
);
635 MDICREATESTRUCT16to32A( cs16
, &cs
);
636 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cs
, result
, arg
);
637 MDICREATESTRUCT32Ato16( &cs
, cs16
);
642 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32( HIWORD(lParam
) ),
643 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
644 else /* message sent to MDI client */
645 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
647 case WM_MDIGETACTIVE
:
649 BOOL maximized
= FALSE
;
650 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&maximized
, result
, arg
);
651 *result
= MAKELRESULT( LOWORD(*result
), maximized
);
655 ret
= callback( hwnd32
, wParam
? WM_MDIREFRESHMENU
: WM_MDISETMENU
,
656 (WPARAM
)HMENU_32(LOWORD(lParam
)), (LPARAM
)HMENU_32(HIWORD(lParam
)),
659 case WM_GETMINMAXINFO
:
661 MINMAXINFO16
*mmi16
= MapSL(lParam
);
664 MINMAXINFO16to32( mmi16
, &mmi
);
665 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&mmi
, result
, arg
);
666 MINMAXINFO32to16( &mmi
, mmi16
);
669 case WM_WINDOWPOSCHANGING
:
670 case WM_WINDOWPOSCHANGED
:
672 WINDOWPOS16
*winpos16
= MapSL(lParam
);
675 WINDOWPOS16to32( winpos16
, &winpos
);
676 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&winpos
, result
, arg
);
677 WINDOWPOS32to16( &winpos
, winpos16
);
682 NCCALCSIZE_PARAMS16
*nc16
= MapSL(lParam
);
683 NCCALCSIZE_PARAMS nc
;
686 RECT16to32( &nc16
->rgrc
[0], &nc
.rgrc
[0] );
689 RECT16to32( &nc16
->rgrc
[1], &nc
.rgrc
[1] );
690 RECT16to32( &nc16
->rgrc
[2], &nc
.rgrc
[2] );
691 WINDOWPOS16to32( MapSL(nc16
->lppos
), &winpos
);
694 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&nc
, result
, arg
);
695 RECT32to16( &nc
.rgrc
[0], &nc16
->rgrc
[0] );
698 RECT32to16( &nc
.rgrc
[1], &nc16
->rgrc
[1] );
699 RECT32to16( &nc
.rgrc
[2], &nc16
->rgrc
[2] );
700 WINDOWPOS32to16( &winpos
, MapSL(nc16
->lppos
) );
706 COMPAREITEMSTRUCT16
* cis16
= MapSL(lParam
);
707 COMPAREITEMSTRUCT cis
;
708 cis
.CtlType
= cis16
->CtlType
;
709 cis
.CtlID
= cis16
->CtlID
;
710 cis
.hwndItem
= WIN_Handle32( cis16
->hwndItem
);
711 cis
.itemID1
= cis16
->itemID1
;
712 cis
.itemData1
= cis16
->itemData1
;
713 cis
.itemID2
= cis16
->itemID2
;
714 cis
.itemData2
= cis16
->itemData2
;
715 cis
.dwLocaleId
= 0; /* FIXME */
716 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cis
, result
, arg
);
721 DELETEITEMSTRUCT16
* dis16
= MapSL(lParam
);
722 DELETEITEMSTRUCT dis
;
723 dis
.CtlType
= dis16
->CtlType
;
724 dis
.CtlID
= dis16
->CtlID
;
725 dis
.hwndItem
= WIN_Handle32( dis16
->hwndItem
);
726 dis
.itemData
= dis16
->itemData
;
727 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&dis
, result
, arg
);
732 MEASUREITEMSTRUCT16
* mis16
= MapSL(lParam
);
733 MEASUREITEMSTRUCT mis
;
734 mis
.CtlType
= mis16
->CtlType
;
735 mis
.CtlID
= mis16
->CtlID
;
736 mis
.itemID
= mis16
->itemID
;
737 mis
.itemWidth
= mis16
->itemWidth
;
738 mis
.itemHeight
= mis16
->itemHeight
;
739 mis
.itemData
= mis16
->itemData
;
740 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&mis
, result
, arg
);
741 mis16
->itemWidth
= (UINT16
)mis
.itemWidth
;
742 mis16
->itemHeight
= (UINT16
)mis
.itemHeight
;
747 DRAWITEMSTRUCT16
* dis16
= MapSL(lParam
);
749 dis
.CtlType
= dis16
->CtlType
;
750 dis
.CtlID
= dis16
->CtlID
;
751 dis
.itemID
= dis16
->itemID
;
752 dis
.itemAction
= dis16
->itemAction
;
753 dis
.itemState
= dis16
->itemState
;
754 dis
.hwndItem
= (dis
.CtlType
== ODT_MENU
) ? (HWND
)HMENU_32(dis16
->hwndItem
)
755 : WIN_Handle32( dis16
->hwndItem
);
756 dis
.hDC
= HDC_32(dis16
->hDC
);
757 dis
.itemData
= dis16
->itemData
;
758 dis
.rcItem
.left
= dis16
->rcItem
.left
;
759 dis
.rcItem
.top
= dis16
->rcItem
.top
;
760 dis
.rcItem
.right
= dis16
->rcItem
.right
;
761 dis
.rcItem
.bottom
= dis16
->rcItem
.bottom
;
762 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&dis
, result
, arg
);
767 COPYDATASTRUCT16
*cds16
= MapSL(lParam
);
769 cds
.dwData
= cds16
->dwData
;
770 cds
.cbData
= cds16
->cbData
;
771 cds
.lpData
= MapSL(cds16
->lpData
);
772 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cds
, result
, arg
);
778 MSG16
*msg16
= MapSL(lParam
);
780 msg32
.hwnd
= WIN_Handle32( msg16
->hwnd
);
781 msg32
.message
= msg16
->message
;
782 msg32
.wParam
= msg16
->wParam
;
783 msg32
.lParam
= msg16
->lParam
;
784 msg32
.time
= msg16
->time
;
785 msg32
.pt
.x
= msg16
->pt
.x
;
786 msg32
.pt
.y
= msg16
->pt
.y
;
787 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&msg32
, result
, arg
);
790 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
795 next
.hmenuIn
= (HMENU
)lParam
;
798 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&next
, result
, arg
);
799 *result
= MAKELONG( HMENU_16(next
.hmenuNext
), HWND_16(next
.hwndNext
) );
806 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, HIWORD(lParam
) ),
807 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
811 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
812 (LPARAM
)WIN_Handle32( HIWORD(lParam
) ), result
, arg
);
815 if (HIWORD(lParam
) <= CTLCOLOR_STATIC
)
816 ret
= callback( hwnd32
, WM_CTLCOLORMSGBOX
+ HIWORD(lParam
),
817 (WPARAM
)HDC_32(wParam
), (LPARAM
)WIN_Handle32( LOWORD(lParam
) ),
822 case WM_WININICHANGE
:
823 case WM_DEVMODECHANGE
:
824 case WM_ASKCBFORMATNAME
:
826 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)MapSL(lParam
), result
, arg
);
829 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
830 (LPARAM
)HMENU_32(HIWORD(lParam
)), result
, arg
);
833 if((LOWORD(lParam
) & MF_POPUP
) && (LOWORD(lParam
) != 0xFFFF))
835 HMENU hmenu
= HMENU_32(HIWORD(lParam
));
836 int pos
= find_sub_menu( &hmenu
, wParam
);
837 if (pos
== -1) pos
= 0;
840 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
841 (LPARAM
)HMENU_32(HIWORD(lParam
)), result
, arg
);
843 case WM_PARENTNOTIFY
:
844 if ((wParam
== WM_CREATE
) || (wParam
== WM_DESTROY
))
845 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, HIWORD(lParam
) ),
846 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
848 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
851 /* We need this when SetActiveWindow sends a Sendmessage16() to
852 * a 32-bit window. Might be superfluous with 32-bit interprocess
854 if (lParam
) lParam
= HTASK_32(lParam
);
855 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
857 case WM_DDE_INITIATE
:
858 case WM_DDE_TERMINATE
:
859 case WM_DDE_UNADVISE
:
861 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
867 HANDLE16 lo16
= LOWORD(lParam
);
869 if (lo16
&& !(lo32
= convert_handle_16_to_32(lo16
, GMEM_DDESHARE
))) break;
870 lParam
= PackDDElParam( msg
, lo32
, HIWORD(lParam
) );
871 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
873 break; /* FIXME don't know how to free allocated memory (handle) !! */
876 UINT_PTR lo
= LOWORD(lParam
);
877 UINT_PTR hi
= HIWORD(lParam
);
881 if (GlobalGetAtomNameA(hi
, buf
, 2) > 0) flag
|= 1;
882 if (GlobalSize16(hi
) != 0) flag
|= 2;
888 WARN("DDE_ACK: neither atom nor handle!!!\n");
893 break; /* atom, nothing to do */
895 WARN("DDE_ACK: %lx both atom and handle... choosing handle\n", hi
);
898 hi
= convert_handle_16_to_32(hi
, GMEM_DDESHARE
);
901 lParam
= PackDDElParam( WM_DDE_ACK
, lo
, hi
);
902 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
904 break; /* FIXME don't know how to free allocated memory (handle) !! */
906 lParam
= convert_handle_16_to_32( HIWORD(lParam
), GMEM_DDESHARE
);
907 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
908 break; /* FIXME don't know how to free allocated memory (handle) !! */
909 case WM_PAINTCLIPBOARD
:
910 case WM_SIZECLIPBOARD
:
911 FIXME_(msg
)( "message %04x needs translation\n", msg
);
914 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
921 /**********************************************************************
922 * WINPROC_CallProc32ATo16
924 * Call a 16-bit window procedure, translating the 32-bit args.
926 LRESULT
WINPROC_CallProc32ATo16( winproc_callback16_t callback
, HWND hwnd
, UINT msg
,
927 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
936 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)lParam
;
938 MDICREATESTRUCT16 mdi_cs16
;
939 BOOL mdi_child
= (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
);
941 CREATESTRUCT32Ato16( cs32
, &cs
);
942 cs
.lpszName
= MapLS( cs32
->lpszName
);
943 cs
.lpszClass
= MapLS( cs32
->lpszClass
);
947 MDICREATESTRUCTA
*mdi_cs
= cs32
->lpCreateParams
;
948 MDICREATESTRUCT32Ato16( mdi_cs
, &mdi_cs16
);
949 mdi_cs16
.szTitle
= MapLS( mdi_cs
->szTitle
);
950 mdi_cs16
.szClass
= MapLS( mdi_cs
->szClass
);
951 cs
.lpCreateParams
= MapLS( &mdi_cs16
);
953 lParam
= MapLS( &cs
);
954 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
956 UnMapLS( cs
.lpszName
);
957 UnMapLS( cs
.lpszClass
);
960 UnMapLS( cs
.lpCreateParams
);
961 UnMapLS( mdi_cs16
.szTitle
);
962 UnMapLS( mdi_cs16
.szClass
);
968 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)lParam
;
969 MDICREATESTRUCT16 cs
;
971 MDICREATESTRUCT32Ato16( cs32
, &cs
);
972 cs
.szTitle
= MapLS( cs32
->szTitle
);
973 cs
.szClass
= MapLS( cs32
->szClass
);
974 lParam
= MapLS( &cs
);
975 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
977 UnMapLS( cs
.szTitle
);
978 UnMapLS( cs
.szClass
);
982 if (GetWindowLongW( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
983 ret
= callback( HWND_16(hwnd
), msg
, ((HWND
)lParam
== hwnd
),
984 MAKELPARAM( LOWORD(lParam
), LOWORD(wParam
) ), result
, arg
);
986 ret
= callback( HWND_16(hwnd
), msg
, HWND_16( wParam
), 0, result
, arg
);
988 case WM_MDIGETACTIVE
:
989 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
990 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(*result
);
991 *result
= (LRESULT
)WIN_Handle32( LOWORD(*result
) );
994 ret
= callback( HWND_16(hwnd
), msg
, (lParam
== 0),
995 MAKELPARAM( LOWORD(wParam
), LOWORD(lParam
) ), result
, arg
);
997 case WM_GETMINMAXINFO
:
999 MINMAXINFO
*mmi32
= (MINMAXINFO
*)lParam
;
1002 MINMAXINFO32to16( mmi32
, &mmi
);
1003 lParam
= MapLS( &mmi
);
1004 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1006 MINMAXINFO16to32( &mmi
, mmi32
);
1011 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)lParam
;
1012 NCCALCSIZE_PARAMS16 nc
;
1015 RECT32to16( &nc32
->rgrc
[0], &nc
.rgrc
[0] );
1018 RECT32to16( &nc32
->rgrc
[1], &nc
.rgrc
[1] );
1019 RECT32to16( &nc32
->rgrc
[2], &nc
.rgrc
[2] );
1020 WINDOWPOS32to16( nc32
->lppos
, &winpos
);
1021 nc
.lppos
= MapLS( &winpos
);
1023 lParam
= MapLS( &nc
);
1024 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1026 RECT16to32( &nc
.rgrc
[0], &nc32
->rgrc
[0] );
1029 RECT16to32( &nc
.rgrc
[1], &nc32
->rgrc
[1] );
1030 RECT16to32( &nc
.rgrc
[2], &nc32
->rgrc
[2] );
1031 WINDOWPOS16to32( &winpos
, nc32
->lppos
);
1032 UnMapLS( nc
.lppos
);
1036 case WM_WINDOWPOSCHANGING
:
1037 case WM_WINDOWPOSCHANGED
:
1039 WINDOWPOS
*winpos32
= (WINDOWPOS
*)lParam
;
1042 WINDOWPOS32to16( winpos32
, &winpos
);
1043 lParam
= MapLS( &winpos
);
1044 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1046 WINDOWPOS16to32( &winpos
, winpos32
);
1049 case WM_COMPAREITEM
:
1051 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)lParam
;
1052 COMPAREITEMSTRUCT16 cis
;
1053 cis
.CtlType
= cis32
->CtlType
;
1054 cis
.CtlID
= cis32
->CtlID
;
1055 cis
.hwndItem
= HWND_16( cis32
->hwndItem
);
1056 cis
.itemID1
= cis32
->itemID1
;
1057 cis
.itemData1
= cis32
->itemData1
;
1058 cis
.itemID2
= cis32
->itemID2
;
1059 cis
.itemData2
= cis32
->itemData2
;
1060 lParam
= MapLS( &cis
);
1061 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1067 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)lParam
;
1068 DELETEITEMSTRUCT16 dis
;
1069 dis
.CtlType
= dis32
->CtlType
;
1070 dis
.CtlID
= dis32
->CtlID
;
1071 dis
.itemID
= dis32
->itemID
;
1072 dis
.hwndItem
= (dis
.CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
1073 : HWND_16( dis32
->hwndItem
);
1074 dis
.itemData
= dis32
->itemData
;
1075 lParam
= MapLS( &dis
);
1076 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1082 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)lParam
;
1083 DRAWITEMSTRUCT16 dis
;
1084 dis
.CtlType
= dis32
->CtlType
;
1085 dis
.CtlID
= dis32
->CtlID
;
1086 dis
.itemID
= dis32
->itemID
;
1087 dis
.itemAction
= dis32
->itemAction
;
1088 dis
.itemState
= dis32
->itemState
;
1089 dis
.hwndItem
= HWND_16( dis32
->hwndItem
);
1090 dis
.hDC
= HDC_16(dis32
->hDC
);
1091 dis
.itemData
= dis32
->itemData
;
1092 dis
.rcItem
.left
= dis32
->rcItem
.left
;
1093 dis
.rcItem
.top
= dis32
->rcItem
.top
;
1094 dis
.rcItem
.right
= dis32
->rcItem
.right
;
1095 dis
.rcItem
.bottom
= dis32
->rcItem
.bottom
;
1096 lParam
= MapLS( &dis
);
1097 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1101 case WM_MEASUREITEM
:
1103 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)lParam
;
1104 MEASUREITEMSTRUCT16 mis
;
1105 mis
.CtlType
= mis32
->CtlType
;
1106 mis
.CtlID
= mis32
->CtlID
;
1107 mis
.itemID
= mis32
->itemID
;
1108 mis
.itemWidth
= mis32
->itemWidth
;
1109 mis
.itemHeight
= mis32
->itemHeight
;
1110 mis
.itemData
= mis32
->itemData
;
1111 lParam
= MapLS( &mis
);
1112 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1114 mis32
->itemWidth
= mis
.itemWidth
;
1115 mis32
->itemHeight
= mis
.itemHeight
;
1120 COPYDATASTRUCT
*cds32
= (COPYDATASTRUCT
*)lParam
;
1121 COPYDATASTRUCT16 cds
;
1123 cds
.dwData
= cds32
->dwData
;
1124 cds
.cbData
= cds32
->cbData
;
1125 cds
.lpData
= MapLS( cds32
->lpData
);
1126 lParam
= MapLS( &cds
);
1127 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1129 UnMapLS( cds
.lpData
);
1135 MSG
*msg32
= (MSG
*)lParam
;
1138 msg16
.hwnd
= HWND_16( msg32
->hwnd
);
1139 msg16
.message
= msg32
->message
;
1140 msg16
.wParam
= msg32
->wParam
;
1141 msg16
.lParam
= msg32
->lParam
;
1142 msg16
.time
= msg32
->time
;
1143 msg16
.pt
.x
= msg32
->pt
.x
;
1144 msg16
.pt
.y
= msg32
->pt
.y
;
1145 lParam
= MapLS( &msg16
);
1146 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1150 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1154 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1155 ret
= callback( HWND_16(hwnd
), msg
, wParam
, (LPARAM
)next
->hmenuIn
, result
, arg
);
1156 next
->hmenuNext
= HMENU_32( LOWORD(*result
) );
1157 next
->hwndNext
= WIN_Handle32( HIWORD(*result
) );
1162 case WM_ASKCBFORMATNAME
:
1163 wParam
= min( wParam
, 0xff80 ); /* Must be < 64K */
1167 case WM_WININICHANGE
:
1168 case WM_DEVMODECHANGE
:
1169 lParam
= MapLS( (void *)lParam
);
1170 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1177 ret
= callback( HWND_16(hwnd
), msg
, wParam
, MAKELPARAM( (HWND16
)lParam
, HIWORD(wParam
) ),
1182 ret
= callback( HWND_16(hwnd
), msg
, wParam
, MAKELPARAM( HIWORD(wParam
), (HWND16
)lParam
),
1185 case WM_CTLCOLORMSGBOX
:
1186 case WM_CTLCOLOREDIT
:
1187 case WM_CTLCOLORLISTBOX
:
1188 case WM_CTLCOLORBTN
:
1189 case WM_CTLCOLORDLG
:
1190 case WM_CTLCOLORSCROLLBAR
:
1191 case WM_CTLCOLORSTATIC
:
1192 ret
= callback( HWND_16(hwnd
), WM_CTLCOLOR
, wParam
,
1193 MAKELPARAM( (HWND16
)lParam
, msg
- WM_CTLCOLORMSGBOX
), result
, arg
);
1196 if(HIWORD(wParam
) & MF_POPUP
)
1199 if ((HIWORD(wParam
) != 0xffff) || lParam
)
1201 if ((hmenu
= GetSubMenu( (HMENU
)lParam
, LOWORD(wParam
) )))
1203 ret
= callback( HWND_16(hwnd
), msg
, HMENU_16(hmenu
),
1204 MAKELPARAM( HIWORD(wParam
), (HMENU16
)lParam
), result
, arg
);
1211 ret
= callback( HWND_16(hwnd
), msg
, wParam
,
1212 MAKELPARAM( HIWORD(wParam
), (HMENU16
)lParam
), result
, arg
);
1214 case WM_PARENTNOTIFY
:
1215 if ((LOWORD(wParam
) == WM_CREATE
) || (LOWORD(wParam
) == WM_DESTROY
))
1216 ret
= callback( HWND_16(hwnd
), msg
, wParam
,
1217 MAKELPARAM( (HWND16
)lParam
, HIWORD(wParam
) ), result
, arg
);
1219 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1221 case WM_ACTIVATEAPP
:
1222 ret
= callback( HWND_16(hwnd
), msg
, wParam
, HTASK_16( lParam
), result
, arg
);
1225 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
))
1226 ret
= callback( HWND_16(hwnd
), WM_PAINTICON
, 1, lParam
, result
, arg
);
1228 ret
= callback( HWND_16(hwnd
), WM_PAINT
, wParam
, lParam
, result
, arg
);
1231 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
)) msg
= WM_ICONERASEBKGND
;
1232 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1234 case WM_DDE_INITIATE
:
1235 case WM_DDE_TERMINATE
:
1236 case WM_DDE_UNADVISE
:
1237 case WM_DDE_REQUEST
:
1238 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
), lParam
, result
, arg
);
1247 UnpackDDElParam( msg
, lParam
, &lo32
, &hi
);
1248 if (lo32
&& !(lo16
= convert_handle_32_to_16(lo32
, GMEM_DDESHARE
))) break;
1249 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
),
1250 MAKELPARAM(lo16
, hi
), result
, arg
);
1252 break; /* FIXME don't know how to free allocated memory (handle) !! */
1259 UnpackDDElParam( msg
, lParam
, &lo
, &hi
);
1261 if (GlobalGetAtomNameA((ATOM
)hi
, buf
, sizeof(buf
)) > 0) flag
|= 1;
1262 if (GlobalSize((HANDLE
)hi
) != 0) flag
|= 2;
1268 WARN("DDE_ACK: neither atom nor handle!!!\n");
1273 break; /* atom, nothing to do */
1275 WARN("DDE_ACK: %lx both atom and handle... choosing handle\n", hi
);
1278 hi
= convert_handle_32_to_16(hi
, GMEM_DDESHARE
);
1281 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
),
1282 MAKELPARAM(lo
, hi
), result
, arg
);
1284 break; /* FIXME don't know how to free allocated memory (handle) !! */
1285 case WM_DDE_EXECUTE
:
1286 lParam
= MAKELPARAM( 0, convert_handle_32_to_16( lParam
, GMEM_DDESHARE
));
1287 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1288 break; /* FIXME don't know how to free allocated memory (handle) !! */
1290 ret
= callback( HWND_16(hwnd
), SBM_SETRANGE16
, 0, MAKELPARAM(wParam
, lParam
), result
, arg
);
1293 ret
= callback( HWND_16(hwnd
), SBM_GETRANGE16
, wParam
, lParam
, result
, arg
);
1294 *(LPINT
)wParam
= LOWORD(*result
);
1295 *(LPINT
)lParam
= HIWORD(*result
);
1302 ret
= callback( HWND_16(hwnd
), msg
+ BM_GETCHECK16
- BM_GETCHECK
, wParam
, lParam
, result
, arg
);
1310 case EM_SCROLLCARET
:
1313 case EM_GETLINECOUNT
:
1325 case EM_LINEFROMCHAR
:
1326 case EM_SETTABSTOPS
:
1327 case EM_SETPASSWORDCHAR
:
1328 case EM_EMPTYUNDOBUFFER
:
1329 case EM_GETFIRSTVISIBLELINE
:
1330 case EM_SETREADONLY
:
1331 case EM_SETWORDBREAKPROC
:
1332 case EM_GETWORDBREAKPROC
:
1333 case EM_GETPASSWORDCHAR
:
1334 ret
= callback( HWND_16(hwnd
), msg
+ EM_GETSEL16
- EM_GETSEL
, wParam
, lParam
, result
, arg
);
1337 ret
= callback( HWND_16(hwnd
), EM_SETSEL16
, 0, MAKELPARAM( wParam
, lParam
), result
, arg
);
1341 case LB_DELETESTRING
:
1342 case LB_GETANCHORINDEX
:
1343 case LB_GETCARETINDEX
:
1346 case LB_GETHORIZONTALEXTENT
:
1347 case LB_GETITEMDATA
:
1348 case LB_GETITEMHEIGHT
:
1350 case LB_GETSELCOUNT
:
1352 case LB_GETTOPINDEX
:
1353 case LB_RESETCONTENT
:
1354 case LB_SELITEMRANGE
:
1355 case LB_SELITEMRANGEEX
:
1356 case LB_SETANCHORINDEX
:
1357 case LB_SETCARETINDEX
:
1358 case LB_SETCOLUMNWIDTH
:
1360 case LB_SETHORIZONTALEXTENT
:
1361 case LB_SETITEMDATA
:
1362 case LB_SETITEMHEIGHT
:
1364 case LB_SETTOPINDEX
:
1365 ret
= callback( HWND_16(hwnd
), msg
+ LB_ADDSTRING16
- LB_ADDSTRING
, wParam
, lParam
, result
, arg
);
1369 case LB_FINDSTRINGEXACT
:
1370 case LB_INSERTSTRING
:
1371 case LB_SELECTSTRING
:
1375 lParam
= MapLS( (LPSTR
)lParam
);
1376 ret
= callback( HWND_16(hwnd
), msg
+ LB_ADDSTRING16
- LB_ADDSTRING
, wParam
, lParam
, result
, arg
);
1379 case LB_GETSELITEMS
:
1381 INT
*items32
= (INT
*)lParam
;
1382 INT16
*items
, buffer
[512];
1385 wParam
= min( wParam
, 0x7f80 ); /* Must be < 64K */
1386 if (!(items
= get_buffer( buffer
, sizeof(buffer
), wParam
* sizeof(INT16
) ))) break;
1387 lParam
= MapLS( items
);
1388 ret
= callback( HWND_16(hwnd
), LB_GETSELITEMS16
, wParam
, lParam
, result
, arg
);
1390 for (i
= 0; i
< wParam
; i
++) items32
[i
] = items
[i
];
1391 free_buffer( buffer
, items
);
1394 case LB_SETTABSTOPS
:
1397 INT
*stops32
= (INT
*)lParam
;
1398 INT16
*stops
, buffer
[512];
1401 wParam
= min( wParam
, 0x7f80 ); /* Must be < 64K */
1402 if (!(stops
= get_buffer( buffer
, sizeof(buffer
), wParam
* sizeof(INT16
) ))) break;
1403 for (i
= 0; i
< wParam
; i
++) stops
[i
] = stops32
[i
];
1404 lParam
= MapLS( stops
);
1405 ret
= callback( HWND_16(hwnd
), LB_SETTABSTOPS16
, wParam
, lParam
, result
, arg
);
1407 free_buffer( buffer
, stops
);
1409 else ret
= callback( HWND_16(hwnd
), LB_SETTABSTOPS16
, wParam
, lParam
, result
, arg
);
1411 case CB_DELETESTRING
:
1413 case CB_GETLBTEXTLEN
:
1415 case CB_RESETCONTENT
:
1419 case CB_SHOWDROPDOWN
:
1420 case CB_SETITEMDATA
:
1421 case CB_SETITEMHEIGHT
:
1422 case CB_GETITEMHEIGHT
:
1423 case CB_SETEXTENDEDUI
:
1424 case CB_GETEXTENDEDUI
:
1425 case CB_GETDROPPEDSTATE
:
1426 ret
= callback( HWND_16(hwnd
), msg
+ CB_GETEDITSEL16
- CB_GETEDITSEL
, wParam
, lParam
, result
, arg
);
1429 ret
= callback( HWND_16(hwnd
), CB_GETEDITSEL16
, wParam
, lParam
, result
, arg
);
1430 if (wParam
) *((PUINT
)(wParam
)) = LOWORD(*result
);
1431 if (lParam
) *((PUINT
)(lParam
)) = HIWORD(*result
); /* FIXME: subtract 1? */
1435 case CB_FINDSTRINGEXACT
:
1436 case CB_INSERTSTRING
:
1437 case CB_SELECTSTRING
:
1440 lParam
= MapLS( (LPSTR
)lParam
);
1441 ret
= callback( HWND_16(hwnd
), msg
+ CB_GETEDITSEL16
- CB_GETEDITSEL
, wParam
, lParam
, result
, arg
);
1444 case LB_GETITEMRECT
:
1445 case CB_GETDROPPEDCONTROLRECT
:
1447 RECT
*r32
= (RECT
*)lParam
;
1449 lParam
= MapLS( &rect
);
1450 ret
= callback( HWND_16(hwnd
),
1451 (msg
== LB_GETITEMRECT
) ? LB_GETITEMRECT16
: CB_GETDROPPEDCONTROLRECT16
,
1452 wParam
, lParam
, result
, arg
);
1454 RECT16to32( &rect
, r32
);
1457 case WM_PAINTCLIPBOARD
:
1458 case WM_SIZECLIPBOARD
:
1459 FIXME_(msg
)( "message %04x needs translation\n", msg
);
1461 /* the following messages should not be sent to 16-bit apps */
1464 case WM_CAPTURECHANGED
:
1465 case WM_STYLECHANGING
:
1466 case WM_STYLECHANGED
:
1469 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1476 /***********************************************************************
1477 * SendMessage (USER.111)
1479 LRESULT WINAPI
SendMessage16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1482 HWND hwnd
= WIN_Handle32( hwnd16
);
1484 if (hwnd
!= HWND_BROADCAST
&&
1485 GetWindowThreadProcessId( hwnd
, NULL
) == GetCurrentThreadId())
1487 /* call 16-bit window proc directly */
1490 /* first the WH_CALLWNDPROC hook */
1491 call_WH_CALLWNDPROC_hook( hwnd16
, msg
, wparam
, lparam
);
1493 if (!(winproc
= (WNDPROC16
)GetWindowLong16( hwnd16
, GWLP_WNDPROC
))) return 0;
1495 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx\n", hwnd16
, msg
, wparam
, lparam
);
1496 result
= CallWindowProc16( winproc
, hwnd16
, msg
, wparam
, lparam
);
1497 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx returned %08lx\n",
1498 hwnd16
, msg
, wparam
, lparam
, result
);
1500 else /* map to 32-bit unicode for inter-thread/process message */
1502 WINPROC_CallProc16To32A( send_message_callback
, hwnd16
, msg
, wparam
, lparam
, &result
, NULL
);
1508 /***********************************************************************
1509 * PostMessage (USER.110)
1511 BOOL16 WINAPI
PostMessage16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1514 return WINPROC_CallProc16To32A( post_message_callback
, hwnd
, msg
, wparam
, lparam
, &unused
, NULL
);
1518 /***********************************************************************
1519 * PostAppMessage (USER.116)
1521 BOOL16 WINAPI
PostAppMessage16( HTASK16 hTask
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1524 DWORD_PTR tid
= HTASK_32( hTask
);
1526 if (!tid
) return FALSE
;
1527 return WINPROC_CallProc16To32A( post_thread_message_callback
, 0, msg
, wparam
, lparam
,
1528 &unused
, (void *)tid
);
1532 /**********************************************************************
1533 * CallWindowProc (USER.122)
1535 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
1536 WPARAM16 wParam
, LPARAM lParam
)
1538 int index
= winproc_to_index( func
);
1541 if (!func
) return 0;
1543 if (index
== -1 || index
>= MAX_WINPROCS32
)
1544 call_window_proc16( hwnd
, msg
, wParam
, lParam
, &result
, func
);
1547 WNDPROC proc
= (WNDPROC
)func
;
1548 if (thunk_array
&& thunk_array
[index
].proc
) proc
= thunk_array
[index
].proc
;
1549 WINPROC_CallProc16To32A( call_window_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, proc
);
1555 /**********************************************************************
1556 * __wine_call_wndproc (USER.1010)
1558 LRESULT WINAPI
__wine_call_wndproc( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
, WNDPROC proc
)
1561 WINPROC_CallProc16To32A( call_window_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, proc
);
1566 /***********************************************************************
1567 * InSendMessage (USER.192)
1569 BOOL16 WINAPI
InSendMessage16(void)
1571 return InSendMessage();
1575 /***********************************************************************
1576 * ReplyMessage (USER.115)
1578 void WINAPI
ReplyMessage16( LRESULT result
)
1580 ReplyMessage( result
);
1584 /***********************************************************************
1585 * PeekMessage32 (USER.819)
1587 BOOL16 WINAPI
PeekMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
,
1588 UINT16 first
, UINT16 last
, UINT16 flags
,
1589 BOOL16 wHaveParamHigh
)
1593 HWND hwnd
= WIN_Handle32( hwnd16
);
1595 if(USER16_AlertableWait
)
1596 MsgWaitForMultipleObjectsEx( 0, NULL
, 0, 0, MWMO_ALERTABLE
);
1597 if (!PeekMessageA( &msg
, hwnd
, first
, last
, flags
)) return FALSE
;
1599 msg16
->msg
.time
= msg
.time
;
1600 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
1601 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
1602 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
1603 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
1604 &unused
, &msg16
->msg
);
1609 /***********************************************************************
1610 * DefWindowProc (USER.107)
1612 LRESULT WINAPI
DefWindowProc16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
1615 HWND hwnd
= WIN_Handle32( hwnd16
);
1621 CREATESTRUCT16
*cs16
= MapSL(lParam
);
1624 cs32
.lpCreateParams
= ULongToPtr(cs16
->lpCreateParams
);
1625 cs32
.hInstance
= HINSTANCE_32(cs16
->hInstance
);
1626 cs32
.hMenu
= HMENU_32(cs16
->hMenu
);
1627 cs32
.hwndParent
= WIN_Handle32(cs16
->hwndParent
);
1632 cs32
.style
= cs16
->style
;
1633 cs32
.dwExStyle
= cs16
->dwExStyle
;
1634 cs32
.lpszName
= MapSL(cs16
->lpszName
);
1635 cs32
.lpszClass
= MapSL(cs16
->lpszClass
);
1636 return DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&cs32
);
1640 RECT16
*rect16
= MapSL(lParam
);
1643 rect32
.left
= rect16
->left
;
1644 rect32
.top
= rect16
->top
;
1645 rect32
.right
= rect16
->right
;
1646 rect32
.bottom
= rect16
->bottom
;
1648 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&rect32
);
1650 rect16
->left
= rect32
.left
;
1651 rect16
->top
= rect32
.top
;
1652 rect16
->right
= rect32
.right
;
1653 rect16
->bottom
= rect32
.bottom
;
1656 case WM_WINDOWPOSCHANGING
:
1657 case WM_WINDOWPOSCHANGED
:
1659 WINDOWPOS16
*pos16
= MapSL(lParam
);
1662 pos32
.hwnd
= WIN_Handle32(pos16
->hwnd
);
1663 pos32
.hwndInsertAfter
= WIN_Handle32(pos16
->hwndInsertAfter
);
1666 pos32
.cx
= pos16
->cx
;
1667 pos32
.cy
= pos16
->cy
;
1668 pos32
.flags
= pos16
->flags
;
1670 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&pos32
);
1672 pos16
->hwnd
= HWND_16(pos32
.hwnd
);
1673 pos16
->hwndInsertAfter
= HWND_16(pos32
.hwndInsertAfter
);
1676 pos16
->cx
= pos32
.cx
;
1677 pos16
->cy
= pos32
.cy
;
1678 pos16
->flags
= pos32
.flags
;
1683 return DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)MapSL(lParam
) );
1685 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
1690 /***********************************************************************
1691 * DefDlgProc (USER.308)
1693 LRESULT WINAPI
DefDlgProc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
1696 WINPROC_CallProc16To32A( defdlg_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, 0 );
1701 /***********************************************************************
1702 * PeekMessage (USER.109)
1704 BOOL16 WINAPI
PeekMessage16( MSG16
*msg
, HWND16 hwnd
,
1705 UINT16 first
, UINT16 last
, UINT16 flags
)
1707 return PeekMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, flags
, FALSE
);
1711 /***********************************************************************
1712 * GetMessage32 (USER.820)
1714 BOOL16 WINAPI
GetMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
, UINT16 first
,
1715 UINT16 last
, BOOL16 wHaveParamHigh
)
1719 HWND hwnd
= WIN_Handle32( hwnd16
);
1721 if(USER16_AlertableWait
)
1722 MsgWaitForMultipleObjectsEx( 0, NULL
, INFINITE
, 0, MWMO_ALERTABLE
);
1723 GetMessageA( &msg
, hwnd
, first
, last
);
1724 msg16
->msg
.time
= msg
.time
;
1725 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
1726 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
1727 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
1728 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
1729 &unused
, &msg16
->msg
);
1731 TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
1732 msg16
->msg
.message
, hwnd
, first
, last
);
1734 return msg16
->msg
.message
!= WM_QUIT
;
1738 /***********************************************************************
1739 * GetMessage (USER.108)
1741 BOOL16 WINAPI
GetMessage16( MSG16
*msg
, HWND16 hwnd
, UINT16 first
, UINT16 last
)
1743 return GetMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, FALSE
);
1747 /***********************************************************************
1748 * TranslateMessage32 (USER.821)
1750 BOOL16 WINAPI
TranslateMessage32_16( const MSG32_16
*msg
, BOOL16 wHaveParamHigh
)
1754 msg32
.hwnd
= WIN_Handle32( msg
->msg
.hwnd
);
1755 msg32
.message
= msg
->msg
.message
;
1756 msg32
.wParam
= MAKEWPARAM( msg
->msg
.wParam
, wHaveParamHigh
? msg
->wParamHigh
: 0 );
1757 msg32
.lParam
= msg
->msg
.lParam
;
1758 return TranslateMessage( &msg32
);
1762 /***********************************************************************
1763 * TranslateMessage (USER.113)
1765 BOOL16 WINAPI
TranslateMessage16( const MSG16
*msg
)
1767 return TranslateMessage32_16( (const MSG32_16
*)msg
, FALSE
);
1771 /***********************************************************************
1772 * DispatchMessage (USER.114)
1774 LONG WINAPI
DispatchMessage16( const MSG16
* msg
)
1779 /* Process timer messages */
1780 if ((msg
->message
== WM_TIMER
) || (msg
->message
== WM_SYSTIMER
))
1783 return CallWindowProc16( (WNDPROC16
)msg
->lParam
, msg
->hwnd
,
1784 msg
->message
, msg
->wParam
, GetTickCount() );
1787 if (!(winproc
= (WNDPROC16
)GetWindowLong16( msg
->hwnd
, GWLP_WNDPROC
)))
1789 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
1792 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx\n", msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1793 retval
= CallWindowProc16( winproc
, msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1794 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx returned %08lx\n",
1795 msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
, retval
);
1800 /***********************************************************************
1801 * DispatchMessage32 (USER.822)
1803 LONG WINAPI
DispatchMessage32_16( const MSG32_16
*msg16
, BOOL16 wHaveParamHigh
)
1805 if (wHaveParamHigh
== FALSE
)
1806 return DispatchMessage16( &msg16
->msg
);
1811 msg
.hwnd
= WIN_Handle32( msg16
->msg
.hwnd
);
1812 msg
.message
= msg16
->msg
.message
;
1813 msg
.wParam
= MAKEWPARAM( msg16
->msg
.wParam
, msg16
->wParamHigh
);
1814 msg
.lParam
= msg16
->msg
.lParam
;
1815 msg
.time
= msg16
->msg
.time
;
1816 msg
.pt
.x
= msg16
->msg
.pt
.x
;
1817 msg
.pt
.y
= msg16
->msg
.pt
.y
;
1818 return DispatchMessageA( &msg
);
1823 /***********************************************************************
1824 * IsDialogMessage (USER.90)
1826 BOOL16 WINAPI
IsDialogMessage16( HWND16 hwndDlg
, MSG16
*msg16
)
1831 msg
.hwnd
= WIN_Handle32(msg16
->hwnd
);
1832 hwndDlg32
= WIN_Handle32(hwndDlg
);
1834 switch(msg16
->message
)
1839 msg
.message
= msg16
->message
;
1840 msg
.wParam
= msg16
->wParam
;
1841 msg
.lParam
= msg16
->lParam
;
1842 msg
.time
= msg16
->time
;
1843 msg
.pt
.x
= msg16
->pt
.x
;
1844 msg
.pt
.y
= msg16
->pt
.y
;
1845 return IsDialogMessageA( hwndDlg32
, &msg
);
1848 if ((hwndDlg32
!= msg
.hwnd
) && !IsChild( hwndDlg32
, msg
.hwnd
)) return FALSE
;
1849 TranslateMessage16( msg16
);
1850 DispatchMessage16( msg16
);
1855 /***********************************************************************
1856 * MsgWaitForMultipleObjects (USER.640)
1858 DWORD WINAPI
MsgWaitForMultipleObjects16( DWORD count
, const HANDLE
*handles
,
1859 BOOL wait_all
, DWORD timeout
, DWORD mask
)
1861 return MsgWaitForMultipleObjectsEx( count
, handles
, timeout
, mask
,
1862 wait_all
? MWMO_WAITALL
: 0 );
1866 /**********************************************************************
1867 * SetDoubleClickTime (USER.20)
1869 void WINAPI
SetDoubleClickTime16( UINT16 interval
)
1871 SetDoubleClickTime( interval
);
1875 /**********************************************************************
1876 * GetDoubleClickTime (USER.21)
1878 UINT16 WINAPI
GetDoubleClickTime16(void)
1880 return GetDoubleClickTime();
1884 /***********************************************************************
1885 * PostQuitMessage (USER.6)
1887 void WINAPI
PostQuitMessage16( INT16 exitCode
)
1889 PostQuitMessage( exitCode
);
1893 /**********************************************************************
1894 * GetKeyState (USER.106)
1896 INT16 WINAPI
GetKeyState16(INT16 vkey
)
1898 return GetKeyState(vkey
);
1902 /**********************************************************************
1903 * GetKeyboardState (USER.222)
1905 BOOL WINAPI
GetKeyboardState16( LPBYTE state
)
1907 return GetKeyboardState( state
);
1911 /**********************************************************************
1912 * SetKeyboardState (USER.223)
1914 BOOL WINAPI
SetKeyboardState16( LPBYTE state
)
1916 return SetKeyboardState( state
);
1920 /***********************************************************************
1921 * SetMessageQueue (USER.266)
1923 BOOL16 WINAPI
SetMessageQueue16( INT16 size
)
1925 return SetMessageQueue( size
);
1929 /***********************************************************************
1930 * UserYield (USER.332)
1932 void WINAPI
UserYield16(void)
1935 PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
| PM_QS_SENDMESSAGE
);
1939 /***********************************************************************
1940 * GetQueueStatus (USER.334)
1942 DWORD WINAPI
GetQueueStatus16( UINT16 flags
)
1944 return GetQueueStatus( flags
);
1948 /***********************************************************************
1949 * GetInputState (USER.335)
1951 BOOL16 WINAPI
GetInputState16(void)
1953 return GetInputState();
1957 /**********************************************************************
1958 * TranslateAccelerator (USER.178)
1960 INT16 WINAPI
TranslateAccelerator16( HWND16 hwnd
, HACCEL16 hAccel
, LPMSG16 msg
)
1965 msg32
.message
= msg
->message
;
1966 /* msg32.hwnd not used */
1967 msg32
.wParam
= msg
->wParam
;
1968 msg32
.lParam
= msg
->lParam
;
1969 return TranslateAcceleratorW( WIN_Handle32(hwnd
), HACCEL_32(hAccel
), &msg32
);
1973 /**********************************************************************
1974 * TranslateMDISysAccel (USER.451)
1976 BOOL16 WINAPI
TranslateMDISysAccel16( HWND16 hwndClient
, LPMSG16 msg
)
1978 if (msg
->message
== WM_KEYDOWN
|| msg
->message
== WM_SYSKEYDOWN
)
1981 msg32
.hwnd
= WIN_Handle32(msg
->hwnd
);
1982 msg32
.message
= msg
->message
;
1983 msg32
.wParam
= msg
->wParam
;
1984 msg32
.lParam
= msg
->lParam
;
1985 /* MDICLIENTINFO is still the same for win32 and win16 ... */
1986 return TranslateMDISysAccel( WIN_Handle32(hwndClient
), &msg32
);
1992 /***********************************************************************
1995 static LRESULT
button_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
1997 static const UINT msg16_offset
= BM_GETCHECK16
- BM_GETCHECK
;
2006 return wow_handlers32
.button_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2008 return wow_handlers32
.button_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2013 /***********************************************************************
2016 static LRESULT
combo_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2018 static const UINT msg16_offset
= CB_GETEDITSEL16
- CB_GETEDITSEL
;
2022 case CB_INSERTSTRING16
:
2023 case CB_SELECTSTRING16
:
2024 case CB_FINDSTRING16
:
2025 case CB_FINDSTRINGEXACT16
:
2026 wParam
= (INT
)(INT16
)wParam
;
2028 case CB_ADDSTRING16
:
2030 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2031 if ((style
& CBS_HASSTRINGS
) || !(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)))
2032 lParam
= (LPARAM
)MapSL(lParam
);
2033 msg
-= msg16_offset
;
2036 case CB_SETITEMHEIGHT16
:
2037 case CB_GETITEMHEIGHT16
:
2038 case CB_SETCURSEL16
:
2039 case CB_GETLBTEXTLEN16
:
2040 case CB_GETITEMDATA16
:
2041 case CB_SETITEMDATA16
:
2042 wParam
= (INT
)(INT16
)wParam
; /* signed integer */
2043 msg
-= msg16_offset
;
2045 case CB_GETDROPPEDCONTROLRECT16
:
2046 lParam
= (LPARAM
)MapSL(lParam
);
2050 RECT16
*r16
= (RECT16
*)lParam
;
2051 wow_handlers32
.combo_proc( hwnd
, CB_GETDROPPEDCONTROLRECT
, wParam
, (LPARAM
)&r
, FALSE
);
2054 r16
->right
= r
.right
;
2055 r16
->bottom
= r
.bottom
;
2059 if (wParam
& DDL_DRIVES
) wParam
|= DDL_EXCLUSIVE
;
2060 lParam
= (LPARAM
)MapSL(lParam
);
2061 msg
-= msg16_offset
;
2063 case CB_GETLBTEXT16
:
2064 wParam
= (INT
)(INT16
)wParam
;
2065 lParam
= (LPARAM
)MapSL(lParam
);
2066 msg
-= msg16_offset
;
2068 case CB_GETEDITSEL16
:
2069 wParam
= lParam
= 0; /* just in case */
2070 msg
-= msg16_offset
;
2072 case CB_LIMITTEXT16
:
2073 case CB_SETEDITSEL16
:
2074 case CB_DELETESTRING16
:
2075 case CB_RESETCONTENT16
:
2076 case CB_GETDROPPEDSTATE16
:
2077 case CB_SHOWDROPDOWN16
:
2079 case CB_GETCURSEL16
:
2080 case CB_SETEXTENDEDUI16
:
2081 case CB_GETEXTENDEDUI16
:
2082 msg
-= msg16_offset
;
2085 return wow_handlers32
.combo_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2087 return wow_handlers32
.combo_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2090 /*********************************************************************
2091 * edit_lock_buffer (internal)
2093 * A 16 bit application might send an EM_GETHANDLE message and expect a HLOCAL16
2094 * (16 bit SEG:OFF handler). From that moment on we have to keep using this
2095 * 16 bit memory handler, because it is supposed to be valid at all times after
2097 * We create a HLOCAL16 buffer in edit_get_handle and copy the text from the
2098 * HLOCAL buffer, when needed
2102 #define GWW_HANDLE16 sizeof(void*)
2104 static void edit_lock_buffer( HWND hwnd
)
2106 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2107 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2112 if (!hloc16
) return;
2113 if (!(hloc32
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return;
2115 oldDS
= stack16
->ds
;
2116 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2117 size
= LocalSize16(hloc16
);
2118 if (LocalReAlloc( hloc32
, size
, LMEM_MOVEABLE
))
2120 char *text
= MapSL( LocalLock16( hloc16
));
2121 char *dest
= LocalLock( hloc32
);
2122 memcpy( dest
, text
, size
);
2123 LocalUnlock( hloc32
);
2124 LocalUnlock16( hloc16
);
2126 stack16
->ds
= oldDS
;
2130 static void edit_unlock_buffer( HWND hwnd
)
2132 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2133 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2138 if (!hloc16
) return;
2139 if (!(hloc32
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return;
2140 size
= LocalSize( hloc32
);
2142 oldDS
= stack16
->ds
;
2143 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2144 if (LocalReAlloc16( hloc16
, size
, LMEM_MOVEABLE
))
2146 char *text
= LocalLock( hloc32
);
2147 char *dest
= MapSL( LocalLock16( hloc16
));
2148 memcpy( dest
, text
, size
);
2149 LocalUnlock( hloc32
);
2150 LocalUnlock16( hloc16
);
2152 stack16
->ds
= oldDS
;
2155 static HLOCAL16
edit_get_handle( HWND hwnd
)
2160 STACK16FRAME
* stack16
;
2162 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2164 if (hloc16
) return hloc16
;
2166 if (!(hloc
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return 0;
2167 alloc_size
= LocalSize( hloc
);
2169 stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2170 oldDS
= stack16
->ds
;
2171 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2173 if (!LocalHeapSize16())
2175 if (!LocalInit16(stack16
->ds
, 0, GlobalSize16(stack16
->ds
)))
2177 ERR("could not initialize local heap\n");
2182 if (!(hloc16
= LocalAlloc16(LMEM_MOVEABLE
| LMEM_ZEROINIT
, alloc_size
)))
2184 ERR("could not allocate new 16 bit buffer\n");
2188 if (!(textA
= MapSL(LocalLock16( hloc16
))))
2190 ERR("could not lock new 16 bit buffer\n");
2191 LocalFree16(hloc16
);
2195 memcpy( textA
, LocalLock( hloc
), alloc_size
);
2196 LocalUnlock( hloc
);
2197 LocalUnlock16( hloc16
);
2198 SetWindowWord( hwnd
, GWW_HANDLE16
, hloc16
);
2201 stack16
->ds
= oldDS
;
2205 static void edit_set_handle( HWND hwnd
, HLOCAL16 hloc16
)
2207 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2208 HINSTANCE16 hInstance
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2209 HANDLE16 oldDS
= stack16
->ds
;
2214 if (!(GetWindowLongW( hwnd
, GWL_STYLE
) & ES_MULTILINE
)) return;
2215 if (!hloc16
) return;
2217 stack16
->ds
= hInstance
;
2218 count
= LocalSize16(hloc16
);
2219 text
= MapSL(LocalLock16(hloc16
));
2220 if ((hloc32
= LocalAlloc(LMEM_MOVEABLE
, count
)))
2222 memcpy( LocalLock(hloc32
), text
, count
);
2223 LocalUnlock(hloc32
);
2224 LocalUnlock16(hloc16
);
2225 SetWindowWord( hwnd
, GWW_HANDLE16
, hloc16
);
2227 stack16
->ds
= oldDS
;
2229 if (hloc32
) wow_handlers32
.edit_proc( hwnd
, EM_SETHANDLE
, (WPARAM
)hloc32
, 0, FALSE
);
2232 static void edit_destroy_handle( HWND hwnd
)
2234 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2237 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2238 HANDLE16 oldDS
= stack16
->ds
;
2240 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2241 while (LocalUnlock16(hloc16
)) ;
2242 LocalFree16(hloc16
);
2243 stack16
->ds
= oldDS
;
2244 SetWindowWord( hwnd
, GWW_HANDLE16
, 0 );
2248 /*********************************************************************
2251 static LRESULT
edit_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2253 static const UINT msg16_offset
= EM_GETSEL16
- EM_GETSEL
;
2256 edit_lock_buffer( hwnd
);
2260 case EM_SCROLLCARET16
:
2261 case EM_GETMODIFY16
:
2262 case EM_SETMODIFY16
:
2263 case EM_GETLINECOUNT16
:
2265 case EM_LINELENGTH16
:
2266 case EM_LIMITTEXT16
:
2270 case EM_LINEFROMCHAR16
:
2271 case EM_SETPASSWORDCHAR16
:
2272 case EM_EMPTYUNDOBUFFER16
:
2273 case EM_SETREADONLY16
:
2274 case EM_GETPASSWORDCHAR16
:
2275 /* these messages missing from specs */
2280 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2283 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, 0, 0, FALSE
);
2285 case EM_REPLACESEL16
:
2287 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)MapSL(lParam
), FALSE
);
2289 case EM_LINESCROLL16
:
2290 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, (INT
)(SHORT
)HIWORD(lParam
),
2291 (INT
)(SHORT
)LOWORD(lParam
), FALSE
);
2293 case EM_LINEINDEX16
:
2294 if ((INT16
)wParam
== -1) wParam
= -1;
2295 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2298 if ((short)LOWORD(lParam
) == -1)
2305 wParam
= LOWORD(lParam
);
2306 lParam
= HIWORD(lParam
);
2308 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2314 RECT16
*r16
= MapSL(lParam
);
2315 wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)&rect
, FALSE
);
2316 r16
->left
= rect
.left
;
2317 r16
->top
= rect
.top
;
2318 r16
->right
= rect
.right
;
2319 r16
->bottom
= rect
.bottom
;
2323 case EM_SETRECTNP16
:
2327 RECT16
*r16
= MapSL(lParam
);
2328 rect
.left
= r16
->left
;
2329 rect
.top
= r16
->top
;
2330 rect
.right
= r16
->right
;
2331 rect
.bottom
= r16
->bottom
;
2332 wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)&rect
, FALSE
);
2335 case EM_SETHANDLE16
:
2336 edit_set_handle( hwnd
, (HLOCAL16
)wParam
);
2338 case EM_GETHANDLE16
:
2339 result
= edit_get_handle( hwnd
);
2341 case EM_SETTABSTOPS16
:
2343 INT16
*tabs16
= MapSL(lParam
);
2344 INT i
, count
= wParam
, *tabs
= NULL
;
2347 if (!(tabs
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*tabs
) ))) return 0;
2348 for (i
= 0; i
< count
; i
++) tabs
[i
] = tabs16
[i
];
2350 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, count
, (LPARAM
)tabs
, FALSE
);
2351 HeapFree( GetProcessHeap(), 0, tabs
);
2354 case EM_GETFIRSTVISIBLELINE16
:
2355 if (!(GetWindowLongW( hwnd
, GWL_STYLE
) & ES_MULTILINE
)) break;
2356 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2358 case EM_SETWORDBREAKPROC16
:
2360 struct word_break_thunk
*thunk
= add_word_break_thunk( (EDITWORDBREAKPROC16
)lParam
);
2361 result
= wow_handlers32
.edit_proc( hwnd
, EM_SETWORDBREAKPROC
, wParam
, (LPARAM
)thunk
, FALSE
);
2364 case EM_GETWORDBREAKPROC16
:
2365 result
= wow_handlers32
.edit_proc( hwnd
, EM_GETWORDBREAKPROC
, wParam
, lParam
, FALSE
);
2366 result
= (LRESULT
)get_word_break_thunk( (EDITWORDBREAKPROCA
)result
);
2369 edit_destroy_handle( hwnd
);
2370 return wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
); /* no unlock on destroy */
2373 if (LOWORD(wParam
) == EM_GETTHUMB16
|| LOWORD(wParam
) == EM_LINESCROLL16
) wParam
-= msg16_offset
;
2374 result
= wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2377 result
= wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2380 edit_unlock_buffer( hwnd
);
2385 /***********************************************************************
2388 static LRESULT
listbox_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2390 static const UINT msg16_offset
= LB_ADDSTRING16
- LB_ADDSTRING
;
2396 if (is_old_app( hwnd
))
2398 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2399 int height
, remaining
, item_height
;
2402 /* give a margin for error to old 16 bits programs - if we need
2403 less than the height of the nonclient area, round to the
2404 *next* number of items */
2406 if (!(style
& LBS_NOINTEGRALHEIGHT
) && !(style
& LBS_OWNERDRAWVARIABLE
))
2408 GetClientRect( hwnd
, &rect
);
2409 height
= rect
.bottom
- rect
.top
;
2410 item_height
= wow_handlers32
.listbox_proc( hwnd
, LB_GETITEMHEIGHT
, 0, 0, FALSE
);
2411 remaining
= item_height
? (height
% item_height
) : 0;
2412 if ((height
> item_height
) && remaining
)
2414 GetWindowRect( hwnd
, &rect
);
2415 if ((item_height
- remaining
) <= rect
.bottom
- rect
.top
- height
)
2416 remaining
= remaining
- item_height
;
2417 TRACE( "[%p]: changing height %d -> %d\n", hwnd
, height
, height
- remaining
);
2418 SetWindowPos( hwnd
, 0, 0, 0, rect
.right
- rect
.left
,
2419 rect
.bottom
- rect
.top
- remaining
,
2420 SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOMOVE
);
2425 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2427 case LB_RESETCONTENT16
:
2428 case LB_DELETESTRING16
:
2429 case LB_GETITEMDATA16
:
2430 case LB_SETITEMDATA16
:
2432 case LB_GETTEXTLEN16
:
2433 case LB_GETCURSEL16
:
2434 case LB_GETTOPINDEX16
:
2435 case LB_GETITEMHEIGHT16
:
2436 case LB_SETCARETINDEX16
:
2437 case LB_GETCARETINDEX16
:
2438 case LB_SETTOPINDEX16
:
2439 case LB_SETCOLUMNWIDTH16
:
2440 case LB_GETSELCOUNT16
:
2441 case LB_SELITEMRANGE16
:
2442 case LB_SELITEMRANGEEX16
:
2443 case LB_GETHORIZONTALEXTENT16
:
2444 case LB_SETHORIZONTALEXTENT16
:
2445 case LB_GETANCHORINDEX16
:
2448 msg
-= msg16_offset
;
2452 case LB_SETCURSEL16
:
2453 case LB_SETANCHORINDEX16
:
2454 wParam
= (INT
)(INT16
)wParam
;
2455 msg
-= msg16_offset
;
2457 case LB_INSERTSTRING16
:
2458 case LB_FINDSTRING16
:
2459 case LB_FINDSTRINGEXACT16
:
2460 case LB_SELECTSTRING16
:
2461 wParam
= (INT
)(INT16
)wParam
;
2463 case LB_ADDSTRING16
:
2466 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2467 if ((style
& LBS_HASSTRINGS
) || !(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)))
2468 lParam
= (LPARAM
)MapSL(lParam
);
2469 msg
-= msg16_offset
;
2473 lParam
= (LPARAM
)MapSL(lParam
);
2474 msg
-= msg16_offset
;
2476 case LB_SETITEMHEIGHT16
:
2477 lParam
= LOWORD(lParam
);
2478 msg
-= msg16_offset
;
2480 case LB_GETITEMRECT16
:
2483 RECT16
*r16
= MapSL(lParam
);
2484 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_GETITEMRECT
, (INT16
)wParam
, (LPARAM
)&rect
, FALSE
);
2485 r16
->left
= rect
.left
;
2486 r16
->top
= rect
.top
;
2487 r16
->right
= rect
.right
;
2488 r16
->bottom
= rect
.bottom
;
2491 case LB_GETSELITEMS16
:
2493 INT16
*array16
= MapSL( lParam
);
2494 INT i
, count
= (INT16
)wParam
, *array
;
2495 if (!(array
= HeapAlloc( GetProcessHeap(), 0, wParam
* sizeof(*array
) ))) return LB_ERRSPACE
;
2496 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_GETSELITEMS
, count
, (LPARAM
)array
, FALSE
);
2497 for (i
= 0; i
< ret
; i
++) array16
[i
] = array
[i
];
2498 HeapFree( GetProcessHeap(), 0, array
);
2502 /* according to Win16 docs, DDL_DRIVES should make DDL_EXCLUSIVE
2503 * be set automatically (this is different in Win32) */
2504 if (wParam
& DDL_DRIVES
) wParam
|= DDL_EXCLUSIVE
;
2505 lParam
= (LPARAM
)MapSL(lParam
);
2506 msg
-= msg16_offset
;
2508 case LB_SETTABSTOPS16
:
2510 INT i
, count
, *tabs
= NULL
;
2511 INT16
*tabs16
= MapSL( lParam
);
2513 if ((count
= (INT16
)wParam
) > 0)
2515 if (!(tabs
= HeapAlloc( GetProcessHeap(), 0, wParam
* sizeof(*tabs
) ))) return LB_ERRSPACE
;
2516 for (i
= 0; i
< count
; i
++) tabs
[i
] = tabs16
[i
] << 1; /* FIXME */
2518 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_SETTABSTOPS
, count
, (LPARAM
)tabs
, FALSE
);
2519 HeapFree( GetProcessHeap(), 0, tabs
);
2523 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2525 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2529 /***********************************************************************
2532 static LRESULT
mdiclient_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2534 if (msg
== WM_CREATE
)
2536 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
2537 HINSTANCE instance
= (HINSTANCE
)GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2538 BOOL is_win32
= !instance
|| ((ULONG_PTR
)instance
>> 16);
2540 /* Translation layer doesn't know what's in the cs->lpCreateParams
2541 * so we have to keep track of what environment we're in. */
2544 void *orig
= cs
->lpCreateParams
;
2546 CLIENTCREATESTRUCT ccs
;
2547 CLIENTCREATESTRUCT16
*ccs16
= MapSL( PtrToUlong( orig
));
2549 ccs
.hWindowMenu
= HMENU_32(ccs16
->hWindowMenu
);
2550 ccs
.idFirstChild
= ccs16
->idFirstChild
;
2551 cs
->lpCreateParams
= &ccs
;
2552 ret
= wow_handlers32
.mdiclient_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2553 cs
->lpCreateParams
= orig
;
2557 return wow_handlers32
.mdiclient_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2561 /***********************************************************************
2564 static LRESULT
scrollbar_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2566 static const UINT msg16_offset
= SBM_SETPOS16
- SBM_SETPOS
;
2572 case SBM_ENABLE_ARROWS16
:
2573 msg
-= msg16_offset
;
2575 case SBM_SETRANGE16
:
2576 msg
= wParam
? SBM_SETRANGEREDRAW
: SBM_SETRANGE
;
2577 wParam
= LOWORD(lParam
);
2578 lParam
= HIWORD(lParam
);
2580 case SBM_GETRANGE16
:
2583 wow_handlers32
.scrollbar_proc( hwnd
, SBM_GETRANGE
, (WPARAM
)&min
, (LPARAM
)&max
, FALSE
);
2584 return MAKELRESULT(min
, max
);
2587 return wow_handlers32
.scrollbar_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2589 return wow_handlers32
.scrollbar_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2593 /***********************************************************************
2596 static LRESULT
static_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2602 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
2603 LRESULT ret
= wow_handlers32
.static_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2606 if (((ULONG_PTR
)cs
->hInstance
>> 16)) return ret
; /* 32-bit instance, nothing to do */
2607 switch (cs
->style
& SS_TYPEMASK
)
2611 HICON16 icon
= LoadIcon16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2612 if (!icon
) icon
= LoadCursor16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2613 if (icon
) wow_handlers32
.static_proc( hwnd
, STM_SETIMAGE
, IMAGE_ICON
,
2614 (LPARAM
)get_icon_32(icon
), FALSE
);
2619 HBITMAP16 bitmap
= LoadBitmap16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2620 if (bitmap
) wow_handlers32
.static_proc( hwnd
, STM_SETIMAGE
, IMAGE_BITMAP
,
2621 (LPARAM
)HBITMAP_32(bitmap
), FALSE
);
2628 wParam
= (WPARAM
)get_icon_32( (HICON16
)wParam
);
2629 return wow_handlers32
.static_proc( hwnd
, STM_SETICON
, wParam
, lParam
, FALSE
);
2631 return get_icon_16( (HICON
)wow_handlers32
.static_proc( hwnd
, STM_GETICON
, wParam
, lParam
, FALSE
));
2633 return wow_handlers32
.static_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2638 /***********************************************************************
2641 static DWORD
wait_message16( DWORD count
, const HANDLE
*handles
, DWORD timeout
, DWORD mask
, DWORD flags
)
2645 ReleaseThunkLock( &lock
);
2646 ret
= wow_handlers32
.wait_message( count
, handles
, timeout
, mask
, flags
);
2647 RestoreThunkLock( lock
);
2652 /***********************************************************************
2655 HWND
create_window16( CREATESTRUCTW
*cs
, LPCWSTR className
, HINSTANCE instance
, BOOL unicode
)
2657 /* map to module handle */
2658 if (instance
&& !((ULONG_PTR
)instance
>> 16))
2659 instance
= HINSTANCE_32( GetExePtr( HINSTANCE_16(instance
) ));
2661 return wow_handlers32
.create_window( cs
, className
, instance
, unicode
);
2665 /***********************************************************************
2668 static void free_icon_param( ULONG_PTR param
)
2670 GlobalFree16( LOWORD(param
) );
2674 void register_wow_handlers(void)
2676 static const struct wow_handlers16 handlers16
=
2687 call_window_proc_Ato16
,
2688 call_dialog_proc_Ato16
,
2692 UserRegisterWowHandlers( &handlers16
, &wow_handlers32
);