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 WNDPROC16 func
= arg
;
232 int index
= winproc_to_index( func
);
241 DRAWITEMSTRUCT16 dis16
;
242 COMPAREITEMSTRUCT16 cis16
;
246 if (index
>= MAX_WINPROCS32
) func
= winproc16_array
[index
- MAX_WINPROCS32
];
248 /* Window procedures want ax = hInstance, ds = es = ss */
250 memset(&context
, 0, sizeof(context
));
251 context
.SegDs
= context
.SegEs
= SELECTOROF(NtCurrentTeb()->WOW32Reserved
);
252 context
.SegFs
= wine_get_fs();
253 context
.SegGs
= wine_get_gs();
254 if (!(context
.Eax
= GetWindowWord( HWND_32(hwnd
), GWLP_HINSTANCE
))) context
.Eax
= context
.SegDs
;
255 context
.SegCs
= SELECTOROF(func
);
256 context
.Eip
= OFFSETOF(func
);
257 context
.Ebp
= OFFSETOF(NtCurrentTeb()->WOW32Reserved
) + FIELD_OFFSET(STACK16FRAME
, bp
);
261 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
262 work if structures passed in lParam are placed in the stack/data
263 segment. Programmers easily make the mistake of converting lParam
264 to a near rather than a far pointer, since Windows apparently
265 allows this. We copy the structures to the 16 bit stack; this is
266 ugly but makes these programs work. */
271 size
= sizeof(CREATESTRUCT16
); break;
273 size
= sizeof(DRAWITEMSTRUCT16
); break;
275 size
= sizeof(COMPAREITEMSTRUCT16
); break;
279 memcpy( &args
.u
, MapSL(lParam
), size
);
280 lParam
= PtrToUlong(NtCurrentTeb()->WOW32Reserved
) - size
;
284 args
.params
[4] = hwnd
;
285 args
.params
[3] = msg
;
286 args
.params
[2] = wParam
;
287 args
.params
[1] = HIWORD(lParam
);
288 args
.params
[0] = LOWORD(lParam
);
289 WOWCallback16Ex( 0, WCB16_REGS
, sizeof(args
.params
) + size
, &args
, (DWORD
*)&context
);
290 *result
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
294 static LRESULT
call_dialog_proc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wp
, LPARAM lp
,
295 LRESULT
*result
, void *arg
)
297 LRESULT ret
= call_window_proc16( hwnd
, msg
, wp
, lp
, result
, arg
);
298 *result
= GetWindowLongPtrW( WIN_Handle32(hwnd
), DWLP_MSGRESULT
);
302 static LRESULT
call_window_proc_Ato16( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
303 LRESULT
*result
, void *arg
)
305 return WINPROC_CallProc32ATo16( call_window_proc16
, hwnd
, msg
, wp
, lp
, result
, arg
);
308 static LRESULT
call_dialog_proc_Ato16( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
309 LRESULT
*result
, void *arg
)
311 return WINPROC_CallProc32ATo16( call_dialog_proc16
, hwnd
, msg
, wp
, lp
, result
, arg
);
316 /**********************************************************************
317 * Support for Edit word break proc thunks
320 #define MAX_THUNKS 32
322 #include <pshpack1.h>
323 static struct word_break_thunk
325 BYTE popl_eax
; /* popl %eax (return address) */
326 BYTE pushl_proc16
; /* pushl proc16 */
327 EDITWORDBREAKPROC16 proc16
;
328 BYTE pushl_eax
; /* pushl %eax */
329 BYTE jmp
; /* ljmp call_word_break_proc16 */
331 } *word_break_thunks
;
334 /**********************************************************************
335 * call_word_break_proc16
337 static INT16 CALLBACK
call_word_break_proc16( SEGPTR proc16
, LPSTR text
, INT index
, INT count
, INT action
)
343 segptr
= MapLS( text
);
344 args
[4] = SELECTOROF(segptr
);
345 args
[3] = OFFSETOF(segptr
);
349 WOWCallback16Ex( proc16
, WCB16_PASCAL
, sizeof(args
), args
, &result
);
351 return LOWORD(result
);
354 /******************************************************************
355 * add_word_break_thunk
357 static struct word_break_thunk
*add_word_break_thunk( EDITWORDBREAKPROC16 proc16
)
359 struct word_break_thunk
*thunk
;
361 if (!word_break_thunks
)
363 word_break_thunks
= VirtualAlloc( NULL
, MAX_THUNKS
* sizeof(*thunk
),
364 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
365 if (!word_break_thunks
) return NULL
;
367 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
369 thunk
->popl_eax
= 0x58; /* popl %eax */
370 thunk
->pushl_proc16
= 0x68; /* pushl proc16 */
371 thunk
->pushl_eax
= 0x50; /* pushl %eax */
372 thunk
->jmp
= 0xe9; /* jmp call_word_break_proc16 */
373 thunk
->callback
= (char *)call_word_break_proc16
- (char *)(&thunk
->callback
+ 1);
376 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
377 if (thunk
->proc16
== proc16
) return thunk
;
379 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
381 if (thunk
->proc16
) continue;
382 thunk
->proc16
= proc16
;
385 FIXME("Out of word break thunks\n");
389 /******************************************************************
390 * get_word_break_thunk
392 static EDITWORDBREAKPROC16
get_word_break_thunk( EDITWORDBREAKPROCA proc
)
394 struct word_break_thunk
*thunk
= (struct word_break_thunk
*)proc
;
395 if (word_break_thunks
&& thunk
>= word_break_thunks
&& thunk
< &word_break_thunks
[MAX_THUNKS
])
396 return thunk
->proc16
;
401 /***********************************************************************
402 * Support for 16<->32 message mapping
405 static inline void *get_buffer( void *static_buffer
, size_t size
, size_t need
)
407 if (size
>= need
) return static_buffer
;
408 return HeapAlloc( GetProcessHeap(), 0, need
);
411 static inline void free_buffer( void *static_buffer
, void *buffer
)
413 if (buffer
!= static_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
416 static void RECT16to32( const RECT16
*from
, RECT
*to
)
418 to
->left
= from
->left
;
420 to
->right
= from
->right
;
421 to
->bottom
= from
->bottom
;
424 static void RECT32to16( const RECT
*from
, RECT16
*to
)
426 to
->left
= from
->left
;
428 to
->right
= from
->right
;
429 to
->bottom
= from
->bottom
;
432 static void MINMAXINFO32to16( const MINMAXINFO
*from
, MINMAXINFO16
*to
)
434 to
->ptReserved
.x
= from
->ptReserved
.x
;
435 to
->ptReserved
.y
= from
->ptReserved
.y
;
436 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
437 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
438 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
439 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
440 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
441 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
442 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
443 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
446 static void MINMAXINFO16to32( const MINMAXINFO16
*from
, MINMAXINFO
*to
)
448 to
->ptReserved
.x
= from
->ptReserved
.x
;
449 to
->ptReserved
.y
= from
->ptReserved
.y
;
450 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
451 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
452 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
453 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
454 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
455 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
456 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
457 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
460 static void WINDOWPOS32to16( const WINDOWPOS
* from
, WINDOWPOS16
* to
)
462 to
->hwnd
= HWND_16(from
->hwnd
);
463 to
->hwndInsertAfter
= HWND_16(from
->hwndInsertAfter
);
468 to
->flags
= from
->flags
;
471 static void WINDOWPOS16to32( const WINDOWPOS16
* from
, WINDOWPOS
* to
)
473 to
->hwnd
= WIN_Handle32(from
->hwnd
);
474 to
->hwndInsertAfter
= (from
->hwndInsertAfter
== (HWND16
)-1) ?
475 HWND_TOPMOST
: WIN_Handle32(from
->hwndInsertAfter
);
480 to
->flags
= from
->flags
;
483 /* The strings are not copied */
484 static void CREATESTRUCT32Ato16( const CREATESTRUCTA
* from
, CREATESTRUCT16
* to
)
486 to
->lpCreateParams
= (SEGPTR
)from
->lpCreateParams
;
487 to
->hInstance
= HINSTANCE_16(from
->hInstance
);
488 to
->hMenu
= HMENU_16(from
->hMenu
);
489 to
->hwndParent
= HWND_16(from
->hwndParent
);
494 to
->style
= from
->style
;
495 to
->dwExStyle
= from
->dwExStyle
;
498 static void CREATESTRUCT16to32A( const CREATESTRUCT16
* from
, CREATESTRUCTA
*to
)
501 to
->lpCreateParams
= (LPVOID
)from
->lpCreateParams
;
502 to
->hInstance
= HINSTANCE_32(from
->hInstance
);
503 to
->hMenu
= HMENU_32(from
->hMenu
);
504 to
->hwndParent
= WIN_Handle32(from
->hwndParent
);
509 to
->style
= from
->style
;
510 to
->dwExStyle
= from
->dwExStyle
;
511 to
->lpszName
= MapSL(from
->lpszName
);
512 to
->lpszClass
= MapSL(from
->lpszClass
);
515 /* The strings are not copied */
516 static void MDICREATESTRUCT32Ato16( const MDICREATESTRUCTA
* from
, MDICREATESTRUCT16
* to
)
518 to
->hOwner
= HINSTANCE_16(from
->hOwner
);
523 to
->style
= from
->style
;
524 to
->lParam
= from
->lParam
;
527 static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16
* from
, MDICREATESTRUCTA
*to
)
529 to
->hOwner
= HINSTANCE_32(from
->hOwner
);
534 to
->style
= from
->style
;
535 to
->lParam
= from
->lParam
;
536 to
->szTitle
= MapSL(from
->szTitle
);
537 to
->szClass
= MapSL(from
->szClass
);
540 static UINT_PTR
convert_handle_16_to_32(HANDLE16 src
, unsigned int flags
)
543 UINT sz
= GlobalSize16(src
);
546 if (!(dst
= GlobalAlloc(flags
, sz
)))
548 ptr16
= GlobalLock16(src
);
549 ptr32
= GlobalLock(dst
);
550 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr32
, ptr16
, sz
);
554 return (UINT_PTR
)dst
;
557 static HANDLE16
convert_handle_32_to_16(UINT_PTR src
, unsigned int flags
)
560 UINT sz
= GlobalSize((HANDLE
)src
);
563 if (!(dst
= GlobalAlloc16(flags
, sz
)))
565 ptr32
= GlobalLock((HANDLE
)src
);
566 ptr16
= GlobalLock16(dst
);
567 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr16
, ptr32
, sz
);
568 GlobalUnlock((HANDLE
)src
);
574 static BOOL
is_old_app( HWND hwnd
)
576 HINSTANCE inst
= (HINSTANCE
)GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
577 return inst
&& !((ULONG_PTR
)inst
>> 16) && (GetExpWinVer16(LOWORD(inst
)) & 0xFF00) == 0x0300;
580 static int find_sub_menu( HMENU
*hmenu
, HMENU16 target
)
582 int i
, pos
, count
= GetMenuItemCount( *hmenu
);
584 for (i
= 0; i
< count
; i
++)
586 HMENU sub
= GetSubMenu( *hmenu
, i
);
588 if (HMENU_16(sub
) == target
) return i
;
589 if ((pos
= find_sub_menu( &sub
, target
)) != -1)
598 /**********************************************************************
599 * WINPROC_CallProc16To32A
601 LRESULT
WINPROC_CallProc16To32A( winproc_callback_t callback
, HWND16 hwnd
, UINT16 msg
,
602 WPARAM16 wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
605 HWND hwnd32
= WIN_Handle32( hwnd
);
612 CREATESTRUCT16
*cs16
= MapSL(lParam
);
614 MDICREATESTRUCTA mdi_cs
;
616 CREATESTRUCT16to32A( cs16
, &cs
);
617 if (GetWindowLongW(hwnd32
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
619 MDICREATESTRUCT16
*mdi_cs16
= MapSL(cs16
->lpCreateParams
);
620 MDICREATESTRUCT16to32A(mdi_cs16
, &mdi_cs
);
621 cs
.lpCreateParams
= &mdi_cs
;
623 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cs
, result
, arg
);
624 CREATESTRUCT32Ato16( &cs
, cs16
);
629 MDICREATESTRUCT16
*cs16
= MapSL(lParam
);
632 MDICREATESTRUCT16to32A( cs16
, &cs
);
633 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cs
, result
, arg
);
634 MDICREATESTRUCT32Ato16( &cs
, cs16
);
639 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32( HIWORD(lParam
) ),
640 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
641 else /* message sent to MDI client */
642 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
644 case WM_MDIGETACTIVE
:
646 BOOL maximized
= FALSE
;
647 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&maximized
, result
, arg
);
648 *result
= MAKELRESULT( LOWORD(*result
), maximized
);
652 ret
= callback( hwnd32
, wParam
? WM_MDIREFRESHMENU
: WM_MDISETMENU
,
653 (WPARAM
)HMENU_32(LOWORD(lParam
)), (LPARAM
)HMENU_32(HIWORD(lParam
)),
656 case WM_GETMINMAXINFO
:
658 MINMAXINFO16
*mmi16
= MapSL(lParam
);
661 MINMAXINFO16to32( mmi16
, &mmi
);
662 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&mmi
, result
, arg
);
663 MINMAXINFO32to16( &mmi
, mmi16
);
666 case WM_WINDOWPOSCHANGING
:
667 case WM_WINDOWPOSCHANGED
:
669 WINDOWPOS16
*winpos16
= MapSL(lParam
);
672 WINDOWPOS16to32( winpos16
, &winpos
);
673 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&winpos
, result
, arg
);
674 WINDOWPOS32to16( &winpos
, winpos16
);
679 NCCALCSIZE_PARAMS16
*nc16
= MapSL(lParam
);
680 NCCALCSIZE_PARAMS nc
;
683 RECT16to32( &nc16
->rgrc
[0], &nc
.rgrc
[0] );
686 RECT16to32( &nc16
->rgrc
[1], &nc
.rgrc
[1] );
687 RECT16to32( &nc16
->rgrc
[2], &nc
.rgrc
[2] );
688 WINDOWPOS16to32( MapSL(nc16
->lppos
), &winpos
);
691 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&nc
, result
, arg
);
692 RECT32to16( &nc
.rgrc
[0], &nc16
->rgrc
[0] );
695 RECT32to16( &nc
.rgrc
[1], &nc16
->rgrc
[1] );
696 RECT32to16( &nc
.rgrc
[2], &nc16
->rgrc
[2] );
697 WINDOWPOS32to16( &winpos
, MapSL(nc16
->lppos
) );
703 COMPAREITEMSTRUCT16
* cis16
= MapSL(lParam
);
704 COMPAREITEMSTRUCT cis
;
705 cis
.CtlType
= cis16
->CtlType
;
706 cis
.CtlID
= cis16
->CtlID
;
707 cis
.hwndItem
= WIN_Handle32( cis16
->hwndItem
);
708 cis
.itemID1
= cis16
->itemID1
;
709 cis
.itemData1
= cis16
->itemData1
;
710 cis
.itemID2
= cis16
->itemID2
;
711 cis
.itemData2
= cis16
->itemData2
;
712 cis
.dwLocaleId
= 0; /* FIXME */
713 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cis
, result
, arg
);
718 DELETEITEMSTRUCT16
* dis16
= MapSL(lParam
);
719 DELETEITEMSTRUCT dis
;
720 dis
.CtlType
= dis16
->CtlType
;
721 dis
.CtlID
= dis16
->CtlID
;
722 dis
.hwndItem
= WIN_Handle32( dis16
->hwndItem
);
723 dis
.itemData
= dis16
->itemData
;
724 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&dis
, result
, arg
);
729 MEASUREITEMSTRUCT16
* mis16
= MapSL(lParam
);
730 MEASUREITEMSTRUCT mis
;
731 mis
.CtlType
= mis16
->CtlType
;
732 mis
.CtlID
= mis16
->CtlID
;
733 mis
.itemID
= mis16
->itemID
;
734 mis
.itemWidth
= mis16
->itemWidth
;
735 mis
.itemHeight
= mis16
->itemHeight
;
736 mis
.itemData
= mis16
->itemData
;
737 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&mis
, result
, arg
);
738 mis16
->itemWidth
= (UINT16
)mis
.itemWidth
;
739 mis16
->itemHeight
= (UINT16
)mis
.itemHeight
;
744 DRAWITEMSTRUCT16
* dis16
= MapSL(lParam
);
746 dis
.CtlType
= dis16
->CtlType
;
747 dis
.CtlID
= dis16
->CtlID
;
748 dis
.itemID
= dis16
->itemID
;
749 dis
.itemAction
= dis16
->itemAction
;
750 dis
.itemState
= dis16
->itemState
;
751 dis
.hwndItem
= (dis
.CtlType
== ODT_MENU
) ? (HWND
)HMENU_32(dis16
->hwndItem
)
752 : WIN_Handle32( dis16
->hwndItem
);
753 dis
.hDC
= HDC_32(dis16
->hDC
);
754 dis
.itemData
= dis16
->itemData
;
755 dis
.rcItem
.left
= dis16
->rcItem
.left
;
756 dis
.rcItem
.top
= dis16
->rcItem
.top
;
757 dis
.rcItem
.right
= dis16
->rcItem
.right
;
758 dis
.rcItem
.bottom
= dis16
->rcItem
.bottom
;
759 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&dis
, result
, arg
);
764 COPYDATASTRUCT16
*cds16
= MapSL(lParam
);
766 cds
.dwData
= cds16
->dwData
;
767 cds
.cbData
= cds16
->cbData
;
768 cds
.lpData
= MapSL(cds16
->lpData
);
769 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cds
, result
, arg
);
775 MSG16
*msg16
= MapSL(lParam
);
777 msg32
.hwnd
= WIN_Handle32( msg16
->hwnd
);
778 msg32
.message
= msg16
->message
;
779 msg32
.wParam
= msg16
->wParam
;
780 msg32
.lParam
= msg16
->lParam
;
781 msg32
.time
= msg16
->time
;
782 msg32
.pt
.x
= msg16
->pt
.x
;
783 msg32
.pt
.y
= msg16
->pt
.y
;
784 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&msg32
, result
, arg
);
787 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
792 next
.hmenuIn
= (HMENU
)lParam
;
795 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&next
, result
, arg
);
796 *result
= MAKELONG( HMENU_16(next
.hmenuNext
), HWND_16(next
.hwndNext
) );
803 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, HIWORD(lParam
) ),
804 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
808 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
809 (LPARAM
)WIN_Handle32( HIWORD(lParam
) ), result
, arg
);
812 if (HIWORD(lParam
) <= CTLCOLOR_STATIC
)
813 ret
= callback( hwnd32
, WM_CTLCOLORMSGBOX
+ HIWORD(lParam
),
814 (WPARAM
)HDC_32(wParam
), (LPARAM
)WIN_Handle32( LOWORD(lParam
) ),
819 case WM_WININICHANGE
:
820 case WM_DEVMODECHANGE
:
821 case WM_ASKCBFORMATNAME
:
823 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)MapSL(lParam
), result
, arg
);
826 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
827 (LPARAM
)HMENU_32(HIWORD(lParam
)), result
, arg
);
830 if((LOWORD(lParam
) & MF_POPUP
) && (LOWORD(lParam
) != 0xFFFF))
832 HMENU hmenu
= HMENU_32(HIWORD(lParam
));
833 int pos
= find_sub_menu( &hmenu
, wParam
);
834 if (pos
== -1) pos
= 0;
837 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
838 (LPARAM
)HMENU_32(HIWORD(lParam
)), result
, arg
);
840 case WM_PARENTNOTIFY
:
841 if ((wParam
== WM_CREATE
) || (wParam
== WM_DESTROY
))
842 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, HIWORD(lParam
) ),
843 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
845 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
848 /* We need this when SetActiveWindow sends a Sendmessage16() to
849 * a 32-bit window. Might be superfluous with 32-bit interprocess
851 if (lParam
) lParam
= HTASK_32(lParam
);
852 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
854 case WM_DDE_INITIATE
:
855 case WM_DDE_TERMINATE
:
856 case WM_DDE_UNADVISE
:
858 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
864 HANDLE16 lo16
= LOWORD(lParam
);
866 if (lo16
&& !(lo32
= convert_handle_16_to_32(lo16
, GMEM_DDESHARE
))) break;
867 lParam
= PackDDElParam( msg
, lo32
, HIWORD(lParam
) );
868 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
870 break; /* FIXME don't know how to free allocated memory (handle) !! */
873 UINT_PTR lo
= LOWORD(lParam
);
874 UINT_PTR hi
= HIWORD(lParam
);
878 if (GlobalGetAtomNameA(hi
, buf
, 2) > 0) flag
|= 1;
879 if (GlobalSize16(hi
) != 0) flag
|= 2;
885 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
890 break; /* atom, nothing to do */
892 MESSAGE("DDE_ACK: %lx both atom and handle... choosing handle\n", hi
);
895 hi
= convert_handle_16_to_32(hi
, GMEM_DDESHARE
);
898 lParam
= PackDDElParam( WM_DDE_ACK
, lo
, hi
);
899 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
901 break; /* FIXME don't know how to free allocated memory (handle) !! */
903 lParam
= convert_handle_16_to_32( lParam
, GMEM_DDESHARE
);
904 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
905 break; /* FIXME don't know how to free allocated memory (handle) !! */
906 case WM_PAINTCLIPBOARD
:
907 case WM_SIZECLIPBOARD
:
908 FIXME_(msg
)( "message %04x needs translation\n", msg
);
911 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
918 /**********************************************************************
919 * WINPROC_CallProc32ATo16
921 * Call a 16-bit window procedure, translating the 32-bit args.
923 LRESULT
WINPROC_CallProc32ATo16( winproc_callback16_t callback
, HWND hwnd
, UINT msg
,
924 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
933 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)lParam
;
935 MDICREATESTRUCT16 mdi_cs16
;
936 BOOL mdi_child
= (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
);
938 CREATESTRUCT32Ato16( cs32
, &cs
);
939 cs
.lpszName
= MapLS( cs32
->lpszName
);
940 cs
.lpszClass
= MapLS( cs32
->lpszClass
);
944 MDICREATESTRUCTA
*mdi_cs
= cs32
->lpCreateParams
;
945 MDICREATESTRUCT32Ato16( mdi_cs
, &mdi_cs16
);
946 mdi_cs16
.szTitle
= MapLS( mdi_cs
->szTitle
);
947 mdi_cs16
.szClass
= MapLS( mdi_cs
->szClass
);
948 cs
.lpCreateParams
= MapLS( &mdi_cs16
);
950 lParam
= MapLS( &cs
);
951 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
953 UnMapLS( cs
.lpszName
);
954 UnMapLS( cs
.lpszClass
);
957 UnMapLS( cs
.lpCreateParams
);
958 UnMapLS( mdi_cs16
.szTitle
);
959 UnMapLS( mdi_cs16
.szClass
);
965 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)lParam
;
966 MDICREATESTRUCT16 cs
;
968 MDICREATESTRUCT32Ato16( cs32
, &cs
);
969 cs
.szTitle
= MapLS( cs32
->szTitle
);
970 cs
.szClass
= MapLS( cs32
->szClass
);
971 lParam
= MapLS( &cs
);
972 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
974 UnMapLS( cs
.szTitle
);
975 UnMapLS( cs
.szClass
);
979 if (GetWindowLongW( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
980 ret
= callback( HWND_16(hwnd
), msg
, ((HWND
)lParam
== hwnd
),
981 MAKELPARAM( LOWORD(lParam
), LOWORD(wParam
) ), result
, arg
);
983 ret
= callback( HWND_16(hwnd
), msg
, HWND_16( wParam
), 0, result
, arg
);
985 case WM_MDIGETACTIVE
:
986 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
987 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(*result
);
988 *result
= (LRESULT
)WIN_Handle32( LOWORD(*result
) );
991 ret
= callback( HWND_16(hwnd
), msg
, (lParam
== 0),
992 MAKELPARAM( LOWORD(wParam
), LOWORD(lParam
) ), result
, arg
);
994 case WM_GETMINMAXINFO
:
996 MINMAXINFO
*mmi32
= (MINMAXINFO
*)lParam
;
999 MINMAXINFO32to16( mmi32
, &mmi
);
1000 lParam
= MapLS( &mmi
);
1001 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1003 MINMAXINFO16to32( &mmi
, mmi32
);
1008 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)lParam
;
1009 NCCALCSIZE_PARAMS16 nc
;
1012 RECT32to16( &nc32
->rgrc
[0], &nc
.rgrc
[0] );
1015 RECT32to16( &nc32
->rgrc
[1], &nc
.rgrc
[1] );
1016 RECT32to16( &nc32
->rgrc
[2], &nc
.rgrc
[2] );
1017 WINDOWPOS32to16( nc32
->lppos
, &winpos
);
1018 nc
.lppos
= MapLS( &winpos
);
1020 lParam
= MapLS( &nc
);
1021 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1023 RECT16to32( &nc
.rgrc
[0], &nc32
->rgrc
[0] );
1026 RECT16to32( &nc
.rgrc
[1], &nc32
->rgrc
[1] );
1027 RECT16to32( &nc
.rgrc
[2], &nc32
->rgrc
[2] );
1028 WINDOWPOS16to32( &winpos
, nc32
->lppos
);
1029 UnMapLS( nc
.lppos
);
1033 case WM_WINDOWPOSCHANGING
:
1034 case WM_WINDOWPOSCHANGED
:
1036 WINDOWPOS
*winpos32
= (WINDOWPOS
*)lParam
;
1039 WINDOWPOS32to16( winpos32
, &winpos
);
1040 lParam
= MapLS( &winpos
);
1041 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1043 WINDOWPOS16to32( &winpos
, winpos32
);
1046 case WM_COMPAREITEM
:
1048 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)lParam
;
1049 COMPAREITEMSTRUCT16 cis
;
1050 cis
.CtlType
= cis32
->CtlType
;
1051 cis
.CtlID
= cis32
->CtlID
;
1052 cis
.hwndItem
= HWND_16( cis32
->hwndItem
);
1053 cis
.itemID1
= cis32
->itemID1
;
1054 cis
.itemData1
= cis32
->itemData1
;
1055 cis
.itemID2
= cis32
->itemID2
;
1056 cis
.itemData2
= cis32
->itemData2
;
1057 lParam
= MapLS( &cis
);
1058 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1064 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)lParam
;
1065 DELETEITEMSTRUCT16 dis
;
1066 dis
.CtlType
= dis32
->CtlType
;
1067 dis
.CtlID
= dis32
->CtlID
;
1068 dis
.itemID
= dis32
->itemID
;
1069 dis
.hwndItem
= (dis
.CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
1070 : HWND_16( dis32
->hwndItem
);
1071 dis
.itemData
= dis32
->itemData
;
1072 lParam
= MapLS( &dis
);
1073 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1079 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)lParam
;
1080 DRAWITEMSTRUCT16 dis
;
1081 dis
.CtlType
= dis32
->CtlType
;
1082 dis
.CtlID
= dis32
->CtlID
;
1083 dis
.itemID
= dis32
->itemID
;
1084 dis
.itemAction
= dis32
->itemAction
;
1085 dis
.itemState
= dis32
->itemState
;
1086 dis
.hwndItem
= HWND_16( dis32
->hwndItem
);
1087 dis
.hDC
= HDC_16(dis32
->hDC
);
1088 dis
.itemData
= dis32
->itemData
;
1089 dis
.rcItem
.left
= dis32
->rcItem
.left
;
1090 dis
.rcItem
.top
= dis32
->rcItem
.top
;
1091 dis
.rcItem
.right
= dis32
->rcItem
.right
;
1092 dis
.rcItem
.bottom
= dis32
->rcItem
.bottom
;
1093 lParam
= MapLS( &dis
);
1094 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1098 case WM_MEASUREITEM
:
1100 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)lParam
;
1101 MEASUREITEMSTRUCT16 mis
;
1102 mis
.CtlType
= mis32
->CtlType
;
1103 mis
.CtlID
= mis32
->CtlID
;
1104 mis
.itemID
= mis32
->itemID
;
1105 mis
.itemWidth
= mis32
->itemWidth
;
1106 mis
.itemHeight
= mis32
->itemHeight
;
1107 mis
.itemData
= mis32
->itemData
;
1108 lParam
= MapLS( &mis
);
1109 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1111 mis32
->itemWidth
= mis
.itemWidth
;
1112 mis32
->itemHeight
= mis
.itemHeight
;
1117 COPYDATASTRUCT
*cds32
= (COPYDATASTRUCT
*)lParam
;
1118 COPYDATASTRUCT16 cds
;
1120 cds
.dwData
= cds32
->dwData
;
1121 cds
.cbData
= cds32
->cbData
;
1122 cds
.lpData
= MapLS( cds32
->lpData
);
1123 lParam
= MapLS( &cds
);
1124 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1126 UnMapLS( cds
.lpData
);
1132 MSG
*msg32
= (MSG
*)lParam
;
1135 msg16
.hwnd
= HWND_16( msg32
->hwnd
);
1136 msg16
.message
= msg32
->message
;
1137 msg16
.wParam
= msg32
->wParam
;
1138 msg16
.lParam
= msg32
->lParam
;
1139 msg16
.time
= msg32
->time
;
1140 msg16
.pt
.x
= msg32
->pt
.x
;
1141 msg16
.pt
.y
= msg32
->pt
.y
;
1142 lParam
= MapLS( &msg16
);
1143 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1147 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1151 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1152 ret
= callback( HWND_16(hwnd
), msg
, wParam
, (LPARAM
)next
->hmenuIn
, result
, arg
);
1153 next
->hmenuNext
= HMENU_32( LOWORD(*result
) );
1154 next
->hwndNext
= WIN_Handle32( HIWORD(*result
) );
1159 case WM_ASKCBFORMATNAME
:
1160 wParam
= min( wParam
, 0xff80 ); /* Must be < 64K */
1164 case WM_WININICHANGE
:
1165 case WM_DEVMODECHANGE
:
1166 lParam
= MapLS( (void *)lParam
);
1167 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1174 ret
= callback( HWND_16(hwnd
), msg
, wParam
, MAKELPARAM( (HWND16
)lParam
, HIWORD(wParam
) ),
1179 ret
= callback( HWND_16(hwnd
), msg
, wParam
, MAKELPARAM( HIWORD(wParam
), (HWND16
)lParam
),
1182 case WM_CTLCOLORMSGBOX
:
1183 case WM_CTLCOLOREDIT
:
1184 case WM_CTLCOLORLISTBOX
:
1185 case WM_CTLCOLORBTN
:
1186 case WM_CTLCOLORDLG
:
1187 case WM_CTLCOLORSCROLLBAR
:
1188 case WM_CTLCOLORSTATIC
:
1189 ret
= callback( HWND_16(hwnd
), WM_CTLCOLOR
, wParam
,
1190 MAKELPARAM( (HWND16
)lParam
, msg
- WM_CTLCOLORMSGBOX
), result
, arg
);
1193 if(HIWORD(wParam
) & MF_POPUP
)
1196 if ((HIWORD(wParam
) != 0xffff) || lParam
)
1198 if ((hmenu
= GetSubMenu( (HMENU
)lParam
, LOWORD(wParam
) )))
1200 ret
= callback( HWND_16(hwnd
), msg
, HMENU_16(hmenu
),
1201 MAKELPARAM( HIWORD(wParam
), (HMENU16
)lParam
), result
, arg
);
1208 ret
= callback( HWND_16(hwnd
), msg
, wParam
,
1209 MAKELPARAM( HIWORD(wParam
), (HMENU16
)lParam
), result
, arg
);
1211 case WM_PARENTNOTIFY
:
1212 if ((LOWORD(wParam
) == WM_CREATE
) || (LOWORD(wParam
) == WM_DESTROY
))
1213 ret
= callback( HWND_16(hwnd
), msg
, wParam
,
1214 MAKELPARAM( (HWND16
)lParam
, HIWORD(wParam
) ), result
, arg
);
1216 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1218 case WM_ACTIVATEAPP
:
1219 ret
= callback( HWND_16(hwnd
), msg
, wParam
, HTASK_16( lParam
), result
, arg
);
1222 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
))
1223 ret
= callback( HWND_16(hwnd
), WM_PAINTICON
, 1, lParam
, result
, arg
);
1225 ret
= callback( HWND_16(hwnd
), WM_PAINT
, wParam
, lParam
, result
, arg
);
1228 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
)) msg
= WM_ICONERASEBKGND
;
1229 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1231 case WM_DDE_INITIATE
:
1232 case WM_DDE_TERMINATE
:
1233 case WM_DDE_UNADVISE
:
1234 case WM_DDE_REQUEST
:
1235 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
), lParam
, result
, arg
);
1244 UnpackDDElParam( msg
, lParam
, &lo32
, &hi
);
1245 if (lo32
&& !(lo16
= convert_handle_32_to_16(lo32
, GMEM_DDESHARE
))) break;
1246 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
),
1247 MAKELPARAM(lo16
, hi
), result
, arg
);
1249 break; /* FIXME don't know how to free allocated memory (handle) !! */
1256 UnpackDDElParam( msg
, lParam
, &lo
, &hi
);
1258 if (GlobalGetAtomNameA((ATOM
)hi
, buf
, sizeof(buf
)) > 0) flag
|= 1;
1259 if (GlobalSize((HANDLE
)hi
) != 0) flag
|= 2;
1265 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1270 break; /* atom, nothing to do */
1272 MESSAGE("DDE_ACK: %lx both atom and handle... choosing handle\n", hi
);
1275 hi
= convert_handle_32_to_16(hi
, GMEM_DDESHARE
);
1278 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
),
1279 MAKELPARAM(lo
, hi
), result
, arg
);
1281 break; /* FIXME don't know how to free allocated memory (handle) !! */
1282 case WM_DDE_EXECUTE
:
1283 lParam
= convert_handle_32_to_16(lParam
, GMEM_DDESHARE
);
1284 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1285 break; /* FIXME don't know how to free allocated memory (handle) !! */
1287 ret
= callback( HWND_16(hwnd
), SBM_SETRANGE16
, 0, MAKELPARAM(wParam
, lParam
), result
, arg
);
1290 ret
= callback( HWND_16(hwnd
), SBM_GETRANGE16
, wParam
, lParam
, result
, arg
);
1291 *(LPINT
)wParam
= LOWORD(*result
);
1292 *(LPINT
)lParam
= HIWORD(*result
);
1299 ret
= callback( HWND_16(hwnd
), msg
+ BM_GETCHECK16
- BM_GETCHECK
, wParam
, lParam
, result
, arg
);
1307 case EM_SCROLLCARET
:
1310 case EM_GETLINECOUNT
:
1322 case EM_LINEFROMCHAR
:
1323 case EM_SETTABSTOPS
:
1324 case EM_SETPASSWORDCHAR
:
1325 case EM_EMPTYUNDOBUFFER
:
1326 case EM_GETFIRSTVISIBLELINE
:
1327 case EM_SETREADONLY
:
1328 case EM_SETWORDBREAKPROC
:
1329 case EM_GETWORDBREAKPROC
:
1330 case EM_GETPASSWORDCHAR
:
1331 ret
= callback( HWND_16(hwnd
), msg
+ EM_GETSEL16
- EM_GETSEL
, wParam
, lParam
, result
, arg
);
1334 ret
= callback( HWND_16(hwnd
), EM_SETSEL16
, 0, MAKELPARAM( wParam
, lParam
), result
, arg
);
1338 case LB_DELETESTRING
:
1339 case LB_GETANCHORINDEX
:
1340 case LB_GETCARETINDEX
:
1343 case LB_GETHORIZONTALEXTENT
:
1344 case LB_GETITEMDATA
:
1345 case LB_GETITEMHEIGHT
:
1347 case LB_GETSELCOUNT
:
1349 case LB_GETTOPINDEX
:
1350 case LB_RESETCONTENT
:
1351 case LB_SELITEMRANGE
:
1352 case LB_SELITEMRANGEEX
:
1353 case LB_SETANCHORINDEX
:
1354 case LB_SETCARETINDEX
:
1355 case LB_SETCOLUMNWIDTH
:
1357 case LB_SETHORIZONTALEXTENT
:
1358 case LB_SETITEMDATA
:
1359 case LB_SETITEMHEIGHT
:
1361 case LB_SETTOPINDEX
:
1362 ret
= callback( HWND_16(hwnd
), msg
+ LB_ADDSTRING16
- LB_ADDSTRING
, wParam
, lParam
, result
, arg
);
1366 case LB_FINDSTRINGEXACT
:
1367 case LB_INSERTSTRING
:
1368 case LB_SELECTSTRING
:
1372 lParam
= MapLS( (LPSTR
)lParam
);
1373 ret
= callback( HWND_16(hwnd
), msg
+ LB_ADDSTRING16
- LB_ADDSTRING
, wParam
, lParam
, result
, arg
);
1376 case LB_GETSELITEMS
:
1378 INT
*items32
= (INT
*)lParam
;
1379 INT16
*items
, buffer
[512];
1382 wParam
= min( wParam
, 0x7f80 ); /* Must be < 64K */
1383 if (!(items
= get_buffer( buffer
, sizeof(buffer
), wParam
* sizeof(INT16
) ))) break;
1384 lParam
= MapLS( items
);
1385 ret
= callback( HWND_16(hwnd
), LB_GETSELITEMS16
, wParam
, lParam
, result
, arg
);
1387 for (i
= 0; i
< wParam
; i
++) items32
[i
] = items
[i
];
1388 free_buffer( buffer
, items
);
1391 case LB_SETTABSTOPS
:
1394 INT
*stops32
= (INT
*)lParam
;
1395 INT16
*stops
, buffer
[512];
1398 wParam
= min( wParam
, 0x7f80 ); /* Must be < 64K */
1399 if (!(stops
= get_buffer( buffer
, sizeof(buffer
), wParam
* sizeof(INT16
) ))) break;
1400 for (i
= 0; i
< wParam
; i
++) stops
[i
] = stops32
[i
];
1401 lParam
= MapLS( stops
);
1402 ret
= callback( HWND_16(hwnd
), LB_SETTABSTOPS16
, wParam
, lParam
, result
, arg
);
1404 free_buffer( buffer
, stops
);
1406 else ret
= callback( HWND_16(hwnd
), LB_SETTABSTOPS16
, wParam
, lParam
, result
, arg
);
1408 case CB_DELETESTRING
:
1410 case CB_GETLBTEXTLEN
:
1412 case CB_RESETCONTENT
:
1416 case CB_SHOWDROPDOWN
:
1417 case CB_SETITEMDATA
:
1418 case CB_SETITEMHEIGHT
:
1419 case CB_GETITEMHEIGHT
:
1420 case CB_SETEXTENDEDUI
:
1421 case CB_GETEXTENDEDUI
:
1422 case CB_GETDROPPEDSTATE
:
1423 ret
= callback( HWND_16(hwnd
), msg
+ CB_GETEDITSEL16
- CB_GETEDITSEL
, wParam
, lParam
, result
, arg
);
1426 ret
= callback( HWND_16(hwnd
), CB_GETEDITSEL16
, wParam
, lParam
, result
, arg
);
1427 if (wParam
) *((PUINT
)(wParam
)) = LOWORD(*result
);
1428 if (lParam
) *((PUINT
)(lParam
)) = HIWORD(*result
); /* FIXME: subtract 1? */
1432 case CB_FINDSTRINGEXACT
:
1433 case CB_INSERTSTRING
:
1434 case CB_SELECTSTRING
:
1437 lParam
= MapLS( (LPSTR
)lParam
);
1438 ret
= callback( HWND_16(hwnd
), msg
+ CB_GETEDITSEL16
- CB_GETEDITSEL
, wParam
, lParam
, result
, arg
);
1441 case LB_GETITEMRECT
:
1442 case CB_GETDROPPEDCONTROLRECT
:
1444 RECT
*r32
= (RECT
*)lParam
;
1446 lParam
= MapLS( &rect
);
1447 ret
= callback( HWND_16(hwnd
),
1448 (msg
== LB_GETITEMRECT
) ? LB_GETITEMRECT16
: CB_GETDROPPEDCONTROLRECT16
,
1449 wParam
, lParam
, result
, arg
);
1451 RECT16to32( &rect
, r32
);
1454 case WM_PAINTCLIPBOARD
:
1455 case WM_SIZECLIPBOARD
:
1456 FIXME_(msg
)( "message %04x needs translation\n", msg
);
1458 /* the following messages should not be sent to 16-bit apps */
1461 case WM_CAPTURECHANGED
:
1462 case WM_STYLECHANGING
:
1463 case WM_STYLECHANGED
:
1466 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1473 /***********************************************************************
1474 * SendMessage (USER.111)
1476 LRESULT WINAPI
SendMessage16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1479 HWND hwnd
= WIN_Handle32( hwnd16
);
1481 if (hwnd
!= HWND_BROADCAST
&&
1482 GetWindowThreadProcessId( hwnd
, NULL
) == GetCurrentThreadId())
1484 /* call 16-bit window proc directly */
1487 /* first the WH_CALLWNDPROC hook */
1488 call_WH_CALLWNDPROC_hook( hwnd16
, msg
, wparam
, lparam
);
1490 if (!(winproc
= (WNDPROC16
)GetWindowLong16( hwnd16
, GWLP_WNDPROC
))) return 0;
1492 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx\n", hwnd16
, msg
, wparam
, lparam
);
1493 result
= CallWindowProc16( winproc
, hwnd16
, msg
, wparam
, lparam
);
1494 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx returned %08lx\n",
1495 hwnd16
, msg
, wparam
, lparam
, result
);
1497 else /* map to 32-bit unicode for inter-thread/process message */
1499 WINPROC_CallProc16To32A( send_message_callback
, hwnd16
, msg
, wparam
, lparam
, &result
, NULL
);
1505 /***********************************************************************
1506 * PostMessage (USER.110)
1508 BOOL16 WINAPI
PostMessage16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1511 return WINPROC_CallProc16To32A( post_message_callback
, hwnd
, msg
, wparam
, lparam
, &unused
, NULL
);
1515 /***********************************************************************
1516 * PostAppMessage (USER.116)
1518 BOOL16 WINAPI
PostAppMessage16( HTASK16 hTask
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1521 DWORD_PTR tid
= HTASK_32( hTask
);
1523 if (!tid
) return FALSE
;
1524 return WINPROC_CallProc16To32A( post_thread_message_callback
, 0, msg
, wparam
, lparam
,
1525 &unused
, (void *)tid
);
1529 /**********************************************************************
1530 * CallWindowProc (USER.122)
1532 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
1533 WPARAM16 wParam
, LPARAM lParam
)
1535 int index
= winproc_to_index( func
);
1538 if (!func
) return 0;
1540 if (index
== -1 || index
>= MAX_WINPROCS32
)
1541 call_window_proc16( hwnd
, msg
, wParam
, lParam
, &result
, func
);
1544 WNDPROC proc
= (WNDPROC
)func
;
1545 if (thunk_array
&& thunk_array
[index
].proc
) proc
= thunk_array
[index
].proc
;
1546 WINPROC_CallProc16To32A( call_window_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, proc
);
1552 /**********************************************************************
1553 * __wine_call_wndproc (USER.1010)
1555 LRESULT WINAPI
__wine_call_wndproc( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
, WNDPROC proc
)
1558 WINPROC_CallProc16To32A( call_window_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, proc
);
1563 /***********************************************************************
1564 * InSendMessage (USER.192)
1566 BOOL16 WINAPI
InSendMessage16(void)
1568 return InSendMessage();
1572 /***********************************************************************
1573 * ReplyMessage (USER.115)
1575 void WINAPI
ReplyMessage16( LRESULT result
)
1577 ReplyMessage( result
);
1581 /***********************************************************************
1582 * PeekMessage32 (USER.819)
1584 BOOL16 WINAPI
PeekMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
,
1585 UINT16 first
, UINT16 last
, UINT16 flags
,
1586 BOOL16 wHaveParamHigh
)
1590 HWND hwnd
= WIN_Handle32( hwnd16
);
1592 if(USER16_AlertableWait
)
1593 MsgWaitForMultipleObjectsEx( 0, NULL
, 0, 0, MWMO_ALERTABLE
);
1594 if (!PeekMessageA( &msg
, hwnd
, first
, last
, flags
)) return FALSE
;
1596 msg16
->msg
.time
= msg
.time
;
1597 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
1598 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
1599 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
1600 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
1601 &unused
, &msg16
->msg
);
1606 /***********************************************************************
1607 * DefWindowProc (USER.107)
1609 LRESULT WINAPI
DefWindowProc16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
1612 HWND hwnd
= WIN_Handle32( hwnd16
);
1618 CREATESTRUCT16
*cs16
= MapSL(lParam
);
1621 cs32
.lpCreateParams
= ULongToPtr(cs16
->lpCreateParams
);
1622 cs32
.hInstance
= HINSTANCE_32(cs16
->hInstance
);
1623 cs32
.hMenu
= HMENU_32(cs16
->hMenu
);
1624 cs32
.hwndParent
= WIN_Handle32(cs16
->hwndParent
);
1629 cs32
.style
= cs16
->style
;
1630 cs32
.dwExStyle
= cs16
->dwExStyle
;
1631 cs32
.lpszName
= MapSL(cs16
->lpszName
);
1632 cs32
.lpszClass
= MapSL(cs16
->lpszClass
);
1633 return DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&cs32
);
1637 RECT16
*rect16
= MapSL(lParam
);
1640 rect32
.left
= rect16
->left
;
1641 rect32
.top
= rect16
->top
;
1642 rect32
.right
= rect16
->right
;
1643 rect32
.bottom
= rect16
->bottom
;
1645 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&rect32
);
1647 rect16
->left
= rect32
.left
;
1648 rect16
->top
= rect32
.top
;
1649 rect16
->right
= rect32
.right
;
1650 rect16
->bottom
= rect32
.bottom
;
1653 case WM_WINDOWPOSCHANGING
:
1654 case WM_WINDOWPOSCHANGED
:
1656 WINDOWPOS16
*pos16
= MapSL(lParam
);
1659 pos32
.hwnd
= WIN_Handle32(pos16
->hwnd
);
1660 pos32
.hwndInsertAfter
= WIN_Handle32(pos16
->hwndInsertAfter
);
1663 pos32
.cx
= pos16
->cx
;
1664 pos32
.cy
= pos16
->cy
;
1665 pos32
.flags
= pos16
->flags
;
1667 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&pos32
);
1669 pos16
->hwnd
= HWND_16(pos32
.hwnd
);
1670 pos16
->hwndInsertAfter
= HWND_16(pos32
.hwndInsertAfter
);
1673 pos16
->cx
= pos32
.cx
;
1674 pos16
->cy
= pos32
.cy
;
1675 pos16
->flags
= pos32
.flags
;
1680 return DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)MapSL(lParam
) );
1682 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
1687 /***********************************************************************
1688 * DefDlgProc (USER.308)
1690 LRESULT WINAPI
DefDlgProc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
1693 WINPROC_CallProc16To32A( defdlg_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, 0 );
1698 /***********************************************************************
1699 * PeekMessage (USER.109)
1701 BOOL16 WINAPI
PeekMessage16( MSG16
*msg
, HWND16 hwnd
,
1702 UINT16 first
, UINT16 last
, UINT16 flags
)
1704 return PeekMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, flags
, FALSE
);
1708 /***********************************************************************
1709 * GetMessage32 (USER.820)
1711 BOOL16 WINAPI
GetMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
, UINT16 first
,
1712 UINT16 last
, BOOL16 wHaveParamHigh
)
1716 HWND hwnd
= WIN_Handle32( hwnd16
);
1718 if(USER16_AlertableWait
)
1719 MsgWaitForMultipleObjectsEx( 0, NULL
, INFINITE
, 0, MWMO_ALERTABLE
);
1720 GetMessageA( &msg
, hwnd
, first
, last
);
1721 msg16
->msg
.time
= msg
.time
;
1722 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
1723 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
1724 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
1725 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
1726 &unused
, &msg16
->msg
);
1728 TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
1729 msg16
->msg
.message
, hwnd
, first
, last
);
1731 return msg16
->msg
.message
!= WM_QUIT
;
1735 /***********************************************************************
1736 * GetMessage (USER.108)
1738 BOOL16 WINAPI
GetMessage16( MSG16
*msg
, HWND16 hwnd
, UINT16 first
, UINT16 last
)
1740 return GetMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, FALSE
);
1744 /***********************************************************************
1745 * TranslateMessage32 (USER.821)
1747 BOOL16 WINAPI
TranslateMessage32_16( const MSG32_16
*msg
, BOOL16 wHaveParamHigh
)
1751 msg32
.hwnd
= WIN_Handle32( msg
->msg
.hwnd
);
1752 msg32
.message
= msg
->msg
.message
;
1753 msg32
.wParam
= MAKEWPARAM( msg
->msg
.wParam
, wHaveParamHigh
? msg
->wParamHigh
: 0 );
1754 msg32
.lParam
= msg
->msg
.lParam
;
1755 return TranslateMessage( &msg32
);
1759 /***********************************************************************
1760 * TranslateMessage (USER.113)
1762 BOOL16 WINAPI
TranslateMessage16( const MSG16
*msg
)
1764 return TranslateMessage32_16( (const MSG32_16
*)msg
, FALSE
);
1768 /***********************************************************************
1769 * DispatchMessage (USER.114)
1771 LONG WINAPI
DispatchMessage16( const MSG16
* msg
)
1776 /* Process timer messages */
1777 if ((msg
->message
== WM_TIMER
) || (msg
->message
== WM_SYSTIMER
))
1780 return CallWindowProc16( (WNDPROC16
)msg
->lParam
, msg
->hwnd
,
1781 msg
->message
, msg
->wParam
, GetTickCount() );
1784 if (!(winproc
= (WNDPROC16
)GetWindowLong16( msg
->hwnd
, GWLP_WNDPROC
)))
1786 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
1789 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx\n", msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1790 retval
= CallWindowProc16( winproc
, msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1791 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx returned %08lx\n",
1792 msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
, retval
);
1797 /***********************************************************************
1798 * DispatchMessage32 (USER.822)
1800 LONG WINAPI
DispatchMessage32_16( const MSG32_16
*msg16
, BOOL16 wHaveParamHigh
)
1802 if (wHaveParamHigh
== FALSE
)
1803 return DispatchMessage16( &msg16
->msg
);
1808 msg
.hwnd
= WIN_Handle32( msg16
->msg
.hwnd
);
1809 msg
.message
= msg16
->msg
.message
;
1810 msg
.wParam
= MAKEWPARAM( msg16
->msg
.wParam
, msg16
->wParamHigh
);
1811 msg
.lParam
= msg16
->msg
.lParam
;
1812 msg
.time
= msg16
->msg
.time
;
1813 msg
.pt
.x
= msg16
->msg
.pt
.x
;
1814 msg
.pt
.y
= msg16
->msg
.pt
.y
;
1815 return DispatchMessageA( &msg
);
1820 /***********************************************************************
1821 * IsDialogMessage (USER.90)
1823 BOOL16 WINAPI
IsDialogMessage16( HWND16 hwndDlg
, MSG16
*msg16
)
1828 msg
.hwnd
= WIN_Handle32(msg16
->hwnd
);
1829 hwndDlg32
= WIN_Handle32(hwndDlg
);
1831 switch(msg16
->message
)
1836 msg
.message
= msg16
->message
;
1837 msg
.wParam
= msg16
->wParam
;
1838 msg
.lParam
= msg16
->lParam
;
1839 return IsDialogMessageA( hwndDlg32
, &msg
);
1842 if ((hwndDlg32
!= msg
.hwnd
) && !IsChild( hwndDlg32
, msg
.hwnd
)) return FALSE
;
1843 TranslateMessage16( msg16
);
1844 DispatchMessage16( msg16
);
1849 /***********************************************************************
1850 * MsgWaitForMultipleObjects (USER.640)
1852 DWORD WINAPI
MsgWaitForMultipleObjects16( DWORD count
, CONST HANDLE
*handles
,
1853 BOOL wait_all
, DWORD timeout
, DWORD mask
)
1855 return MsgWaitForMultipleObjectsEx( count
, handles
, timeout
, mask
,
1856 wait_all
? MWMO_WAITALL
: 0 );
1860 /**********************************************************************
1861 * SetDoubleClickTime (USER.20)
1863 void WINAPI
SetDoubleClickTime16( UINT16 interval
)
1865 SetDoubleClickTime( interval
);
1869 /**********************************************************************
1870 * GetDoubleClickTime (USER.21)
1872 UINT16 WINAPI
GetDoubleClickTime16(void)
1874 return GetDoubleClickTime();
1878 /***********************************************************************
1879 * PostQuitMessage (USER.6)
1881 void WINAPI
PostQuitMessage16( INT16 exitCode
)
1883 PostQuitMessage( exitCode
);
1887 /**********************************************************************
1888 * GetKeyState (USER.106)
1890 INT16 WINAPI
GetKeyState16(INT16 vkey
)
1892 return GetKeyState(vkey
);
1896 /**********************************************************************
1897 * GetKeyboardState (USER.222)
1899 BOOL WINAPI
GetKeyboardState16( LPBYTE state
)
1901 return GetKeyboardState( state
);
1905 /**********************************************************************
1906 * SetKeyboardState (USER.223)
1908 BOOL WINAPI
SetKeyboardState16( LPBYTE state
)
1910 return SetKeyboardState( state
);
1914 /***********************************************************************
1915 * SetMessageQueue (USER.266)
1917 BOOL16 WINAPI
SetMessageQueue16( INT16 size
)
1919 return SetMessageQueue( size
);
1923 /***********************************************************************
1924 * UserYield (USER.332)
1926 void WINAPI
UserYield16(void)
1929 PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
| PM_QS_SENDMESSAGE
);
1933 /***********************************************************************
1934 * GetQueueStatus (USER.334)
1936 DWORD WINAPI
GetQueueStatus16( UINT16 flags
)
1938 return GetQueueStatus( flags
);
1942 /***********************************************************************
1943 * GetInputState (USER.335)
1945 BOOL16 WINAPI
GetInputState16(void)
1947 return GetInputState();
1951 /**********************************************************************
1952 * TranslateAccelerator (USER.178)
1954 INT16 WINAPI
TranslateAccelerator16( HWND16 hwnd
, HACCEL16 hAccel
, LPMSG16 msg
)
1959 msg32
.message
= msg
->message
;
1960 /* msg32.hwnd not used */
1961 msg32
.wParam
= msg
->wParam
;
1962 msg32
.lParam
= msg
->lParam
;
1963 return TranslateAcceleratorW( WIN_Handle32(hwnd
), HACCEL_32(hAccel
), &msg32
);
1967 /**********************************************************************
1968 * TranslateMDISysAccel (USER.451)
1970 BOOL16 WINAPI
TranslateMDISysAccel16( HWND16 hwndClient
, LPMSG16 msg
)
1972 if (msg
->message
== WM_KEYDOWN
|| msg
->message
== WM_SYSKEYDOWN
)
1975 msg32
.hwnd
= WIN_Handle32(msg
->hwnd
);
1976 msg32
.message
= msg
->message
;
1977 msg32
.wParam
= msg
->wParam
;
1978 msg32
.lParam
= msg
->lParam
;
1979 /* MDICLIENTINFO is still the same for win32 and win16 ... */
1980 return TranslateMDISysAccel( WIN_Handle32(hwndClient
), &msg32
);
1986 /***********************************************************************
1989 static LRESULT
button_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
1991 static const UINT msg16_offset
= BM_GETCHECK16
- BM_GETCHECK
;
2000 return wow_handlers32
.button_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2002 return wow_handlers32
.button_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2007 /***********************************************************************
2010 static LRESULT
combo_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2012 static const UINT msg16_offset
= CB_GETEDITSEL16
- CB_GETEDITSEL
;
2016 case CB_INSERTSTRING16
:
2017 case CB_SELECTSTRING16
:
2018 case CB_FINDSTRING16
:
2019 case CB_FINDSTRINGEXACT16
:
2020 wParam
= (INT
)(INT16
)wParam
;
2022 case CB_ADDSTRING16
:
2024 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2025 if ((style
& CBS_HASSTRINGS
) || !(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)))
2026 lParam
= (LPARAM
)MapSL(lParam
);
2027 msg
-= msg16_offset
;
2030 case CB_SETITEMHEIGHT16
:
2031 case CB_GETITEMHEIGHT16
:
2032 case CB_SETCURSEL16
:
2033 case CB_GETLBTEXTLEN16
:
2034 case CB_GETITEMDATA16
:
2035 case CB_SETITEMDATA16
:
2036 wParam
= (INT
)(INT16
)wParam
; /* signed integer */
2037 msg
-= msg16_offset
;
2039 case CB_GETDROPPEDCONTROLRECT16
:
2040 lParam
= (LPARAM
)MapSL(lParam
);
2044 RECT16
*r16
= (RECT16
*)lParam
;
2045 wow_handlers32
.combo_proc( hwnd
, CB_GETDROPPEDCONTROLRECT
, wParam
, (LPARAM
)&r
, FALSE
);
2048 r16
->right
= r
.right
;
2049 r16
->bottom
= r
.bottom
;
2053 if (wParam
& DDL_DRIVES
) wParam
|= DDL_EXCLUSIVE
;
2054 lParam
= (LPARAM
)MapSL(lParam
);
2055 msg
-= msg16_offset
;
2057 case CB_GETLBTEXT16
:
2058 wParam
= (INT
)(INT16
)wParam
;
2059 lParam
= (LPARAM
)MapSL(lParam
);
2060 msg
-= msg16_offset
;
2062 case CB_GETEDITSEL16
:
2063 wParam
= lParam
= 0; /* just in case */
2064 msg
-= msg16_offset
;
2066 case CB_LIMITTEXT16
:
2067 case CB_SETEDITSEL16
:
2068 case CB_DELETESTRING16
:
2069 case CB_RESETCONTENT16
:
2070 case CB_GETDROPPEDSTATE16
:
2071 case CB_SHOWDROPDOWN16
:
2073 case CB_GETCURSEL16
:
2074 case CB_SETEXTENDEDUI16
:
2075 case CB_GETEXTENDEDUI16
:
2076 msg
-= msg16_offset
;
2079 return wow_handlers32
.combo_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2081 return wow_handlers32
.combo_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2084 /*********************************************************************
2085 * edit_lock_buffer (internal)
2087 * A 16 bit application might send an EM_GETHANDLE message and expect a HLOCAL16
2088 * (16 bit SEG:OFF handler). From that moment on we have to keep using this
2089 * 16 bit memory handler, because it is supposed to be valid at all times after
2091 * We create a HLOCAL16 buffer in edit_get_handle and copy the text from the
2092 * HLOCAL buffer, when needed
2096 #define GWW_HANDLE16 sizeof(void*)
2098 static void edit_lock_buffer( HWND hwnd
)
2100 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2101 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2106 if (!hloc16
) return;
2107 if (!(hloc32
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return;
2109 oldDS
= stack16
->ds
;
2110 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2111 size
= LocalSize16(hloc16
);
2112 if (LocalReAlloc( hloc32
, size
, LMEM_MOVEABLE
))
2114 char *text
= MapSL( LocalLock16( hloc16
));
2115 char *dest
= LocalLock( hloc32
);
2116 memcpy( dest
, text
, size
);
2117 LocalUnlock( hloc32
);
2118 LocalUnlock16( hloc16
);
2120 stack16
->ds
= oldDS
;
2124 static void edit_unlock_buffer( HWND hwnd
)
2126 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2127 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2132 if (!hloc16
) return;
2133 if (!(hloc32
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return;
2134 size
= LocalSize( hloc32
);
2136 oldDS
= stack16
->ds
;
2137 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2138 if (LocalReAlloc16( hloc16
, size
, LMEM_MOVEABLE
))
2140 char *text
= LocalLock( hloc32
);
2141 char *dest
= MapSL( LocalLock16( hloc16
));
2142 memcpy( dest
, text
, size
);
2143 LocalUnlock( hloc32
);
2144 LocalUnlock16( hloc16
);
2146 stack16
->ds
= oldDS
;
2149 static HLOCAL16
edit_get_handle( HWND hwnd
)
2154 STACK16FRAME
* stack16
;
2156 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2158 if (hloc16
) return hloc16
;
2160 if (!(hloc
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return 0;
2161 alloc_size
= LocalSize( hloc
);
2163 stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2164 oldDS
= stack16
->ds
;
2165 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2167 if (!LocalHeapSize16())
2169 if (!LocalInit16(stack16
->ds
, 0, GlobalSize16(stack16
->ds
)))
2171 ERR("could not initialize local heap\n");
2176 if (!(hloc16
= LocalAlloc16(LMEM_MOVEABLE
| LMEM_ZEROINIT
, alloc_size
)))
2178 ERR("could not allocate new 16 bit buffer\n");
2182 if (!(textA
= MapSL(LocalLock16( hloc16
))))
2184 ERR("could not lock new 16 bit buffer\n");
2185 LocalFree16(hloc16
);
2189 memcpy( textA
, LocalLock( hloc
), alloc_size
);
2190 LocalUnlock( hloc
);
2191 LocalUnlock16( hloc16
);
2192 SetWindowWord( hwnd
, GWW_HANDLE16
, hloc16
);
2195 stack16
->ds
= oldDS
;
2199 static void edit_set_handle( HWND hwnd
, HLOCAL16 hloc16
)
2201 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2202 HINSTANCE16 hInstance
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2203 HANDLE16 oldDS
= stack16
->ds
;
2208 if (!(GetWindowLongW( hwnd
, GWL_STYLE
) & ES_MULTILINE
)) return;
2209 if (!hloc16
) return;
2211 stack16
->ds
= hInstance
;
2212 count
= LocalSize16(hloc16
);
2213 text
= MapSL(LocalLock16(hloc16
));
2214 if ((hloc32
= LocalAlloc(LMEM_MOVEABLE
, count
)))
2216 memcpy( LocalLock(hloc32
), text
, count
);
2217 LocalUnlock(hloc32
);
2218 LocalUnlock16(hloc16
);
2219 SetWindowWord( hwnd
, GWW_HANDLE16
, hloc16
);
2221 stack16
->ds
= oldDS
;
2223 if (hloc32
) wow_handlers32
.edit_proc( hwnd
, EM_SETHANDLE
, (WPARAM
)hloc32
, 0, FALSE
);
2226 static void edit_destroy_handle( HWND hwnd
)
2228 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2231 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2232 HANDLE16 oldDS
= stack16
->ds
;
2234 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2235 while (LocalUnlock16(hloc16
)) ;
2236 LocalFree16(hloc16
);
2237 stack16
->ds
= oldDS
;
2238 SetWindowWord( hwnd
, GWW_HANDLE16
, 0 );
2242 /*********************************************************************
2245 static LRESULT
edit_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2247 static const UINT msg16_offset
= EM_GETSEL16
- EM_GETSEL
;
2250 edit_lock_buffer( hwnd
);
2254 case EM_SCROLLCARET16
:
2255 case EM_GETMODIFY16
:
2256 case EM_SETMODIFY16
:
2257 case EM_GETLINECOUNT16
:
2259 case EM_LINELENGTH16
:
2260 case EM_LIMITTEXT16
:
2264 case EM_LINEFROMCHAR16
:
2265 case EM_SETPASSWORDCHAR16
:
2266 case EM_EMPTYUNDOBUFFER16
:
2267 case EM_SETREADONLY16
:
2268 case EM_GETPASSWORDCHAR16
:
2269 /* these messages missing from specs */
2274 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2277 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, 0, 0, FALSE
);
2279 case EM_REPLACESEL16
:
2281 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)MapSL(lParam
), FALSE
);
2283 case EM_LINESCROLL16
:
2284 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, (INT
)(SHORT
)HIWORD(lParam
),
2285 (INT
)(SHORT
)LOWORD(lParam
), FALSE
);
2287 case EM_LINEINDEX16
:
2288 if ((INT16
)wParam
== -1) wParam
= -1;
2289 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2292 if ((short)LOWORD(lParam
) == -1)
2299 wParam
= LOWORD(lParam
);
2300 lParam
= HIWORD(lParam
);
2302 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2308 RECT16
*r16
= MapSL(lParam
);
2309 wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)&rect
, FALSE
);
2310 r16
->left
= rect
.left
;
2311 r16
->top
= rect
.top
;
2312 r16
->right
= rect
.right
;
2313 r16
->bottom
= rect
.bottom
;
2317 case EM_SETRECTNP16
:
2321 RECT16
*r16
= MapSL(lParam
);
2322 rect
.left
= r16
->left
;
2323 rect
.top
= r16
->top
;
2324 rect
.right
= r16
->right
;
2325 rect
.bottom
= r16
->bottom
;
2326 wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)&rect
, FALSE
);
2329 case EM_SETHANDLE16
:
2330 edit_set_handle( hwnd
, (HLOCAL16
)wParam
);
2332 case EM_GETHANDLE16
:
2333 result
= edit_get_handle( hwnd
);
2335 case EM_SETTABSTOPS16
:
2337 INT16
*tabs16
= MapSL(lParam
);
2338 INT i
, count
= wParam
, *tabs
= NULL
;
2341 if (!(tabs
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*tabs
) ))) return 0;
2342 for (i
= 0; i
< count
; i
++) tabs
[i
] = tabs16
[i
];
2344 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, count
, (LPARAM
)tabs
, FALSE
);
2345 HeapFree( GetProcessHeap(), 0, tabs
);
2348 case EM_GETFIRSTVISIBLELINE16
:
2349 if (!(GetWindowLongW( hwnd
, GWL_STYLE
) & ES_MULTILINE
)) break;
2350 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2352 case EM_SETWORDBREAKPROC16
:
2354 struct word_break_thunk
*thunk
= add_word_break_thunk( (EDITWORDBREAKPROC16
)lParam
);
2355 result
= wow_handlers32
.edit_proc( hwnd
, EM_SETWORDBREAKPROC
, wParam
, (LPARAM
)thunk
, FALSE
);
2358 case EM_GETWORDBREAKPROC16
:
2359 result
= wow_handlers32
.edit_proc( hwnd
, EM_GETWORDBREAKPROC
, wParam
, lParam
, FALSE
);
2360 result
= (LRESULT
)get_word_break_thunk( (EDITWORDBREAKPROCA
)result
);
2363 edit_destroy_handle( hwnd
);
2364 return wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
); /* no unlock on destroy */
2367 if (LOWORD(wParam
) == EM_GETTHUMB16
|| LOWORD(wParam
) == EM_LINESCROLL16
) wParam
-= msg16_offset
;
2368 result
= wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2371 result
= wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2374 edit_unlock_buffer( hwnd
);
2379 /***********************************************************************
2382 static LRESULT
listbox_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2384 static const UINT msg16_offset
= LB_ADDSTRING16
- LB_ADDSTRING
;
2390 if (is_old_app( hwnd
))
2392 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2393 int height
, remaining
, item_height
;
2396 /* give a margin for error to old 16 bits programs - if we need
2397 less than the height of the nonclient area, round to the
2398 *next* number of items */
2400 if (!(style
& LBS_NOINTEGRALHEIGHT
) && !(style
& LBS_OWNERDRAWVARIABLE
))
2402 GetClientRect( hwnd
, &rect
);
2403 height
= rect
.bottom
- rect
.top
;
2404 item_height
= wow_handlers32
.listbox_proc( hwnd
, LB_GETITEMHEIGHT
, 0, 0, FALSE
);
2405 remaining
= item_height
? (height
% item_height
) : 0;
2406 if ((height
> item_height
) && remaining
)
2408 GetWindowRect( hwnd
, &rect
);
2409 if ((item_height
- remaining
) <= rect
.bottom
- rect
.top
- height
)
2410 remaining
= remaining
- item_height
;
2411 TRACE( "[%p]: changing height %d -> %d\n", hwnd
, height
, height
- remaining
);
2412 SetWindowPos( hwnd
, 0, 0, 0, rect
.right
- rect
.left
,
2413 rect
.bottom
- rect
.top
- remaining
,
2414 SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOMOVE
);
2419 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2421 case LB_RESETCONTENT16
:
2422 case LB_DELETESTRING16
:
2423 case LB_GETITEMDATA16
:
2424 case LB_SETITEMDATA16
:
2426 case LB_GETTEXTLEN16
:
2427 case LB_GETCURSEL16
:
2428 case LB_GETTOPINDEX16
:
2429 case LB_GETITEMHEIGHT16
:
2430 case LB_SETCARETINDEX16
:
2431 case LB_GETCARETINDEX16
:
2432 case LB_SETTOPINDEX16
:
2433 case LB_SETCOLUMNWIDTH16
:
2434 case LB_GETSELCOUNT16
:
2435 case LB_SELITEMRANGE16
:
2436 case LB_SELITEMRANGEEX16
:
2437 case LB_GETHORIZONTALEXTENT16
:
2438 case LB_SETHORIZONTALEXTENT16
:
2439 case LB_GETANCHORINDEX16
:
2442 msg
-= msg16_offset
;
2446 case LB_SETCURSEL16
:
2447 case LB_SETANCHORINDEX16
:
2448 wParam
= (INT
)(INT16
)wParam
;
2449 msg
-= msg16_offset
;
2451 case LB_INSERTSTRING16
:
2452 case LB_FINDSTRING16
:
2453 case LB_FINDSTRINGEXACT16
:
2454 case LB_SELECTSTRING16
:
2455 wParam
= (INT
)(INT16
)wParam
;
2457 case LB_ADDSTRING16
:
2460 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2461 if ((style
& LBS_HASSTRINGS
) || !(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)))
2462 lParam
= (LPARAM
)MapSL(lParam
);
2463 msg
-= msg16_offset
;
2467 lParam
= (LPARAM
)MapSL(lParam
);
2468 msg
-= msg16_offset
;
2470 case LB_SETITEMHEIGHT16
:
2471 lParam
= LOWORD(lParam
);
2472 msg
-= msg16_offset
;
2474 case LB_GETITEMRECT16
:
2477 RECT16
*r16
= MapSL(lParam
);
2478 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_GETITEMRECT
, (INT16
)wParam
, (LPARAM
)&rect
, FALSE
);
2479 r16
->left
= rect
.left
;
2480 r16
->top
= rect
.top
;
2481 r16
->right
= rect
.right
;
2482 r16
->bottom
= rect
.bottom
;
2485 case LB_GETSELITEMS16
:
2487 INT16
*array16
= MapSL( lParam
);
2488 INT i
, count
= (INT16
)wParam
, *array
;
2489 if (!(array
= HeapAlloc( GetProcessHeap(), 0, wParam
* sizeof(*array
) ))) return LB_ERRSPACE
;
2490 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_GETSELITEMS
, count
, (LPARAM
)array
, FALSE
);
2491 for (i
= 0; i
< ret
; i
++) array16
[i
] = array
[i
];
2492 HeapFree( GetProcessHeap(), 0, array
);
2496 /* according to Win16 docs, DDL_DRIVES should make DDL_EXCLUSIVE
2497 * be set automatically (this is different in Win32) */
2498 if (wParam
& DDL_DRIVES
) wParam
|= DDL_EXCLUSIVE
;
2499 lParam
= (LPARAM
)MapSL(lParam
);
2500 msg
-= msg16_offset
;
2502 case LB_SETTABSTOPS16
:
2504 INT i
, count
, *tabs
= NULL
;
2505 INT16
*tabs16
= MapSL( lParam
);
2507 if ((count
= (INT16
)wParam
) > 0)
2509 if (!(tabs
= HeapAlloc( GetProcessHeap(), 0, wParam
* sizeof(*tabs
) ))) return LB_ERRSPACE
;
2510 for (i
= 0; i
< count
; i
++) tabs
[i
] = tabs16
[i
] << 1; /* FIXME */
2512 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_SETTABSTOPS
, count
, (LPARAM
)tabs
, FALSE
);
2513 HeapFree( GetProcessHeap(), 0, tabs
);
2517 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2519 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2523 /***********************************************************************
2526 static LRESULT
mdiclient_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2528 if (msg
== WM_CREATE
)
2530 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
2531 HINSTANCE instance
= (HINSTANCE
)GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2532 BOOL is_win32
= !instance
|| ((ULONG_PTR
)instance
>> 16);
2534 /* Translation layer doesn't know what's in the cs->lpCreateParams
2535 * so we have to keep track of what environment we're in. */
2538 void *orig
= cs
->lpCreateParams
;
2540 CLIENTCREATESTRUCT ccs
;
2541 CLIENTCREATESTRUCT16
*ccs16
= MapSL( PtrToUlong( orig
));
2543 ccs
.hWindowMenu
= HMENU_32(ccs16
->hWindowMenu
);
2544 ccs
.idFirstChild
= ccs16
->idFirstChild
;
2545 cs
->lpCreateParams
= &ccs
;
2546 ret
= wow_handlers32
.mdiclient_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2547 cs
->lpCreateParams
= orig
;
2551 return wow_handlers32
.mdiclient_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2555 /***********************************************************************
2558 static LRESULT
scrollbar_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2560 static const UINT msg16_offset
= SBM_SETPOS16
- SBM_SETPOS
;
2566 case SBM_ENABLE_ARROWS16
:
2567 msg
-= msg16_offset
;
2569 case SBM_SETRANGE16
:
2570 msg
= wParam
? SBM_SETRANGEREDRAW
: SBM_SETRANGE
;
2571 wParam
= LOWORD(lParam
);
2572 lParam
= HIWORD(lParam
);
2574 case SBM_GETRANGE16
:
2577 wow_handlers32
.scrollbar_proc( hwnd
, SBM_GETRANGE
, (WPARAM
)&min
, (LPARAM
)&max
, FALSE
);
2578 return MAKELRESULT(min
, max
);
2581 return wow_handlers32
.scrollbar_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2583 return wow_handlers32
.scrollbar_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2587 /***********************************************************************
2590 static LRESULT
static_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2596 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
2597 LRESULT ret
= wow_handlers32
.static_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2600 if (((ULONG_PTR
)cs
->hInstance
>> 16)) return ret
; /* 32-bit instance, nothing to do */
2601 switch (cs
->style
& SS_TYPEMASK
)
2605 HICON16 icon
= LoadIcon16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2606 if (!icon
) icon
= LoadCursor16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2607 if (icon
) wow_handlers32
.static_proc( hwnd
, STM_SETIMAGE
, IMAGE_ICON
,
2608 (LPARAM
)get_icon_32(icon
), FALSE
);
2613 HBITMAP16 bitmap
= LoadBitmap16( HINSTANCE_16(cs
->hInstance
), cs
->lpszName
);
2614 if (bitmap
) wow_handlers32
.static_proc( hwnd
, STM_SETIMAGE
, IMAGE_BITMAP
,
2615 (LPARAM
)HBITMAP_32(bitmap
), FALSE
);
2622 wParam
= (WPARAM
)get_icon_32( (HICON16
)wParam
);
2623 return wow_handlers32
.static_proc( hwnd
, STM_SETICON
, wParam
, lParam
, FALSE
);
2625 return get_icon_16( (HICON
)wow_handlers32
.static_proc( hwnd
, STM_GETICON
, wParam
, lParam
, FALSE
));
2627 return wow_handlers32
.static_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2632 /***********************************************************************
2635 static DWORD
wait_message16( DWORD count
, CONST HANDLE
*handles
, DWORD timeout
, DWORD mask
, DWORD flags
)
2639 ReleaseThunkLock( &lock
);
2640 ret
= wow_handlers32
.wait_message( count
, handles
, timeout
, mask
, flags
);
2641 RestoreThunkLock( lock
);
2646 /***********************************************************************
2649 HWND
create_window16( CREATESTRUCTW
*cs
, LPCWSTR className
, HINSTANCE instance
, BOOL unicode
)
2651 /* map to module handle */
2652 if (instance
&& !((ULONG_PTR
)instance
>> 16))
2653 instance
= HINSTANCE_32( GetExePtr( HINSTANCE_16(instance
) ));
2655 return wow_handlers32
.create_window( cs
, className
, instance
, unicode
);
2659 /***********************************************************************
2662 static void free_icon_param( ULONG_PTR param
)
2664 GlobalFree16( LOWORD(param
) );
2668 void register_wow_handlers(void)
2670 static const struct wow_handlers16 handlers16
=
2681 call_window_proc_Ato16
,
2682 call_dialog_proc_Ato16
,
2686 UserRegisterWowHandlers( &handlers16
, &wow_handlers32
);