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"
33 #include "user_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msg
);
38 WINE_DECLARE_DEBUG_CHANNEL(message
);
40 DWORD USER16_AlertableWait
= 0;
42 struct wow_handlers32 wow_handlers32
;
44 static LRESULT
cwp_hook_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
45 LRESULT
*result
, void *arg
)
54 return HOOK_CallHooks( WH_CALLWNDPROC
, HC_ACTION
, 1, (LPARAM
)&cwp
, FALSE
);
57 static LRESULT
send_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
58 LRESULT
*result
, void *arg
)
60 *result
= SendMessageA( hwnd
, msg
, wp
, lp
);
64 static LRESULT
post_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
65 LRESULT
*result
, void *arg
)
68 return PostMessageA( hwnd
, msg
, wp
, lp
);
71 static LRESULT
post_thread_message_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
72 LRESULT
*result
, void *arg
)
74 DWORD_PTR tid
= (DWORD_PTR
)arg
;
76 return PostThreadMessageA( tid
, msg
, wp
, lp
);
79 static LRESULT
get_message_callback( HWND16 hwnd
, UINT16 msg
, WPARAM16 wp
, LPARAM lp
,
80 LRESULT
*result
, void *arg
)
92 static LRESULT
defdlg_proc_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
93 LRESULT
*result
, void *arg
)
95 *result
= DefDlgProcA( hwnd
, msg
, wp
, lp
);
99 static LRESULT
call_window_proc_callback( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
100 LRESULT
*result
, void *arg
)
103 *result
= CallWindowProcA( proc
, hwnd
, msg
, wp
, lp
);
108 /**********************************************************************
109 * Support for window procedure thunks
112 #include "pshpack1.h"
115 BYTE popl_eax
; /* popl %eax (return address) */
116 BYTE pushl_func
; /* pushl $proc */
118 BYTE pushl_eax
; /* pushl %eax */
119 BYTE ljmp
; /* ljmp relay*/
120 DWORD relay_offset
; /* __wine_call_wndproc */
125 #define WINPROC_HANDLE (~0u >> 16)
126 #define MAX_WINPROCS32 4096
127 #define MAX_WINPROCS16 1024
129 static WNDPROC16 winproc16_array
[MAX_WINPROCS16
];
130 static unsigned int winproc16_used
;
132 static WINPROC_THUNK
*thunk_array
;
133 static UINT thunk_selector
;
135 /* return the window proc index for a given handle, or -1 for an invalid handle
136 * indices 0 .. MAX_WINPROCS32-1 are for 32-bit procs,
137 * indices MAX_WINPROCS32 .. MAX_WINPROCS32+MAX_WINPROCS16-1 for 16-bit procs */
138 static int winproc_to_index( WNDPROC16 handle
)
142 if (HIWORD(handle
) == thunk_selector
)
144 index
= LOWORD(handle
) / sizeof(WINPROC_THUNK
);
145 /* check alignment */
146 if (index
* sizeof(WINPROC_THUNK
) != LOWORD(handle
)) return -1;
147 /* check array limits */
148 if (index
>= MAX_WINPROCS32
) return -1;
152 index
= LOWORD(handle
);
153 if ((ULONG_PTR
)handle
>> 16 != WINPROC_HANDLE
) return -1;
154 /* check array limits */
155 if (index
>= winproc16_used
+ MAX_WINPROCS32
) return -1;
160 /* allocate a 16-bit thunk for an existing window proc */
161 static WNDPROC16
alloc_win16_thunk( WNDPROC handle
)
163 static FARPROC16 relay
;
164 WINPROC_THUNK
*thunk
;
165 UINT index
= LOWORD( handle
);
167 if (index
>= MAX_WINPROCS32
) /* already a 16-bit proc */
168 return winproc16_array
[index
- MAX_WINPROCS32
];
170 if (!thunk_array
) /* allocate the array and its selector */
174 assert( MAX_WINPROCS16
* sizeof(WINPROC_THUNK
) <= 0x10000 );
176 if (!(thunk_selector
= wine_ldt_alloc_entries(1))) return NULL
;
177 if (!(thunk_array
= VirtualAlloc( NULL
, MAX_WINPROCS16
* sizeof(WINPROC_THUNK
), MEM_COMMIT
,
178 PAGE_EXECUTE_READWRITE
))) return NULL
;
179 wine_ldt_set_base( &entry
, thunk_array
);
180 wine_ldt_set_limit( &entry
, MAX_WINPROCS16
* sizeof(WINPROC_THUNK
) - 1 );
181 wine_ldt_set_flags( &entry
, WINE_LDT_FLAGS_CODE
| WINE_LDT_FLAGS_32BIT
);
182 wine_ldt_set_entry( thunk_selector
, &entry
);
183 relay
= GetProcAddress16( GetModuleHandle16("user"), "__wine_call_wndproc" );
186 thunk
= &thunk_array
[index
];
187 thunk
->popl_eax
= 0x58; /* popl %eax */
188 thunk
->pushl_func
= 0x68; /* pushl $proc */
189 thunk
->proc
= handle
;
190 thunk
->pushl_eax
= 0x50; /* pushl %eax */
191 thunk
->ljmp
= 0xea; /* ljmp relay*/
192 thunk
->relay_offset
= OFFSETOF(relay
);
193 thunk
->relay_sel
= SELECTOROF(relay
);
194 return (WNDPROC16
)MAKESEGPTR( thunk_selector
, index
* sizeof(WINPROC_THUNK
) );
197 /**********************************************************************
198 * WINPROC_AllocProc16
200 WNDPROC
WINPROC_AllocProc16( WNDPROC16 func
)
205 if (!func
) return NULL
;
207 /* check if the function is already a win proc */
208 if ((index
= winproc_to_index( func
)) != -1)
209 return (WNDPROC
)(ULONG_PTR
)(index
| (WINPROC_HANDLE
<< 16));
211 /* then check if we already have a winproc for that function */
212 for (index
= 0; index
< winproc16_used
; index
++)
213 if (winproc16_array
[index
] == func
) goto done
;
215 if (winproc16_used
>= MAX_WINPROCS16
)
217 FIXME( "too many winprocs, cannot allocate one for 16-bit %p\n", func
);
220 winproc16_array
[winproc16_used
++] = func
;
223 ret
= (WNDPROC
)(ULONG_PTR
)((index
+ MAX_WINPROCS32
) | (WINPROC_HANDLE
<< 16));
224 TRACE( "returning %p for %p/16-bit (%d/%d used)\n",
225 ret
, func
, winproc16_used
, MAX_WINPROCS16
);
229 /**********************************************************************
232 * Get a window procedure pointer that can be passed to the Windows program.
234 WNDPROC16
WINPROC_GetProc16( WNDPROC proc
, BOOL unicode
)
236 WNDPROC winproc
= wow_handlers32
.alloc_winproc( proc
, unicode
);
238 if ((ULONG_PTR
)winproc
>> 16 != WINPROC_HANDLE
) return (WNDPROC16
)winproc
;
239 return alloc_win16_thunk( winproc
);
242 /* call a 16-bit window procedure */
243 static LRESULT
call_window_proc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
244 LRESULT
*result
, void *arg
)
246 WNDPROC16 func
= arg
;
247 int index
= winproc_to_index( func
);
256 DRAWITEMSTRUCT16 dis16
;
257 COMPAREITEMSTRUCT16 cis16
;
261 if (index
>= MAX_WINPROCS32
) func
= winproc16_array
[index
- MAX_WINPROCS32
];
263 /* Window procedures want ax = hInstance, ds = es = ss */
265 memset(&context
, 0, sizeof(context
));
266 context
.SegDs
= context
.SegEs
= SELECTOROF(NtCurrentTeb()->WOW32Reserved
);
267 context
.SegFs
= wine_get_fs();
268 context
.SegGs
= wine_get_gs();
269 if (!(context
.Eax
= GetWindowWord( HWND_32(hwnd
), GWLP_HINSTANCE
))) context
.Eax
= context
.SegDs
;
270 context
.SegCs
= SELECTOROF(func
);
271 context
.Eip
= OFFSETOF(func
);
272 context
.Ebp
= OFFSETOF(NtCurrentTeb()->WOW32Reserved
) + FIELD_OFFSET(STACK16FRAME
, bp
);
276 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
277 work if structures passed in lParam are placed in the stack/data
278 segment. Programmers easily make the mistake of converting lParam
279 to a near rather than a far pointer, since Windows apparently
280 allows this. We copy the structures to the 16 bit stack; this is
281 ugly but makes these programs work. */
286 size
= sizeof(CREATESTRUCT16
); break;
288 size
= sizeof(DRAWITEMSTRUCT16
); break;
290 size
= sizeof(COMPAREITEMSTRUCT16
); break;
294 memcpy( &args
.u
, MapSL(lParam
), size
);
295 lParam
= PtrToUlong(NtCurrentTeb()->WOW32Reserved
) - size
;
299 args
.params
[4] = hwnd
;
300 args
.params
[3] = msg
;
301 args
.params
[2] = wParam
;
302 args
.params
[1] = HIWORD(lParam
);
303 args
.params
[0] = LOWORD(lParam
);
304 WOWCallback16Ex( 0, WCB16_REGS
, sizeof(args
.params
) + size
, &args
, (DWORD
*)&context
);
305 *result
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
309 static LRESULT
call_dialog_proc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wp
, LPARAM lp
,
310 LRESULT
*result
, void *arg
)
312 LRESULT ret
= call_window_proc16( hwnd
, msg
, wp
, lp
, result
, arg
);
313 *result
= GetWindowLongPtrW( WIN_Handle32(hwnd
), DWLP_MSGRESULT
);
317 static LRESULT
call_window_proc_Ato16( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
318 LRESULT
*result
, void *arg
)
320 return WINPROC_CallProc32ATo16( call_window_proc16
, hwnd
, msg
, wp
, lp
, result
, arg
);
323 static LRESULT
call_dialog_proc_Ato16( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
,
324 LRESULT
*result
, void *arg
)
326 return WINPROC_CallProc32ATo16( call_dialog_proc16
, hwnd
, msg
, wp
, lp
, result
, arg
);
331 /**********************************************************************
332 * Support for Edit word break proc thunks
335 #define MAX_THUNKS 32
337 #include <pshpack1.h>
338 static struct word_break_thunk
340 BYTE popl_eax
; /* popl %eax (return address) */
341 BYTE pushl_proc16
; /* pushl proc16 */
342 EDITWORDBREAKPROC16 proc16
;
343 BYTE pushl_eax
; /* pushl %eax */
344 BYTE jmp
; /* ljmp call_word_break_proc16 */
346 } *word_break_thunks
;
349 /**********************************************************************
350 * call_word_break_proc16
352 static INT16 CALLBACK
call_word_break_proc16( SEGPTR proc16
, LPSTR text
, INT index
, INT count
, INT action
)
358 segptr
= MapLS( text
);
359 args
[4] = SELECTOROF(segptr
);
360 args
[3] = OFFSETOF(segptr
);
364 WOWCallback16Ex( proc16
, WCB16_PASCAL
, sizeof(args
), args
, &result
);
366 return LOWORD(result
);
369 /******************************************************************
370 * add_word_break_thunk
372 static struct word_break_thunk
*add_word_break_thunk( EDITWORDBREAKPROC16 proc16
)
374 struct word_break_thunk
*thunk
;
376 if (!word_break_thunks
)
378 word_break_thunks
= VirtualAlloc( NULL
, MAX_THUNKS
* sizeof(*thunk
),
379 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
380 if (!word_break_thunks
) return NULL
;
382 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
384 thunk
->popl_eax
= 0x58; /* popl %eax */
385 thunk
->pushl_proc16
= 0x68; /* pushl proc16 */
386 thunk
->pushl_eax
= 0x50; /* pushl %eax */
387 thunk
->jmp
= 0xe9; /* jmp call_word_break_proc16 */
388 thunk
->callback
= (char *)call_word_break_proc16
- (char *)(&thunk
->callback
+ 1);
391 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
392 if (thunk
->proc16
== proc16
) return thunk
;
394 for (thunk
= word_break_thunks
; thunk
< &word_break_thunks
[MAX_THUNKS
]; thunk
++)
396 if (thunk
->proc16
) continue;
397 thunk
->proc16
= proc16
;
400 FIXME("Out of word break thunks\n");
404 /******************************************************************
405 * get_word_break_thunk
407 static EDITWORDBREAKPROC16
get_word_break_thunk( EDITWORDBREAKPROCA proc
)
409 struct word_break_thunk
*thunk
= (struct word_break_thunk
*)proc
;
410 if (word_break_thunks
&& thunk
>= word_break_thunks
&& thunk
< &word_break_thunks
[MAX_THUNKS
])
411 return thunk
->proc16
;
416 /***********************************************************************
417 * Support for 16<->32 message mapping
420 static inline void *get_buffer( void *static_buffer
, size_t size
, size_t need
)
422 if (size
>= need
) return static_buffer
;
423 return HeapAlloc( GetProcessHeap(), 0, need
);
426 static inline void free_buffer( void *static_buffer
, void *buffer
)
428 if (buffer
!= static_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
431 static void RECT16to32( const RECT16
*from
, RECT
*to
)
433 to
->left
= from
->left
;
435 to
->right
= from
->right
;
436 to
->bottom
= from
->bottom
;
439 static void RECT32to16( const RECT
*from
, RECT16
*to
)
441 to
->left
= from
->left
;
443 to
->right
= from
->right
;
444 to
->bottom
= from
->bottom
;
447 static void MINMAXINFO32to16( const MINMAXINFO
*from
, MINMAXINFO16
*to
)
449 to
->ptReserved
.x
= from
->ptReserved
.x
;
450 to
->ptReserved
.y
= from
->ptReserved
.y
;
451 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
452 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
453 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
454 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
455 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
456 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
457 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
458 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
461 static void MINMAXINFO16to32( const MINMAXINFO16
*from
, MINMAXINFO
*to
)
463 to
->ptReserved
.x
= from
->ptReserved
.x
;
464 to
->ptReserved
.y
= from
->ptReserved
.y
;
465 to
->ptMaxSize
.x
= from
->ptMaxSize
.x
;
466 to
->ptMaxSize
.y
= from
->ptMaxSize
.y
;
467 to
->ptMaxPosition
.x
= from
->ptMaxPosition
.x
;
468 to
->ptMaxPosition
.y
= from
->ptMaxPosition
.y
;
469 to
->ptMinTrackSize
.x
= from
->ptMinTrackSize
.x
;
470 to
->ptMinTrackSize
.y
= from
->ptMinTrackSize
.y
;
471 to
->ptMaxTrackSize
.x
= from
->ptMaxTrackSize
.x
;
472 to
->ptMaxTrackSize
.y
= from
->ptMaxTrackSize
.y
;
475 static void WINDOWPOS32to16( const WINDOWPOS
* from
, WINDOWPOS16
* to
)
477 to
->hwnd
= HWND_16(from
->hwnd
);
478 to
->hwndInsertAfter
= HWND_16(from
->hwndInsertAfter
);
483 to
->flags
= from
->flags
;
486 static void WINDOWPOS16to32( const WINDOWPOS16
* from
, WINDOWPOS
* to
)
488 to
->hwnd
= WIN_Handle32(from
->hwnd
);
489 to
->hwndInsertAfter
= (from
->hwndInsertAfter
== (HWND16
)-1) ?
490 HWND_TOPMOST
: WIN_Handle32(from
->hwndInsertAfter
);
495 to
->flags
= from
->flags
;
498 /* The strings are not copied */
499 static void CREATESTRUCT32Ato16( const CREATESTRUCTA
* from
, CREATESTRUCT16
* to
)
501 to
->lpCreateParams
= (SEGPTR
)from
->lpCreateParams
;
502 to
->hInstance
= HINSTANCE_16(from
->hInstance
);
503 to
->hMenu
= HMENU_16(from
->hMenu
);
504 to
->hwndParent
= HWND_16(from
->hwndParent
);
509 to
->style
= from
->style
;
510 to
->dwExStyle
= from
->dwExStyle
;
513 static void CREATESTRUCT16to32A( const CREATESTRUCT16
* from
, CREATESTRUCTA
*to
)
516 to
->lpCreateParams
= (LPVOID
)from
->lpCreateParams
;
517 to
->hInstance
= HINSTANCE_32(from
->hInstance
);
518 to
->hMenu
= HMENU_32(from
->hMenu
);
519 to
->hwndParent
= WIN_Handle32(from
->hwndParent
);
524 to
->style
= from
->style
;
525 to
->dwExStyle
= from
->dwExStyle
;
526 to
->lpszName
= MapSL(from
->lpszName
);
527 to
->lpszClass
= MapSL(from
->lpszClass
);
530 /* The strings are not copied */
531 static void MDICREATESTRUCT32Ato16( const MDICREATESTRUCTA
* from
, MDICREATESTRUCT16
* to
)
533 to
->hOwner
= HINSTANCE_16(from
->hOwner
);
538 to
->style
= from
->style
;
539 to
->lParam
= from
->lParam
;
542 static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16
* from
, MDICREATESTRUCTA
*to
)
544 to
->hOwner
= HINSTANCE_32(from
->hOwner
);
549 to
->style
= from
->style
;
550 to
->lParam
= from
->lParam
;
551 to
->szTitle
= MapSL(from
->szTitle
);
552 to
->szClass
= MapSL(from
->szClass
);
555 static UINT_PTR
convert_handle_16_to_32(HANDLE16 src
, unsigned int flags
)
558 UINT sz
= GlobalSize16(src
);
561 if (!(dst
= GlobalAlloc(flags
, sz
)))
563 ptr16
= GlobalLock16(src
);
564 ptr32
= GlobalLock(dst
);
565 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr32
, ptr16
, sz
);
569 return (UINT_PTR
)dst
;
572 static HANDLE16
convert_handle_32_to_16(UINT_PTR src
, unsigned int flags
)
575 UINT sz
= GlobalSize((HANDLE
)src
);
578 if (!(dst
= GlobalAlloc16(flags
, sz
)))
580 ptr32
= GlobalLock((HANDLE
)src
);
581 ptr16
= GlobalLock16(dst
);
582 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr16
, ptr32
, sz
);
583 GlobalUnlock((HANDLE
)src
);
589 static int find_sub_menu( HMENU
*hmenu
, HMENU16 target
)
591 int i
, pos
, count
= GetMenuItemCount( *hmenu
);
593 for (i
= 0; i
< count
; i
++)
595 HMENU sub
= GetSubMenu( *hmenu
, i
);
597 if (HMENU_16(sub
) == target
) return i
;
598 if ((pos
= find_sub_menu( &sub
, target
)) != -1)
607 /**********************************************************************
608 * WINPROC_CallProc16To32A
610 LRESULT
WINPROC_CallProc16To32A( winproc_callback_t callback
, HWND16 hwnd
, UINT16 msg
,
611 WPARAM16 wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
614 HWND hwnd32
= WIN_Handle32( hwnd
);
621 CREATESTRUCT16
*cs16
= MapSL(lParam
);
623 MDICREATESTRUCTA mdi_cs
;
625 CREATESTRUCT16to32A( cs16
, &cs
);
626 if (GetWindowLongW(hwnd32
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
628 MDICREATESTRUCT16
*mdi_cs16
= MapSL(cs16
->lpCreateParams
);
629 MDICREATESTRUCT16to32A(mdi_cs16
, &mdi_cs
);
630 cs
.lpCreateParams
= &mdi_cs
;
632 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cs
, result
, arg
);
633 CREATESTRUCT32Ato16( &cs
, cs16
);
638 MDICREATESTRUCT16
*cs16
= MapSL(lParam
);
641 MDICREATESTRUCT16to32A( cs16
, &cs
);
642 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cs
, result
, arg
);
643 MDICREATESTRUCT32Ato16( &cs
, cs16
);
648 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32( HIWORD(lParam
) ),
649 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
650 else /* message sent to MDI client */
651 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
653 case WM_MDIGETACTIVE
:
655 BOOL maximized
= FALSE
;
656 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&maximized
, result
, arg
);
657 *result
= MAKELRESULT( LOWORD(*result
), maximized
);
661 ret
= callback( hwnd32
, wParam
? WM_MDIREFRESHMENU
: WM_MDISETMENU
,
662 (WPARAM
)HMENU_32(LOWORD(lParam
)), (LPARAM
)HMENU_32(HIWORD(lParam
)),
665 case WM_GETMINMAXINFO
:
667 MINMAXINFO16
*mmi16
= MapSL(lParam
);
670 MINMAXINFO16to32( mmi16
, &mmi
);
671 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&mmi
, result
, arg
);
672 MINMAXINFO32to16( &mmi
, mmi16
);
675 case WM_WINDOWPOSCHANGING
:
676 case WM_WINDOWPOSCHANGED
:
678 WINDOWPOS16
*winpos16
= MapSL(lParam
);
681 WINDOWPOS16to32( winpos16
, &winpos
);
682 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&winpos
, result
, arg
);
683 WINDOWPOS32to16( &winpos
, winpos16
);
688 NCCALCSIZE_PARAMS16
*nc16
= MapSL(lParam
);
689 NCCALCSIZE_PARAMS nc
;
692 RECT16to32( &nc16
->rgrc
[0], &nc
.rgrc
[0] );
695 RECT16to32( &nc16
->rgrc
[1], &nc
.rgrc
[1] );
696 RECT16to32( &nc16
->rgrc
[2], &nc
.rgrc
[2] );
697 WINDOWPOS16to32( MapSL(nc16
->lppos
), &winpos
);
700 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&nc
, result
, arg
);
701 RECT32to16( &nc
.rgrc
[0], &nc16
->rgrc
[0] );
704 RECT32to16( &nc
.rgrc
[1], &nc16
->rgrc
[1] );
705 RECT32to16( &nc
.rgrc
[2], &nc16
->rgrc
[2] );
706 WINDOWPOS32to16( &winpos
, MapSL(nc16
->lppos
) );
712 COMPAREITEMSTRUCT16
* cis16
= MapSL(lParam
);
713 COMPAREITEMSTRUCT cis
;
714 cis
.CtlType
= cis16
->CtlType
;
715 cis
.CtlID
= cis16
->CtlID
;
716 cis
.hwndItem
= WIN_Handle32( cis16
->hwndItem
);
717 cis
.itemID1
= cis16
->itemID1
;
718 cis
.itemData1
= cis16
->itemData1
;
719 cis
.itemID2
= cis16
->itemID2
;
720 cis
.itemData2
= cis16
->itemData2
;
721 cis
.dwLocaleId
= 0; /* FIXME */
722 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cis
, result
, arg
);
727 DELETEITEMSTRUCT16
* dis16
= MapSL(lParam
);
728 DELETEITEMSTRUCT dis
;
729 dis
.CtlType
= dis16
->CtlType
;
730 dis
.CtlID
= dis16
->CtlID
;
731 dis
.hwndItem
= WIN_Handle32( dis16
->hwndItem
);
732 dis
.itemData
= dis16
->itemData
;
733 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&dis
, result
, arg
);
738 MEASUREITEMSTRUCT16
* mis16
= MapSL(lParam
);
739 MEASUREITEMSTRUCT mis
;
740 mis
.CtlType
= mis16
->CtlType
;
741 mis
.CtlID
= mis16
->CtlID
;
742 mis
.itemID
= mis16
->itemID
;
743 mis
.itemWidth
= mis16
->itemWidth
;
744 mis
.itemHeight
= mis16
->itemHeight
;
745 mis
.itemData
= mis16
->itemData
;
746 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&mis
, result
, arg
);
747 mis16
->itemWidth
= (UINT16
)mis
.itemWidth
;
748 mis16
->itemHeight
= (UINT16
)mis
.itemHeight
;
753 DRAWITEMSTRUCT16
* dis16
= MapSL(lParam
);
755 dis
.CtlType
= dis16
->CtlType
;
756 dis
.CtlID
= dis16
->CtlID
;
757 dis
.itemID
= dis16
->itemID
;
758 dis
.itemAction
= dis16
->itemAction
;
759 dis
.itemState
= dis16
->itemState
;
760 dis
.hwndItem
= (dis
.CtlType
== ODT_MENU
) ? (HWND
)HMENU_32(dis16
->hwndItem
)
761 : WIN_Handle32( dis16
->hwndItem
);
762 dis
.hDC
= HDC_32(dis16
->hDC
);
763 dis
.itemData
= dis16
->itemData
;
764 dis
.rcItem
.left
= dis16
->rcItem
.left
;
765 dis
.rcItem
.top
= dis16
->rcItem
.top
;
766 dis
.rcItem
.right
= dis16
->rcItem
.right
;
767 dis
.rcItem
.bottom
= dis16
->rcItem
.bottom
;
768 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&dis
, result
, arg
);
773 COPYDATASTRUCT16
*cds16
= MapSL(lParam
);
775 cds
.dwData
= cds16
->dwData
;
776 cds
.cbData
= cds16
->cbData
;
777 cds
.lpData
= MapSL(cds16
->lpData
);
778 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&cds
, result
, arg
);
784 MSG16
*msg16
= MapSL(lParam
);
786 msg32
.hwnd
= WIN_Handle32( msg16
->hwnd
);
787 msg32
.message
= msg16
->message
;
788 msg32
.wParam
= msg16
->wParam
;
789 msg32
.lParam
= msg16
->lParam
;
790 msg32
.time
= msg16
->time
;
791 msg32
.pt
.x
= msg16
->pt
.x
;
792 msg32
.pt
.y
= msg16
->pt
.y
;
793 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&msg32
, result
, arg
);
796 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
801 next
.hmenuIn
= (HMENU
)lParam
;
804 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)&next
, result
, arg
);
805 *result
= MAKELONG( HMENU_16(next
.hmenuNext
), HWND_16(next
.hwndNext
) );
812 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, HIWORD(lParam
) ),
813 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
817 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
818 (LPARAM
)WIN_Handle32( HIWORD(lParam
) ), result
, arg
);
821 if (HIWORD(lParam
) <= CTLCOLOR_STATIC
)
822 ret
= callback( hwnd32
, WM_CTLCOLORMSGBOX
+ HIWORD(lParam
),
823 (WPARAM
)HDC_32(wParam
), (LPARAM
)WIN_Handle32( LOWORD(lParam
) ),
828 case WM_WININICHANGE
:
829 case WM_DEVMODECHANGE
:
830 case WM_ASKCBFORMATNAME
:
832 ret
= callback( hwnd32
, msg
, wParam
, (LPARAM
)MapSL(lParam
), result
, arg
);
835 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
836 (LPARAM
)HMENU_32(HIWORD(lParam
)), result
, arg
);
839 if((LOWORD(lParam
) & MF_POPUP
) && (LOWORD(lParam
) != 0xFFFF))
841 HMENU hmenu
= HMENU_32(HIWORD(lParam
));
842 int pos
= find_sub_menu( &hmenu
, wParam
);
843 if (pos
== -1) pos
= 0;
846 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, LOWORD(lParam
) ),
847 (LPARAM
)HMENU_32(HIWORD(lParam
)), result
, arg
);
849 case WM_PARENTNOTIFY
:
850 if ((wParam
== WM_CREATE
) || (wParam
== WM_DESTROY
))
851 ret
= callback( hwnd32
, msg
, MAKEWPARAM( wParam
, HIWORD(lParam
) ),
852 (LPARAM
)WIN_Handle32( LOWORD(lParam
) ), result
, arg
);
854 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
857 /* We need this when SetActiveWindow sends a Sendmessage16() to
858 * a 32-bit window. Might be superfluous with 32-bit interprocess
860 if (lParam
) lParam
= HTASK_32(lParam
);
861 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
863 case WM_DDE_INITIATE
:
864 case WM_DDE_TERMINATE
:
865 case WM_DDE_UNADVISE
:
867 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
873 HANDLE16 lo16
= LOWORD(lParam
);
875 if (lo16
&& !(lo32
= convert_handle_16_to_32(lo16
, GMEM_DDESHARE
))) break;
876 lParam
= PackDDElParam( msg
, lo32
, HIWORD(lParam
) );
877 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
879 break; /* FIXME don't know how to free allocated memory (handle) !! */
882 UINT_PTR lo
= LOWORD(lParam
);
883 UINT_PTR hi
= HIWORD(lParam
);
887 if (GlobalGetAtomNameA(hi
, buf
, 2) > 0) flag
|= 1;
888 if (GlobalSize16(hi
) != 0) flag
|= 2;
894 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
899 break; /* atom, nothing to do */
901 MESSAGE("DDE_ACK: %lx both atom and handle... choosing handle\n", hi
);
904 hi
= convert_handle_16_to_32(hi
, GMEM_DDESHARE
);
907 lParam
= PackDDElParam( WM_DDE_ACK
, lo
, hi
);
908 ret
= callback( hwnd32
, msg
, (WPARAM
)WIN_Handle32(wParam
), lParam
, result
, arg
);
910 break; /* FIXME don't know how to free allocated memory (handle) !! */
912 lParam
= convert_handle_16_to_32( lParam
, GMEM_DDESHARE
);
913 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
914 break; /* FIXME don't know how to free allocated memory (handle) !! */
915 case WM_PAINTCLIPBOARD
:
916 case WM_SIZECLIPBOARD
:
917 FIXME_(msg
)( "message %04x needs translation\n", msg
);
920 ret
= callback( hwnd32
, msg
, wParam
, lParam
, result
, arg
);
927 /**********************************************************************
928 * WINPROC_CallProc32ATo16
930 * Call a 16-bit window procedure, translating the 32-bit args.
932 LRESULT
WINPROC_CallProc32ATo16( winproc_callback16_t callback
, HWND hwnd
, UINT msg
,
933 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
, void *arg
)
942 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)lParam
;
944 MDICREATESTRUCT16 mdi_cs16
;
945 BOOL mdi_child
= (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
);
947 CREATESTRUCT32Ato16( cs32
, &cs
);
948 cs
.lpszName
= MapLS( cs32
->lpszName
);
949 cs
.lpszClass
= MapLS( cs32
->lpszClass
);
953 MDICREATESTRUCTA
*mdi_cs
= cs32
->lpCreateParams
;
954 MDICREATESTRUCT32Ato16( mdi_cs
, &mdi_cs16
);
955 mdi_cs16
.szTitle
= MapLS( mdi_cs
->szTitle
);
956 mdi_cs16
.szClass
= MapLS( mdi_cs
->szClass
);
957 cs
.lpCreateParams
= MapLS( &mdi_cs16
);
959 lParam
= MapLS( &cs
);
960 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
962 UnMapLS( cs
.lpszName
);
963 UnMapLS( cs
.lpszClass
);
966 UnMapLS( cs
.lpCreateParams
);
967 UnMapLS( mdi_cs16
.szTitle
);
968 UnMapLS( mdi_cs16
.szClass
);
974 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)lParam
;
975 MDICREATESTRUCT16 cs
;
977 MDICREATESTRUCT32Ato16( cs32
, &cs
);
978 cs
.szTitle
= MapLS( cs32
->szTitle
);
979 cs
.szClass
= MapLS( cs32
->szClass
);
980 lParam
= MapLS( &cs
);
981 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
983 UnMapLS( cs
.szTitle
);
984 UnMapLS( cs
.szClass
);
988 if (GetWindowLongW( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
989 ret
= callback( HWND_16(hwnd
), msg
, ((HWND
)lParam
== hwnd
),
990 MAKELPARAM( LOWORD(lParam
), LOWORD(wParam
) ), result
, arg
);
992 ret
= callback( HWND_16(hwnd
), msg
, HWND_16( wParam
), 0, result
, arg
);
994 case WM_MDIGETACTIVE
:
995 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
996 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(*result
);
997 *result
= (LRESULT
)WIN_Handle32( LOWORD(*result
) );
1000 ret
= callback( HWND_16(hwnd
), msg
, (lParam
== 0),
1001 MAKELPARAM( LOWORD(wParam
), LOWORD(lParam
) ), result
, arg
);
1003 case WM_GETMINMAXINFO
:
1005 MINMAXINFO
*mmi32
= (MINMAXINFO
*)lParam
;
1008 MINMAXINFO32to16( mmi32
, &mmi
);
1009 lParam
= MapLS( &mmi
);
1010 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1012 MINMAXINFO16to32( &mmi
, mmi32
);
1017 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)lParam
;
1018 NCCALCSIZE_PARAMS16 nc
;
1021 RECT32to16( &nc32
->rgrc
[0], &nc
.rgrc
[0] );
1024 RECT32to16( &nc32
->rgrc
[1], &nc
.rgrc
[1] );
1025 RECT32to16( &nc32
->rgrc
[2], &nc
.rgrc
[2] );
1026 WINDOWPOS32to16( nc32
->lppos
, &winpos
);
1027 nc
.lppos
= MapLS( &winpos
);
1029 lParam
= MapLS( &nc
);
1030 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1032 RECT16to32( &nc
.rgrc
[0], &nc32
->rgrc
[0] );
1035 RECT16to32( &nc
.rgrc
[1], &nc32
->rgrc
[1] );
1036 RECT16to32( &nc
.rgrc
[2], &nc32
->rgrc
[2] );
1037 WINDOWPOS16to32( &winpos
, nc32
->lppos
);
1038 UnMapLS( nc
.lppos
);
1042 case WM_WINDOWPOSCHANGING
:
1043 case WM_WINDOWPOSCHANGED
:
1045 WINDOWPOS
*winpos32
= (WINDOWPOS
*)lParam
;
1048 WINDOWPOS32to16( winpos32
, &winpos
);
1049 lParam
= MapLS( &winpos
);
1050 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1052 WINDOWPOS16to32( &winpos
, winpos32
);
1055 case WM_COMPAREITEM
:
1057 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)lParam
;
1058 COMPAREITEMSTRUCT16 cis
;
1059 cis
.CtlType
= cis32
->CtlType
;
1060 cis
.CtlID
= cis32
->CtlID
;
1061 cis
.hwndItem
= HWND_16( cis32
->hwndItem
);
1062 cis
.itemID1
= cis32
->itemID1
;
1063 cis
.itemData1
= cis32
->itemData1
;
1064 cis
.itemID2
= cis32
->itemID2
;
1065 cis
.itemData2
= cis32
->itemData2
;
1066 lParam
= MapLS( &cis
);
1067 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1073 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)lParam
;
1074 DELETEITEMSTRUCT16 dis
;
1075 dis
.CtlType
= dis32
->CtlType
;
1076 dis
.CtlID
= dis32
->CtlID
;
1077 dis
.itemID
= dis32
->itemID
;
1078 dis
.hwndItem
= (dis
.CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
1079 : HWND_16( dis32
->hwndItem
);
1080 dis
.itemData
= dis32
->itemData
;
1081 lParam
= MapLS( &dis
);
1082 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1088 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)lParam
;
1089 DRAWITEMSTRUCT16 dis
;
1090 dis
.CtlType
= dis32
->CtlType
;
1091 dis
.CtlID
= dis32
->CtlID
;
1092 dis
.itemID
= dis32
->itemID
;
1093 dis
.itemAction
= dis32
->itemAction
;
1094 dis
.itemState
= dis32
->itemState
;
1095 dis
.hwndItem
= HWND_16( dis32
->hwndItem
);
1096 dis
.hDC
= HDC_16(dis32
->hDC
);
1097 dis
.itemData
= dis32
->itemData
;
1098 dis
.rcItem
.left
= dis32
->rcItem
.left
;
1099 dis
.rcItem
.top
= dis32
->rcItem
.top
;
1100 dis
.rcItem
.right
= dis32
->rcItem
.right
;
1101 dis
.rcItem
.bottom
= dis32
->rcItem
.bottom
;
1102 lParam
= MapLS( &dis
);
1103 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1107 case WM_MEASUREITEM
:
1109 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)lParam
;
1110 MEASUREITEMSTRUCT16 mis
;
1111 mis
.CtlType
= mis32
->CtlType
;
1112 mis
.CtlID
= mis32
->CtlID
;
1113 mis
.itemID
= mis32
->itemID
;
1114 mis
.itemWidth
= mis32
->itemWidth
;
1115 mis
.itemHeight
= mis32
->itemHeight
;
1116 mis
.itemData
= mis32
->itemData
;
1117 lParam
= MapLS( &mis
);
1118 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1120 mis32
->itemWidth
= mis
.itemWidth
;
1121 mis32
->itemHeight
= mis
.itemHeight
;
1126 COPYDATASTRUCT
*cds32
= (COPYDATASTRUCT
*)lParam
;
1127 COPYDATASTRUCT16 cds
;
1129 cds
.dwData
= cds32
->dwData
;
1130 cds
.cbData
= cds32
->cbData
;
1131 cds
.lpData
= MapLS( cds32
->lpData
);
1132 lParam
= MapLS( &cds
);
1133 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1135 UnMapLS( cds
.lpData
);
1141 MSG
*msg32
= (MSG
*)lParam
;
1144 msg16
.hwnd
= HWND_16( msg32
->hwnd
);
1145 msg16
.message
= msg32
->message
;
1146 msg16
.wParam
= msg32
->wParam
;
1147 msg16
.lParam
= msg32
->lParam
;
1148 msg16
.time
= msg32
->time
;
1149 msg16
.pt
.x
= msg32
->pt
.x
;
1150 msg16
.pt
.y
= msg32
->pt
.y
;
1151 lParam
= MapLS( &msg16
);
1152 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1156 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1160 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1161 ret
= callback( HWND_16(hwnd
), msg
, wParam
, (LPARAM
)next
->hmenuIn
, result
, arg
);
1162 next
->hmenuNext
= HMENU_32( LOWORD(*result
) );
1163 next
->hwndNext
= WIN_Handle32( HIWORD(*result
) );
1168 case WM_ASKCBFORMATNAME
:
1169 wParam
= min( wParam
, 0xff80 ); /* Must be < 64K */
1173 case WM_WININICHANGE
:
1174 case WM_DEVMODECHANGE
:
1175 lParam
= MapLS( (void *)lParam
);
1176 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1183 ret
= callback( HWND_16(hwnd
), msg
, wParam
, MAKELPARAM( (HWND16
)lParam
, HIWORD(wParam
) ),
1188 ret
= callback( HWND_16(hwnd
), msg
, wParam
, MAKELPARAM( HIWORD(wParam
), (HWND16
)lParam
),
1191 case WM_CTLCOLORMSGBOX
:
1192 case WM_CTLCOLOREDIT
:
1193 case WM_CTLCOLORLISTBOX
:
1194 case WM_CTLCOLORBTN
:
1195 case WM_CTLCOLORDLG
:
1196 case WM_CTLCOLORSCROLLBAR
:
1197 case WM_CTLCOLORSTATIC
:
1198 ret
= callback( HWND_16(hwnd
), WM_CTLCOLOR
, wParam
,
1199 MAKELPARAM( (HWND16
)lParam
, msg
- WM_CTLCOLORMSGBOX
), result
, arg
);
1202 if(HIWORD(wParam
) & MF_POPUP
)
1205 if ((HIWORD(wParam
) != 0xffff) || lParam
)
1207 if ((hmenu
= GetSubMenu( (HMENU
)lParam
, LOWORD(wParam
) )))
1209 ret
= callback( HWND_16(hwnd
), msg
, HMENU_16(hmenu
),
1210 MAKELPARAM( HIWORD(wParam
), (HMENU16
)lParam
), result
, arg
);
1217 ret
= callback( HWND_16(hwnd
), msg
, wParam
,
1218 MAKELPARAM( HIWORD(wParam
), (HMENU16
)lParam
), result
, arg
);
1220 case WM_PARENTNOTIFY
:
1221 if ((LOWORD(wParam
) == WM_CREATE
) || (LOWORD(wParam
) == WM_DESTROY
))
1222 ret
= callback( HWND_16(hwnd
), msg
, wParam
,
1223 MAKELPARAM( (HWND16
)lParam
, HIWORD(wParam
) ), result
, arg
);
1225 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1227 case WM_ACTIVATEAPP
:
1228 ret
= callback( HWND_16(hwnd
), msg
, wParam
, HTASK_16( lParam
), result
, arg
);
1231 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
))
1232 ret
= callback( HWND_16(hwnd
), WM_PAINTICON
, 1, lParam
, result
, arg
);
1234 ret
= callback( HWND_16(hwnd
), WM_PAINT
, wParam
, lParam
, result
, arg
);
1237 if (IsIconic( hwnd
) && GetClassLongPtrW( hwnd
, GCLP_HICON
)) msg
= WM_ICONERASEBKGND
;
1238 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1240 case WM_DDE_INITIATE
:
1241 case WM_DDE_TERMINATE
:
1242 case WM_DDE_UNADVISE
:
1243 case WM_DDE_REQUEST
:
1244 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
), lParam
, result
, arg
);
1253 UnpackDDElParam( msg
, lParam
, &lo32
, &hi
);
1254 if (lo32
&& !(lo16
= convert_handle_32_to_16(lo32
, GMEM_DDESHARE
))) break;
1255 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
),
1256 MAKELPARAM(lo16
, hi
), result
, arg
);
1258 break; /* FIXME don't know how to free allocated memory (handle) !! */
1265 UnpackDDElParam( msg
, lParam
, &lo
, &hi
);
1267 if (GlobalGetAtomNameA((ATOM
)hi
, buf
, sizeof(buf
)) > 0) flag
|= 1;
1268 if (GlobalSize((HANDLE
)hi
) != 0) flag
|= 2;
1274 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1279 break; /* atom, nothing to do */
1281 MESSAGE("DDE_ACK: %lx both atom and handle... choosing handle\n", hi
);
1284 hi
= convert_handle_32_to_16(hi
, GMEM_DDESHARE
);
1287 ret
= callback( HWND_16(hwnd
), msg
, HWND_16(wParam
),
1288 MAKELPARAM(lo
, hi
), result
, arg
);
1290 break; /* FIXME don't know how to free allocated memory (handle) !! */
1291 case WM_DDE_EXECUTE
:
1292 lParam
= convert_handle_32_to_16(lParam
, GMEM_DDESHARE
);
1293 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1294 break; /* FIXME don't know how to free allocated memory (handle) !! */
1296 ret
= callback( HWND_16(hwnd
), SBM_SETRANGE16
, 0, MAKELPARAM(wParam
, lParam
), result
, arg
);
1299 ret
= callback( HWND_16(hwnd
), SBM_GETRANGE16
, wParam
, lParam
, result
, arg
);
1300 *(LPINT
)wParam
= LOWORD(*result
);
1301 *(LPINT
)lParam
= HIWORD(*result
);
1308 ret
= callback( HWND_16(hwnd
), msg
+ BM_GETCHECK16
- BM_GETCHECK
, wParam
, lParam
, result
, arg
);
1316 case EM_SCROLLCARET
:
1319 case EM_GETLINECOUNT
:
1331 case EM_LINEFROMCHAR
:
1332 case EM_SETTABSTOPS
:
1333 case EM_SETPASSWORDCHAR
:
1334 case EM_EMPTYUNDOBUFFER
:
1335 case EM_GETFIRSTVISIBLELINE
:
1336 case EM_SETREADONLY
:
1337 case EM_SETWORDBREAKPROC
:
1338 case EM_GETWORDBREAKPROC
:
1339 case EM_GETPASSWORDCHAR
:
1340 ret
= callback( HWND_16(hwnd
), msg
+ EM_GETSEL16
- EM_GETSEL
, wParam
, lParam
, result
, arg
);
1343 ret
= callback( HWND_16(hwnd
), EM_SETSEL16
, 0, MAKELPARAM( wParam
, lParam
), result
, arg
);
1347 case LB_DELETESTRING
:
1348 case LB_GETANCHORINDEX
:
1349 case LB_GETCARETINDEX
:
1352 case LB_GETHORIZONTALEXTENT
:
1353 case LB_GETITEMDATA
:
1354 case LB_GETITEMHEIGHT
:
1356 case LB_GETSELCOUNT
:
1358 case LB_GETTOPINDEX
:
1359 case LB_RESETCONTENT
:
1360 case LB_SELITEMRANGE
:
1361 case LB_SELITEMRANGEEX
:
1362 case LB_SETANCHORINDEX
:
1363 case LB_SETCARETINDEX
:
1364 case LB_SETCOLUMNWIDTH
:
1366 case LB_SETHORIZONTALEXTENT
:
1367 case LB_SETITEMDATA
:
1368 case LB_SETITEMHEIGHT
:
1370 case LB_SETTOPINDEX
:
1371 ret
= callback( HWND_16(hwnd
), msg
+ LB_ADDSTRING16
- LB_ADDSTRING
, wParam
, lParam
, result
, arg
);
1375 case LB_FINDSTRINGEXACT
:
1376 case LB_INSERTSTRING
:
1377 case LB_SELECTSTRING
:
1381 lParam
= MapLS( (LPSTR
)lParam
);
1382 ret
= callback( HWND_16(hwnd
), msg
+ LB_ADDSTRING16
- LB_ADDSTRING
, wParam
, lParam
, result
, arg
);
1385 case LB_GETSELITEMS
:
1387 INT
*items32
= (INT
*)lParam
;
1388 INT16
*items
, buffer
[512];
1391 wParam
= min( wParam
, 0x7f80 ); /* Must be < 64K */
1392 if (!(items
= get_buffer( buffer
, sizeof(buffer
), wParam
* sizeof(INT16
) ))) break;
1393 lParam
= MapLS( items
);
1394 ret
= callback( HWND_16(hwnd
), LB_GETSELITEMS16
, wParam
, lParam
, result
, arg
);
1396 for (i
= 0; i
< wParam
; i
++) items32
[i
] = items
[i
];
1397 free_buffer( buffer
, items
);
1400 case LB_SETTABSTOPS
:
1403 INT
*stops32
= (INT
*)lParam
;
1404 INT16
*stops
, buffer
[512];
1407 wParam
= min( wParam
, 0x7f80 ); /* Must be < 64K */
1408 if (!(stops
= get_buffer( buffer
, sizeof(buffer
), wParam
* sizeof(INT16
) ))) break;
1409 for (i
= 0; i
< wParam
; i
++) stops
[i
] = stops32
[i
];
1410 lParam
= MapLS( stops
);
1411 ret
= callback( HWND_16(hwnd
), LB_SETTABSTOPS16
, wParam
, lParam
, result
, arg
);
1413 free_buffer( buffer
, stops
);
1415 else ret
= callback( HWND_16(hwnd
), LB_SETTABSTOPS16
, wParam
, lParam
, result
, arg
);
1417 case CB_DELETESTRING
:
1419 case CB_GETLBTEXTLEN
:
1421 case CB_RESETCONTENT
:
1425 case CB_SHOWDROPDOWN
:
1426 case CB_SETITEMDATA
:
1427 case CB_SETITEMHEIGHT
:
1428 case CB_GETITEMHEIGHT
:
1429 case CB_SETEXTENDEDUI
:
1430 case CB_GETEXTENDEDUI
:
1431 case CB_GETDROPPEDSTATE
:
1432 ret
= callback( HWND_16(hwnd
), msg
+ CB_GETEDITSEL16
- CB_GETEDITSEL
, wParam
, lParam
, result
, arg
);
1435 ret
= callback( HWND_16(hwnd
), CB_GETEDITSEL16
, wParam
, lParam
, result
, arg
);
1436 if (wParam
) *((PUINT
)(wParam
)) = LOWORD(*result
);
1437 if (lParam
) *((PUINT
)(lParam
)) = HIWORD(*result
); /* FIXME: substract 1? */
1441 case CB_FINDSTRINGEXACT
:
1442 case CB_INSERTSTRING
:
1443 case CB_SELECTSTRING
:
1446 lParam
= MapLS( (LPSTR
)lParam
);
1447 ret
= callback( HWND_16(hwnd
), msg
+ CB_GETEDITSEL16
- CB_GETEDITSEL
, wParam
, lParam
, result
, arg
);
1450 case LB_GETITEMRECT
:
1451 case CB_GETDROPPEDCONTROLRECT
:
1453 RECT
*r32
= (RECT
*)lParam
;
1455 lParam
= MapLS( &rect
);
1456 ret
= callback( HWND_16(hwnd
),
1457 (msg
== LB_GETITEMRECT
) ? LB_GETITEMRECT16
: CB_GETDROPPEDCONTROLRECT16
,
1458 wParam
, lParam
, result
, arg
);
1460 RECT16to32( &rect
, r32
);
1463 case WM_PAINTCLIPBOARD
:
1464 case WM_SIZECLIPBOARD
:
1465 FIXME_(msg
)( "message %04x needs translation\n", msg
);
1467 /* the following messages should not be sent to 16-bit apps */
1470 case WM_CAPTURECHANGED
:
1471 case WM_STYLECHANGING
:
1472 case WM_STYLECHANGED
:
1475 ret
= callback( HWND_16(hwnd
), msg
, wParam
, lParam
, result
, arg
);
1482 /***********************************************************************
1483 * SendMessage (USER.111)
1485 LRESULT WINAPI
SendMessage16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1488 HWND hwnd
= WIN_Handle32( hwnd16
);
1490 if (hwnd
!= HWND_BROADCAST
&&
1491 GetWindowThreadProcessId( hwnd
, NULL
) == GetCurrentThreadId())
1493 /* call 16-bit window proc directly */
1496 /* first the WH_CALLWNDPROC hook */
1497 WINPROC_CallProc16To32A( cwp_hook_callback
, hwnd16
, msg
, wparam
, lparam
, &result
, NULL
);
1499 if (!(winproc
= (WNDPROC16
)GetWindowLong16( hwnd16
, GWLP_WNDPROC
))) return 0;
1501 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx\n", hwnd16
, msg
, wparam
, lparam
);
1502 result
= CallWindowProc16( winproc
, hwnd16
, msg
, wparam
, lparam
);
1503 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx returned %08lx\n",
1504 hwnd16
, msg
, wparam
, lparam
, result
);
1506 else /* map to 32-bit unicode for inter-thread/process message */
1508 WINPROC_CallProc16To32A( send_message_callback
, hwnd16
, msg
, wparam
, lparam
, &result
, NULL
);
1514 /***********************************************************************
1515 * PostMessage (USER.110)
1517 BOOL16 WINAPI
PostMessage16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1520 return WINPROC_CallProc16To32A( post_message_callback
, hwnd
, msg
, wparam
, lparam
, &unused
, NULL
);
1524 /***********************************************************************
1525 * PostAppMessage (USER.116)
1527 BOOL16 WINAPI
PostAppMessage16( HTASK16 hTask
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
1530 DWORD_PTR tid
= HTASK_32( hTask
);
1532 if (!tid
) return FALSE
;
1533 return WINPROC_CallProc16To32A( post_thread_message_callback
, 0, msg
, wparam
, lparam
,
1534 &unused
, (void *)tid
);
1538 /**********************************************************************
1539 * CallWindowProc (USER.122)
1541 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
1542 WPARAM16 wParam
, LPARAM lParam
)
1544 int index
= winproc_to_index( func
);
1547 if (!func
) return 0;
1549 if (index
== -1 || index
>= MAX_WINPROCS32
)
1550 call_window_proc16( hwnd
, msg
, wParam
, lParam
, &result
, func
);
1553 WNDPROC proc
= (WNDPROC
)func
;
1554 if (thunk_array
&& thunk_array
[index
].proc
) proc
= thunk_array
[index
].proc
;
1555 WINPROC_CallProc16To32A( call_window_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, proc
);
1561 /**********************************************************************
1562 * __wine_call_wndproc (USER.1010)
1564 LRESULT WINAPI
__wine_call_wndproc( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
, WNDPROC proc
)
1567 WINPROC_CallProc16To32A( call_window_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, proc
);
1572 /***********************************************************************
1573 * InSendMessage (USER.192)
1575 BOOL16 WINAPI
InSendMessage16(void)
1577 return InSendMessage();
1581 /***********************************************************************
1582 * ReplyMessage (USER.115)
1584 void WINAPI
ReplyMessage16( LRESULT result
)
1586 ReplyMessage( result
);
1590 /***********************************************************************
1591 * PeekMessage32 (USER.819)
1593 BOOL16 WINAPI
PeekMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
,
1594 UINT16 first
, UINT16 last
, UINT16 flags
,
1595 BOOL16 wHaveParamHigh
)
1599 HWND hwnd
= WIN_Handle32( hwnd16
);
1601 if(USER16_AlertableWait
)
1602 MsgWaitForMultipleObjectsEx( 0, NULL
, 0, 0, MWMO_ALERTABLE
);
1603 if (!PeekMessageA( &msg
, hwnd
, first
, last
, flags
)) return FALSE
;
1605 msg16
->msg
.time
= msg
.time
;
1606 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
1607 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
1608 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
1609 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
1610 &unused
, &msg16
->msg
);
1615 /***********************************************************************
1616 * DefWindowProc (USER.107)
1618 LRESULT WINAPI
DefWindowProc16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
1621 HWND hwnd
= WIN_Handle32( hwnd16
);
1627 CREATESTRUCT16
*cs16
= MapSL(lParam
);
1630 cs32
.lpCreateParams
= ULongToPtr(cs16
->lpCreateParams
);
1631 cs32
.hInstance
= HINSTANCE_32(cs16
->hInstance
);
1632 cs32
.hMenu
= HMENU_32(cs16
->hMenu
);
1633 cs32
.hwndParent
= WIN_Handle32(cs16
->hwndParent
);
1638 cs32
.style
= cs16
->style
;
1639 cs32
.dwExStyle
= cs16
->dwExStyle
;
1640 cs32
.lpszName
= MapSL(cs16
->lpszName
);
1641 cs32
.lpszClass
= MapSL(cs16
->lpszClass
);
1642 return DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&cs32
);
1646 RECT16
*rect16
= MapSL(lParam
);
1649 rect32
.left
= rect16
->left
;
1650 rect32
.top
= rect16
->top
;
1651 rect32
.right
= rect16
->right
;
1652 rect32
.bottom
= rect16
->bottom
;
1654 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&rect32
);
1656 rect16
->left
= rect32
.left
;
1657 rect16
->top
= rect32
.top
;
1658 rect16
->right
= rect32
.right
;
1659 rect16
->bottom
= rect32
.bottom
;
1662 case WM_WINDOWPOSCHANGING
:
1663 case WM_WINDOWPOSCHANGED
:
1665 WINDOWPOS16
*pos16
= MapSL(lParam
);
1668 pos32
.hwnd
= WIN_Handle32(pos16
->hwnd
);
1669 pos32
.hwndInsertAfter
= WIN_Handle32(pos16
->hwndInsertAfter
);
1672 pos32
.cx
= pos16
->cx
;
1673 pos32
.cy
= pos16
->cy
;
1674 pos32
.flags
= pos16
->flags
;
1676 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&pos32
);
1678 pos16
->hwnd
= HWND_16(pos32
.hwnd
);
1679 pos16
->hwndInsertAfter
= HWND_16(pos32
.hwndInsertAfter
);
1682 pos16
->cx
= pos32
.cx
;
1683 pos16
->cy
= pos32
.cy
;
1684 pos16
->flags
= pos32
.flags
;
1689 return DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)MapSL(lParam
) );
1691 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
1696 /***********************************************************************
1697 * DefDlgProc (USER.308)
1699 LRESULT WINAPI
DefDlgProc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
1702 WINPROC_CallProc16To32A( defdlg_proc_callback
, hwnd
, msg
, wParam
, lParam
, &result
, 0 );
1707 /***********************************************************************
1708 * PeekMessage (USER.109)
1710 BOOL16 WINAPI
PeekMessage16( MSG16
*msg
, HWND16 hwnd
,
1711 UINT16 first
, UINT16 last
, UINT16 flags
)
1713 return PeekMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, flags
, FALSE
);
1717 /***********************************************************************
1718 * GetMessage32 (USER.820)
1720 BOOL16 WINAPI
GetMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
, UINT16 first
,
1721 UINT16 last
, BOOL16 wHaveParamHigh
)
1725 HWND hwnd
= WIN_Handle32( hwnd16
);
1727 if(USER16_AlertableWait
)
1728 MsgWaitForMultipleObjectsEx( 0, NULL
, INFINITE
, 0, MWMO_ALERTABLE
);
1729 GetMessageA( &msg
, hwnd
, first
, last
);
1730 msg16
->msg
.time
= msg
.time
;
1731 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
1732 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
1733 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
1734 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
1735 &unused
, &msg16
->msg
);
1737 TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
1738 msg16
->msg
.message
, hwnd
, first
, last
);
1740 return msg16
->msg
.message
!= WM_QUIT
;
1744 /***********************************************************************
1745 * GetMessage (USER.108)
1747 BOOL16 WINAPI
GetMessage16( MSG16
*msg
, HWND16 hwnd
, UINT16 first
, UINT16 last
)
1749 return GetMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, FALSE
);
1753 /***********************************************************************
1754 * TranslateMessage32 (USER.821)
1756 BOOL16 WINAPI
TranslateMessage32_16( const MSG32_16
*msg
, BOOL16 wHaveParamHigh
)
1760 msg32
.hwnd
= WIN_Handle32( msg
->msg
.hwnd
);
1761 msg32
.message
= msg
->msg
.message
;
1762 msg32
.wParam
= MAKEWPARAM( msg
->msg
.wParam
, wHaveParamHigh
? msg
->wParamHigh
: 0 );
1763 msg32
.lParam
= msg
->msg
.lParam
;
1764 return TranslateMessage( &msg32
);
1768 /***********************************************************************
1769 * TranslateMessage (USER.113)
1771 BOOL16 WINAPI
TranslateMessage16( const MSG16
*msg
)
1773 return TranslateMessage32_16( (const MSG32_16
*)msg
, FALSE
);
1777 /***********************************************************************
1778 * DispatchMessage (USER.114)
1780 LONG WINAPI
DispatchMessage16( const MSG16
* msg
)
1785 /* Process timer messages */
1786 if ((msg
->message
== WM_TIMER
) || (msg
->message
== WM_SYSTIMER
))
1789 return CallWindowProc16( (WNDPROC16
)msg
->lParam
, msg
->hwnd
,
1790 msg
->message
, msg
->wParam
, GetTickCount() );
1793 if (!(winproc
= (WNDPROC16
)GetWindowLong16( msg
->hwnd
, GWLP_WNDPROC
)))
1795 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
1798 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx\n", msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1799 retval
= CallWindowProc16( winproc
, msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1800 TRACE_(message
)("(0x%04x) [%04x] wp=%04x lp=%08lx returned %08lx\n",
1801 msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
, retval
);
1806 /***********************************************************************
1807 * DispatchMessage32 (USER.822)
1809 LONG WINAPI
DispatchMessage32_16( const MSG32_16
*msg16
, BOOL16 wHaveParamHigh
)
1811 if (wHaveParamHigh
== FALSE
)
1812 return DispatchMessage16( &msg16
->msg
);
1817 msg
.hwnd
= WIN_Handle32( msg16
->msg
.hwnd
);
1818 msg
.message
= msg16
->msg
.message
;
1819 msg
.wParam
= MAKEWPARAM( msg16
->msg
.wParam
, msg16
->wParamHigh
);
1820 msg
.lParam
= msg16
->msg
.lParam
;
1821 msg
.time
= msg16
->msg
.time
;
1822 msg
.pt
.x
= msg16
->msg
.pt
.x
;
1823 msg
.pt
.y
= msg16
->msg
.pt
.y
;
1824 return DispatchMessageA( &msg
);
1829 /***********************************************************************
1830 * IsDialogMessage (USER.90)
1832 BOOL16 WINAPI
IsDialogMessage16( HWND16 hwndDlg
, MSG16
*msg16
)
1837 msg
.hwnd
= WIN_Handle32(msg16
->hwnd
);
1838 hwndDlg32
= WIN_Handle32(hwndDlg
);
1840 switch(msg16
->message
)
1845 msg
.message
= msg16
->message
;
1846 msg
.wParam
= msg16
->wParam
;
1847 msg
.lParam
= msg16
->lParam
;
1848 return IsDialogMessageA( hwndDlg32
, &msg
);
1851 if ((hwndDlg32
!= msg
.hwnd
) && !IsChild( hwndDlg32
, msg
.hwnd
)) return FALSE
;
1852 TranslateMessage16( msg16
);
1853 DispatchMessage16( msg16
);
1858 /***********************************************************************
1859 * MsgWaitForMultipleObjects (USER.640)
1861 DWORD WINAPI
MsgWaitForMultipleObjects16( DWORD count
, CONST HANDLE
*handles
,
1862 BOOL wait_all
, DWORD timeout
, DWORD mask
)
1864 return MsgWaitForMultipleObjectsEx( count
, handles
, timeout
, mask
,
1865 wait_all
? MWMO_WAITALL
: 0 );
1869 /**********************************************************************
1870 * SetDoubleClickTime (USER.20)
1872 void WINAPI
SetDoubleClickTime16( UINT16 interval
)
1874 SetDoubleClickTime( interval
);
1878 /**********************************************************************
1879 * GetDoubleClickTime (USER.21)
1881 UINT16 WINAPI
GetDoubleClickTime16(void)
1883 return GetDoubleClickTime();
1887 /***********************************************************************
1888 * PostQuitMessage (USER.6)
1890 void WINAPI
PostQuitMessage16( INT16 exitCode
)
1892 PostQuitMessage( exitCode
);
1896 /**********************************************************************
1897 * GetKeyState (USER.106)
1899 INT16 WINAPI
GetKeyState16(INT16 vkey
)
1901 return GetKeyState(vkey
);
1905 /**********************************************************************
1906 * GetKeyboardState (USER.222)
1908 BOOL WINAPI
GetKeyboardState16( LPBYTE state
)
1910 return GetKeyboardState( state
);
1914 /**********************************************************************
1915 * SetKeyboardState (USER.223)
1917 BOOL WINAPI
SetKeyboardState16( LPBYTE state
)
1919 return SetKeyboardState( state
);
1923 /***********************************************************************
1924 * SetMessageQueue (USER.266)
1926 BOOL16 WINAPI
SetMessageQueue16( INT16 size
)
1928 return SetMessageQueue( size
);
1932 /***********************************************************************
1933 * UserYield (USER.332)
1935 void WINAPI
UserYield16(void)
1938 PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
| PM_QS_SENDMESSAGE
);
1942 /***********************************************************************
1943 * GetQueueStatus (USER.334)
1945 DWORD WINAPI
GetQueueStatus16( UINT16 flags
)
1947 return GetQueueStatus( flags
);
1951 /***********************************************************************
1952 * GetInputState (USER.335)
1954 BOOL16 WINAPI
GetInputState16(void)
1956 return GetInputState();
1960 /**********************************************************************
1961 * TranslateAccelerator (USER.178)
1963 INT16 WINAPI
TranslateAccelerator16( HWND16 hwnd
, HACCEL16 hAccel
, LPMSG16 msg
)
1968 msg32
.message
= msg
->message
;
1969 /* msg32.hwnd not used */
1970 msg32
.wParam
= msg
->wParam
;
1971 msg32
.lParam
= msg
->lParam
;
1972 return TranslateAcceleratorW( WIN_Handle32(hwnd
), HACCEL_32(hAccel
), &msg32
);
1976 /**********************************************************************
1977 * TranslateMDISysAccel (USER.451)
1979 BOOL16 WINAPI
TranslateMDISysAccel16( HWND16 hwndClient
, LPMSG16 msg
)
1981 if (msg
->message
== WM_KEYDOWN
|| msg
->message
== WM_SYSKEYDOWN
)
1984 msg32
.hwnd
= WIN_Handle32(msg
->hwnd
);
1985 msg32
.message
= msg
->message
;
1986 msg32
.wParam
= msg
->wParam
;
1987 msg32
.lParam
= msg
->lParam
;
1988 /* MDICLIENTINFO is still the same for win32 and win16 ... */
1989 return TranslateMDISysAccel( WIN_Handle32(hwndClient
), &msg32
);
1995 /***********************************************************************
1998 static LRESULT
button_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2000 static const UINT msg16_offset
= BM_GETCHECK16
- BM_GETCHECK
;
2009 return wow_handlers32
.button_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2011 return wow_handlers32
.button_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2016 /***********************************************************************
2019 static LRESULT
combo_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2021 static const UINT msg16_offset
= CB_GETEDITSEL16
- CB_GETEDITSEL
;
2025 case CB_INSERTSTRING16
:
2026 case CB_SELECTSTRING16
:
2027 case CB_FINDSTRING16
:
2028 case CB_FINDSTRINGEXACT16
:
2029 wParam
= (INT
)(INT16
)wParam
;
2031 case CB_ADDSTRING16
:
2033 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2034 if ((style
& CBS_HASSTRINGS
) || !(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)))
2035 lParam
= (LPARAM
)MapSL(lParam
);
2036 msg
-= msg16_offset
;
2039 case CB_SETITEMHEIGHT16
:
2040 case CB_GETITEMHEIGHT16
:
2041 case CB_SETCURSEL16
:
2042 case CB_GETLBTEXTLEN16
:
2043 case CB_GETITEMDATA16
:
2044 case CB_SETITEMDATA16
:
2045 wParam
= (INT
)(INT16
)wParam
; /* signed integer */
2046 msg
-= msg16_offset
;
2048 case CB_GETDROPPEDCONTROLRECT16
:
2049 lParam
= (LPARAM
)MapSL(lParam
);
2053 RECT16
*r16
= (RECT16
*)lParam
;
2054 wow_handlers32
.combo_proc( hwnd
, CB_GETDROPPEDCONTROLRECT
, wParam
, (LPARAM
)&r
, FALSE
);
2057 r16
->right
= r
.right
;
2058 r16
->bottom
= r
.bottom
;
2062 if (wParam
& DDL_DRIVES
) wParam
|= DDL_EXCLUSIVE
;
2063 lParam
= (LPARAM
)MapSL(lParam
);
2064 msg
-= msg16_offset
;
2066 case CB_GETLBTEXT16
:
2067 wParam
= (INT
)(INT16
)wParam
;
2068 lParam
= (LPARAM
)MapSL(lParam
);
2069 msg
-= msg16_offset
;
2071 case CB_GETEDITSEL16
:
2072 wParam
= lParam
= 0; /* just in case */
2073 msg
-= msg16_offset
;
2075 case CB_LIMITTEXT16
:
2076 case CB_SETEDITSEL16
:
2077 case CB_DELETESTRING16
:
2078 case CB_RESETCONTENT16
:
2079 case CB_GETDROPPEDSTATE16
:
2080 case CB_SHOWDROPDOWN16
:
2082 case CB_GETCURSEL16
:
2083 case CB_SETEXTENDEDUI16
:
2084 case CB_GETEXTENDEDUI16
:
2085 msg
-= msg16_offset
;
2088 return wow_handlers32
.combo_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2090 return wow_handlers32
.combo_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2094 #define GWW_HANDLE16 sizeof(void*)
2096 static void edit_lock_buffer( HWND hwnd
)
2098 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2099 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2104 if (!hloc16
) return;
2105 if (!(hloc32
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return;
2107 oldDS
= stack16
->ds
;
2108 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2109 size
= LocalSize16(hloc16
);
2110 if (LocalReAlloc( hloc32
, size
, LMEM_MOVEABLE
))
2112 char *text
= MapSL( LocalLock16( hloc16
));
2113 char *dest
= LocalLock( hloc32
);
2114 memcpy( dest
, text
, size
);
2115 LocalUnlock( hloc32
);
2116 LocalUnlock16( hloc16
);
2118 stack16
->ds
= oldDS
;
2122 static void edit_unlock_buffer( HWND hwnd
)
2124 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2125 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2130 if (!hloc16
) return;
2131 if (!(hloc32
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return;
2132 size
= LocalSize( hloc32
);
2134 oldDS
= stack16
->ds
;
2135 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2136 if (LocalReAlloc16( hloc16
, size
, LMEM_MOVEABLE
))
2138 char *text
= LocalLock( hloc32
);
2139 char *dest
= MapSL( LocalLock16( hloc16
));
2140 memcpy( dest
, text
, size
);
2141 LocalUnlock( hloc32
);
2142 LocalUnlock16( hloc16
);
2144 stack16
->ds
= oldDS
;
2147 static HLOCAL16
edit_get_handle( HWND hwnd
)
2152 STACK16FRAME
* stack16
;
2154 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2156 if (hloc16
) return hloc16
;
2158 if (!(hloc
= (HLOCAL
)wow_handlers32
.edit_proc( hwnd
, EM_GETHANDLE
, 0, 0, FALSE
))) return 0;
2159 alloc_size
= LocalSize( hloc
);
2161 stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2162 oldDS
= stack16
->ds
;
2163 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2165 if (!LocalHeapSize16())
2167 if (!LocalInit16(stack16
->ds
, 0, GlobalSize16(stack16
->ds
)))
2169 ERR("could not initialize local heap\n");
2174 if (!(hloc16
= LocalAlloc16(LMEM_MOVEABLE
| LMEM_ZEROINIT
, alloc_size
)))
2176 ERR("could not allocate new 16 bit buffer\n");
2180 if (!(textA
= MapSL(LocalLock16( hloc16
))))
2182 ERR("could not lock new 16 bit buffer\n");
2183 LocalFree16(hloc16
);
2187 memcpy( textA
, LocalLock( hloc
), alloc_size
);
2188 LocalUnlock( hloc
);
2189 LocalUnlock16( hloc16
);
2190 SetWindowWord( hwnd
, GWW_HANDLE16
, hloc16
);
2193 stack16
->ds
= oldDS
;
2197 static void edit_set_handle( HWND hwnd
, HLOCAL16 hloc16
)
2199 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2200 HINSTANCE16 hInstance
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2201 HANDLE16 oldDS
= stack16
->ds
;
2206 if (!(GetWindowLongW( hwnd
, GWL_STYLE
) & ES_MULTILINE
)) return;
2207 if (!hloc16
) return;
2209 stack16
->ds
= hInstance
;
2210 count
= LocalSize16(hloc16
);
2211 text
= MapSL(LocalLock16(hloc16
));
2212 if ((hloc32
= LocalAlloc(LMEM_MOVEABLE
, count
)))
2214 memcpy( LocalLock(hloc32
), text
, count
);
2215 LocalUnlock(hloc32
);
2216 LocalUnlock16(hloc16
);
2217 SetWindowWord( hwnd
, GWW_HANDLE16
, hloc16
);
2219 stack16
->ds
= oldDS
;
2221 if (hloc32
) wow_handlers32
.edit_proc( hwnd
, EM_SETHANDLE
, (WPARAM
)hloc32
, 0, FALSE
);
2224 static void edit_destroy_handle( HWND hwnd
)
2226 HLOCAL16 hloc16
= GetWindowWord( hwnd
, GWW_HANDLE16
);
2229 STACK16FRAME
* stack16
= MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved
));
2230 HANDLE16 oldDS
= stack16
->ds
;
2232 stack16
->ds
= GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2233 while (LocalUnlock16(hloc16
)) ;
2234 LocalFree16(hloc16
);
2235 stack16
->ds
= oldDS
;
2236 SetWindowWord( hwnd
, GWW_HANDLE16
, 0 );
2240 /*********************************************************************
2243 static LRESULT
edit_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2245 static const UINT msg16_offset
= EM_GETSEL16
- EM_GETSEL
;
2248 edit_lock_buffer( hwnd
);
2252 case EM_SCROLLCARET16
:
2253 case EM_GETMODIFY16
:
2254 case EM_SETMODIFY16
:
2255 case EM_GETLINECOUNT16
:
2257 case EM_LINELENGTH16
:
2258 case EM_LIMITTEXT16
:
2262 case EM_LINEFROMCHAR16
:
2263 case EM_SETPASSWORDCHAR16
:
2264 case EM_EMPTYUNDOBUFFER16
:
2265 case EM_SETREADONLY16
:
2266 case EM_GETPASSWORDCHAR16
:
2267 /* these messages missing from specs */
2272 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2275 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, 0, 0, FALSE
);
2277 case EM_REPLACESEL16
:
2279 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)MapSL(lParam
), FALSE
);
2281 case EM_LINESCROLL16
:
2282 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, (INT
)(SHORT
)HIWORD(lParam
),
2283 (INT
)(SHORT
)LOWORD(lParam
), FALSE
);
2285 case EM_LINEINDEX16
:
2286 if ((INT16
)wParam
== -1) wParam
= (WPARAM
)-1;
2287 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2290 if ((short)LOWORD(lParam
) == -1)
2297 wParam
= LOWORD(lParam
);
2298 lParam
= HIWORD(lParam
);
2300 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2306 RECT16
*r16
= MapSL(lParam
);
2307 wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)&rect
, FALSE
);
2308 r16
->left
= rect
.left
;
2309 r16
->top
= rect
.top
;
2310 r16
->right
= rect
.right
;
2311 r16
->bottom
= rect
.bottom
;
2315 case EM_SETRECTNP16
:
2319 RECT16
*r16
= MapSL(lParam
);
2320 rect
.left
= r16
->left
;
2321 rect
.top
= r16
->top
;
2322 rect
.right
= r16
->right
;
2323 rect
.bottom
= r16
->bottom
;
2324 wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, (LPARAM
)&rect
, FALSE
);
2327 case EM_SETHANDLE16
:
2328 edit_set_handle( hwnd
, (HLOCAL16
)wParam
);
2330 case EM_GETHANDLE16
:
2331 result
= edit_get_handle( hwnd
);
2333 case EM_SETTABSTOPS16
:
2335 INT16
*tabs16
= MapSL(lParam
);
2336 INT i
, count
= wParam
, *tabs
= NULL
;
2339 if (!(tabs
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*tabs
) ))) return 0;
2340 for (i
= 0; i
< count
; i
++) tabs
[i
] = tabs16
[i
];
2342 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, count
, (LPARAM
)tabs
, FALSE
);
2343 HeapFree( GetProcessHeap(), 0, tabs
);
2346 case EM_GETFIRSTVISIBLELINE16
:
2347 if (!(GetWindowLongW( hwnd
, GWL_STYLE
) & ES_MULTILINE
)) break;
2348 result
= wow_handlers32
.edit_proc( hwnd
, msg
- msg16_offset
, wParam
, lParam
, FALSE
);
2350 case EM_SETWORDBREAKPROC16
:
2352 struct word_break_thunk
*thunk
= add_word_break_thunk( (EDITWORDBREAKPROC16
)lParam
);
2353 result
= wow_handlers32
.edit_proc( hwnd
, EM_SETWORDBREAKPROC
, wParam
, (LPARAM
)thunk
, FALSE
);
2356 case EM_GETWORDBREAKPROC16
:
2357 result
= wow_handlers32
.edit_proc( hwnd
, EM_GETWORDBREAKPROC
, wParam
, lParam
, FALSE
);
2358 result
= (LRESULT
)get_word_break_thunk( (EDITWORDBREAKPROCA
)result
);
2361 edit_destroy_handle( hwnd
);
2362 return wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
); /* no unlock on destroy */
2365 if (LOWORD(wParam
) == EM_GETTHUMB16
|| LOWORD(wParam
) == EM_LINESCROLL16
) wParam
-= msg16_offset
;
2366 result
= wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2369 result
= wow_handlers32
.edit_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2372 edit_unlock_buffer( hwnd
);
2377 /***********************************************************************
2380 static LRESULT
listbox_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2382 static const UINT msg16_offset
= LB_ADDSTRING16
- LB_ADDSTRING
;
2387 case LB_RESETCONTENT16
:
2388 case LB_DELETESTRING16
:
2389 case LB_GETITEMDATA16
:
2390 case LB_SETITEMDATA16
:
2392 case LB_GETTEXTLEN16
:
2393 case LB_GETCURSEL16
:
2394 case LB_GETTOPINDEX16
:
2395 case LB_GETITEMHEIGHT16
:
2396 case LB_SETCARETINDEX16
:
2397 case LB_GETCARETINDEX16
:
2398 case LB_SETTOPINDEX16
:
2399 case LB_SETCOLUMNWIDTH16
:
2400 case LB_GETSELCOUNT16
:
2401 case LB_SELITEMRANGE16
:
2402 case LB_SELITEMRANGEEX16
:
2403 case LB_GETHORIZONTALEXTENT16
:
2404 case LB_SETHORIZONTALEXTENT16
:
2405 case LB_GETANCHORINDEX16
:
2408 msg
-= msg16_offset
;
2412 case LB_SETCURSEL16
:
2413 case LB_SETANCHORINDEX16
:
2414 wParam
= (INT
)(INT16
)wParam
;
2415 msg
-= msg16_offset
;
2417 case LB_INSERTSTRING16
:
2418 case LB_FINDSTRING16
:
2419 case LB_FINDSTRINGEXACT16
:
2420 case LB_SELECTSTRING16
:
2421 wParam
= (INT
)(INT16
)wParam
;
2423 case LB_ADDSTRING16
:
2426 DWORD style
= GetWindowLongW( hwnd
, GWL_STYLE
);
2427 if ((style
& LBS_HASSTRINGS
) || !(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)))
2428 lParam
= (LPARAM
)MapSL(lParam
);
2429 msg
-= msg16_offset
;
2433 lParam
= (LPARAM
)MapSL(lParam
);
2434 msg
-= msg16_offset
;
2436 case LB_SETITEMHEIGHT16
:
2437 lParam
= LOWORD(lParam
);
2438 msg
-= msg16_offset
;
2440 case LB_GETITEMRECT16
:
2443 RECT16
*r16
= MapSL(lParam
);
2444 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_GETITEMRECT
, (INT16
)wParam
, (LPARAM
)&rect
, FALSE
);
2445 r16
->left
= rect
.left
;
2446 r16
->top
= rect
.top
;
2447 r16
->right
= rect
.right
;
2448 r16
->bottom
= rect
.bottom
;
2451 case LB_GETSELITEMS16
:
2453 INT16
*array16
= MapSL( lParam
);
2454 INT i
, count
= (INT16
)wParam
, *array
;
2455 if (!(array
= HeapAlloc( GetProcessHeap(), 0, wParam
* sizeof(*array
) ))) return LB_ERRSPACE
;
2456 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_GETSELITEMS
, count
, (LPARAM
)array
, FALSE
);
2457 for (i
= 0; i
< ret
; i
++) array16
[i
] = array
[i
];
2458 HeapFree( GetProcessHeap(), 0, array
);
2462 /* according to Win16 docs, DDL_DRIVES should make DDL_EXCLUSIVE
2463 * be set automatically (this is different in Win32) */
2464 if (wParam
& DDL_DRIVES
) wParam
|= DDL_EXCLUSIVE
;
2465 lParam
= (LPARAM
)MapSL(lParam
);
2466 msg
-= msg16_offset
;
2468 case LB_SETTABSTOPS16
:
2470 INT i
, count
, *tabs
= NULL
;
2471 INT16
*tabs16
= MapSL( lParam
);
2473 if ((count
= (INT16
)wParam
) > 0)
2475 if (!(tabs
= HeapAlloc( GetProcessHeap(), 0, wParam
* sizeof(*tabs
) ))) return LB_ERRSPACE
;
2476 for (i
= 0; i
< count
; i
++) tabs
[i
] = tabs16
[i
] << 1; /* FIXME */
2478 ret
= wow_handlers32
.listbox_proc( hwnd
, LB_SETTABSTOPS
, count
, (LPARAM
)tabs
, FALSE
);
2479 HeapFree( GetProcessHeap(), 0, tabs
);
2483 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2485 return wow_handlers32
.listbox_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2489 /***********************************************************************
2492 static LRESULT
mdiclient_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2494 if (msg
== WM_CREATE
)
2496 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
2497 HINSTANCE instance
= (HINSTANCE
)GetWindowLongPtrW( hwnd
, GWLP_HINSTANCE
);
2498 BOOL is_win32
= !instance
|| ((ULONG_PTR
)instance
>> 16);
2500 /* Translation layer doesn't know what's in the cs->lpCreateParams
2501 * so we have to keep track of what environment we're in. */
2504 void *orig
= cs
->lpCreateParams
;
2506 CLIENTCREATESTRUCT ccs
;
2507 CLIENTCREATESTRUCT16
*ccs16
= MapSL( PtrToUlong( orig
));
2509 ccs
.hWindowMenu
= HMENU_32(ccs16
->hWindowMenu
);
2510 ccs
.idFirstChild
= ccs16
->idFirstChild
;
2511 cs
->lpCreateParams
= &ccs
;
2512 ret
= wow_handlers32
.mdiclient_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2513 cs
->lpCreateParams
= orig
;
2517 return wow_handlers32
.mdiclient_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2521 /***********************************************************************
2524 static LRESULT
scrollbar_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2526 static const UINT msg16_offset
= SBM_SETPOS16
- SBM_SETPOS
;
2532 case SBM_ENABLE_ARROWS16
:
2533 msg
-= msg16_offset
;
2535 case SBM_SETRANGE16
:
2536 msg
= wParam
? SBM_SETRANGEREDRAW
: SBM_SETRANGE
;
2537 wParam
= LOWORD(lParam
);
2538 lParam
= HIWORD(lParam
);
2540 case SBM_GETRANGE16
:
2543 wow_handlers32
.scrollbar_proc( hwnd
, SBM_GETRANGE
, (WPARAM
)&min
, (LPARAM
)&max
, FALSE
);
2544 return MAKELRESULT(min
, max
);
2547 return wow_handlers32
.scrollbar_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2549 return wow_handlers32
.scrollbar_proc( hwnd
, msg
, wParam
, lParam
, FALSE
);
2553 /***********************************************************************
2556 static LRESULT
static_proc16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, BOOL unicode
)
2561 wParam
= (WPARAM
)HICON_32( (HICON16
)wParam
);
2562 return wow_handlers32
.static_proc( hwnd
, STM_SETICON
, wParam
, lParam
, FALSE
);
2564 return HICON_16( wow_handlers32
.static_proc( hwnd
, STM_GETICON
, wParam
, lParam
, FALSE
));
2566 return wow_handlers32
.static_proc( hwnd
, msg
, wParam
, lParam
, unicode
);
2571 /***********************************************************************
2574 HWND
create_window16( CREATESTRUCTW
*cs
, LPCWSTR className
, HINSTANCE instance
, BOOL unicode
)
2576 /* map to module handle */
2577 if (instance
&& !((ULONG_PTR
)instance
>> 16))
2578 instance
= HINSTANCE_32( GetExePtr( HINSTANCE_16(instance
) ));
2580 return wow_handlers32
.create_window( cs
, className
, instance
, unicode
);
2584 /***********************************************************************
2585 * cursor/icon handles
2588 static HICON
alloc_icon_handle( unsigned int size
)
2590 HGLOBAL16 handle
= GlobalAlloc16( GMEM_MOVEABLE
, size
);
2591 FarSetOwner16( handle
, 0 );
2592 return HICON_32( handle
);
2595 static struct tagCURSORICONINFO
*get_icon_ptr( HICON handle
)
2597 return GlobalLock16( HICON_16(handle
) );
2600 static void release_icon_ptr( HICON handle
, struct tagCURSORICONINFO
*ptr
)
2602 GlobalUnlock16( HICON_16(handle
) );
2605 static int free_icon_handle( HICON handle
)
2607 return GlobalFree16( HICON_16(handle
) );
2611 void register_wow_handlers(void)
2613 static const struct wow_handlers16 handlers16
=
2623 call_window_proc_Ato16
,
2624 call_dialog_proc_Ato16
,
2631 UserRegisterWowHandlers( &handlers16
, &wow_handlers32
);