2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/port.h"
31 #include "wine/winbase16.h"
32 #include "wine/winuser16.h"
33 #include "stackframe.h"
39 #include "wine/debug.h"
45 WINE_DECLARE_DEBUG_CHANNEL(msg
);
46 WINE_DECLARE_DEBUG_CHANNEL(relay
);
47 WINE_DEFAULT_DEBUG_CHANNEL(win
);
51 /* Window procedure 16-to-32-bit thunk */
54 BYTE popl_eax
; /* popl %eax (return address) */
55 BYTE pushl_func
; /* pushl $proc */
57 BYTE pushl_eax
; /* pushl %eax */
58 BYTE ljmp
; /* ljmp relay*/
59 DWORD relay_offset
; /* __wine_call_wndproc_32A/W */
61 } WINPROC_THUNK_FROM16
;
63 /* Window procedure 32-to-16-bit thunk */
66 BYTE popl_eax
; /* popl %eax (return address) */
67 BYTE pushl_func
; /* pushl $proc */
69 BYTE pushl_eax
; /* pushl %eax */
70 BYTE jmp
; /* jmp relay (relative jump)*/
71 void (*relay
)(); /* WINPROC_CallProc32ATo16() */
72 } WINPROC_THUNK_FROM32
;
74 /* Simple jmp to call 32-bit procedure directly */
77 BYTE jmp
; /* jmp proc (relative jump) */
84 WINPROC_THUNK_FROM16 t_from16
;
85 WINPROC_THUNK_FROM32 t_from32
;
88 typedef struct tagWINDOWPROC
90 WINPROC_THUNK thunk
; /* Thunk */
91 WINPROC_JUMP jmp
; /* Jump */
92 struct tagWINDOWPROC
*next
; /* Next window proc */
93 UINT magic
; /* Magic number */
94 WINDOWPROCTYPE type
; /* Function type */
95 WINDOWPROCUSER user
; /* Function user */
98 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
100 #define WINPROC_THUNKPROC(pproc) \
101 (((pproc)->type == WIN_PROC_16) ? \
102 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
103 (WNDPROC16)((pproc)->thunk.t_from16.proc))
105 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
106 UINT msg
, WPARAM wParam
,
108 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
109 UINT msg
, WPARAM wParam
,
112 #define MAX_WINPROCS (0x10000 / sizeof(WINDOWPROC))
114 static WINDOWPROC winproc_array
[MAX_WINPROCS
];
115 static WINDOWPROC
*winproc_first_free
;
116 static UINT winproc_used
;
117 static CRITICAL_SECTION winproc_cs
= CRITICAL_SECTION_INIT("winproc_cs");
119 /* allocate a window procedure from the global array */
120 static WINDOWPROC
*alloc_winproc(void)
122 WINDOWPROC
*ret
= NULL
;
124 EnterCriticalSection( &winproc_cs
);
125 if ((ret
= winproc_first_free
))
126 winproc_first_free
= ret
->next
;
127 else if (winproc_used
< MAX_WINPROCS
)
128 ret
= &winproc_array
[winproc_used
++];
129 LeaveCriticalSection( &winproc_cs
);
133 static void free_winproc( WINDOWPROC
*proc
)
135 EnterCriticalSection( &winproc_cs
);
137 proc
->next
= winproc_first_free
;
138 winproc_first_free
= proc
;
139 LeaveCriticalSection( &winproc_cs
);
142 static BOOL
is_valid_winproc( WINDOWPROC
*proc
)
144 if (proc
< winproc_array
|| proc
>= winproc_array
+ MAX_WINPROCS
) return FALSE
;
145 if (proc
!= winproc_array
+ (proc
- winproc_array
)) return FALSE
;
146 return (proc
->magic
== WINPROC_MAGIC
);
149 static WORD
get_winproc_selector(void)
151 static LONG winproc_selector
;
154 if (!(ret
= winproc_selector
))
157 WORD sel
= wine_ldt_alloc_entries(1);
158 wine_ldt_set_base( &entry
, winproc_array
);
159 wine_ldt_set_limit( &entry
, sizeof(winproc_array
) - 1 );
160 wine_ldt_set_flags( &entry
, WINE_LDT_FLAGS_CODE
| WINE_LDT_FLAGS_32BIT
);
161 wine_ldt_set_entry( sel
, &entry
);
162 if (!(ret
= InterlockedCompareExchange( &winproc_selector
, sel
, 0 ))) ret
= sel
;
163 else wine_ldt_free_entries( sel
, 1 ); /* somebody beat us to it */
170 /* Some window procedures modify register they shouldn't, or are not
171 * properly declared stdcall; so we need a small assembly wrapper to
173 extern LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
174 WPARAM wParam
, LPARAM lParam
);
175 __ASM_GLOBAL_FUNC( WINPROC_wrapper
,
185 "movl 8(%ebp),%eax\n\t"
187 "leal -12(%ebp),%esp\n\t"
194 static inline LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
195 WPARAM wParam
, LPARAM lParam
)
197 return proc( hwnd
, msg
, wParam
, lParam
);
199 #endif /* __i386__ */
201 /**********************************************************************
202 * WINPROC_CallWndProc32
204 * Call a 32-bit WndProc.
206 static LRESULT
WINPROC_CallWndProc( WNDPROC proc
, HWND hwnd
, UINT msg
,
207 WPARAM wParam
, LPARAM lParam
)
212 hwnd
= WIN_GetFullHandle( hwnd
);
214 DPRINTF( "%04lx:Call window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
215 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
216 /* To avoid any deadlocks, all the locks on the windows structures
217 must be suspended before the control is passed to the application */
218 iWndsLocks
= WIN_SuspendWndsLock();
219 retvalue
= WINPROC_wrapper( proc
, hwnd
, msg
, wParam
, lParam
);
220 WIN_RestoreWndsLock(iWndsLocks
);
223 DPRINTF( "%04lx:Ret window proc %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
224 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
, retvalue
);
228 /***********************************************************************
229 * WINPROC_CallWndProc16
231 * Call a 16-bit window procedure
233 static LRESULT WINAPI
WINPROC_CallWndProc16( WNDPROC16 proc
, HWND16 hwnd
,
234 UINT16 msg
, WPARAM16 wParam
,
241 TEB
*teb
= NtCurrentTeb();
244 /* Window procedures want ax = hInstance, ds = es = ss */
246 memset(&context
, '\0', sizeof(context
));
247 context
.SegDs
= context
.SegEs
= SELECTOROF(teb
->cur_stack
);
248 if (!(context
.Eax
= GetWindowWord( HWND_32(hwnd
), GWL_HINSTANCE
))) context
.Eax
= context
.SegDs
;
249 context
.SegCs
= SELECTOROF(proc
);
250 context
.Eip
= OFFSETOF(proc
);
251 context
.Ebp
= OFFSETOF(teb
->cur_stack
)
252 + (WORD
)&((STACK16FRAME
*)0)->bp
;
256 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
257 work if structures passed in lParam are placed in the stack/data
258 segment. Programmers easily make the mistake of converting lParam
259 to a near rather than a far pointer, since Windows apparently
260 allows this. We copy the structures to the 16 bit stack; this is
261 ugly but makes these programs work. */
266 offset
= sizeof(CREATESTRUCT16
); break;
268 offset
= sizeof(DRAWITEMSTRUCT16
); break;
270 offset
= sizeof(COMPAREITEMSTRUCT16
); break;
274 void *s
= MapSL(lParam
);
275 lParam
= stack16_push( offset
);
276 memcpy( MapSL(lParam
), s
, offset
);
280 iWndsLocks
= WIN_SuspendWndsLock();
282 args
= (WORD
*)THREAD_STACK16(teb
) - 5;
283 args
[0] = LOWORD(lParam
);
284 args
[1] = HIWORD(lParam
);
289 wine_call_to_16_regs_short( &context
, 5 * sizeof(WORD
) );
290 ret
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
291 if (offset
) stack16_pop( offset
);
293 WIN_RestoreWndsLock(iWndsLocks
);
299 /**********************************************************************
302 * Return a pointer to the win proc.
304 static WINDOWPROC
*WINPROC_GetPtr( WNDPROC handle
)
309 /* ptr cannot be < 64K */
310 if (!HIWORD(handle
)) return NULL
;
312 /* Check for a linear pointer */
314 ptr
= (BYTE
*)handle
;
315 /* First check if it is the jmp address */
316 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->jmp
);
317 if (is_valid_winproc(proc
)) return proc
;
319 /* Now it must be the thunk address */
320 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
321 if (is_valid_winproc(proc
)) return proc
;
323 /* Check for a segmented pointer */
325 if (!IsBadReadPtr16( (SEGPTR
)handle
, sizeof(proc
->thunk
) ))
327 ptr
= MapSL( (SEGPTR
)handle
);
328 /* It must be the thunk address */
329 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
330 if (is_valid_winproc(proc
)) return proc
;
337 /**********************************************************************
338 * WINPROC_AllocWinProc
340 * Allocate a new window procedure.
342 static WINDOWPROC
*WINPROC_AllocWinProc( WNDPROC func
, WINDOWPROCTYPE type
,
343 WINDOWPROCUSER user
)
345 static FARPROC16 relay_32A
, relay_32W
;
347 WINDOWPROC
*proc
, *oldproc
;
349 /* Allocate a window procedure */
351 if (!(proc
= alloc_winproc())) return 0;
353 /* Check if the function is already a win proc */
355 if ((oldproc
= WINPROC_GetPtr( func
)))
364 proc
->thunk
.t_from32
.popl_eax
= 0x58; /* popl %eax */
365 proc
->thunk
.t_from32
.pushl_func
= 0x68; /* pushl $proc */
366 proc
->thunk
.t_from32
.proc
= (WNDPROC16
)func
;
367 proc
->thunk
.t_from32
.pushl_eax
= 0x50; /* pushl %eax */
368 proc
->thunk
.t_from32
.jmp
= 0xe9; /* jmp relay*/
369 proc
->thunk
.t_from32
.relay
= /* relative jump */
370 (void(*)())((DWORD
)WINPROC_CallProc32ATo16
-
371 (DWORD
)(&proc
->thunk
.t_from32
.relay
+ 1));
374 if (!relay_32A
) relay_32A
= GetProcAddress16( GetModuleHandle16("user"),
375 "__wine_call_wndproc_32A" );
376 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
377 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
378 proc
->thunk
.t_from16
.proc
= func
;
379 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
380 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
381 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32A
);
382 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32A
);
383 proc
->jmp
.jmp
= 0xe9;
384 /* Fixup relative jump */
385 proc
->jmp
.proc
= (WNDPROC
)((DWORD
)func
- (DWORD
)(&proc
->jmp
.proc
+ 1));
388 if (!relay_32W
) relay_32W
= GetProcAddress16( GetModuleHandle16("user"),
389 "__wine_call_wndproc_32W" );
390 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
391 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
392 proc
->thunk
.t_from16
.proc
= func
;
393 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
394 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
395 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32W
);
396 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32W
);
397 proc
->jmp
.jmp
= 0xe9;
398 /* Fixup relative jump */
399 proc
->jmp
.proc
= (WNDPROC
)((char *)func
- (char *)(&proc
->jmp
.proc
+ 1));
402 /* Should not happen */
405 proc
->magic
= WINPROC_MAGIC
;
410 TRACE("(%p,%d): returning %p\n", func
, type
, proc
);
415 /**********************************************************************
418 * Get a window procedure pointer that can be passed to the Windows program.
420 WNDPROC16
WINPROC_GetProc( WNDPROC proc
, WINDOWPROCTYPE type
)
422 WINDOWPROC
*ptr
= (WINDOWPROC
*)proc
;
424 if (!proc
) return NULL
;
425 if (type
== WIN_PROC_16
) /* We want a 16:16 address */
427 if (ptr
->type
== WIN_PROC_16
)
428 return ptr
->thunk
.t_from32
.proc
;
430 return (WNDPROC16
)MAKESEGPTR( get_winproc_selector(),
431 (char *)&ptr
->thunk
- (char *)winproc_array
);
433 else /* We want a 32-bit address */
435 if (ptr
->type
== WIN_PROC_16
)
436 return (WNDPROC16
)&ptr
->thunk
;
437 else if (type
!= ptr
->type
)
438 /* Have to return the jmp address if types don't match */
439 return (WNDPROC16
)&ptr
->jmp
;
441 /* Some Win16 programs want to get back the proc they set */
442 return (WNDPROC16
)ptr
->thunk
.t_from16
.proc
;
447 /**********************************************************************
450 * Set the window procedure for a window or class. There are
451 * three tree classes of winproc callbacks:
453 * 1) class -> wp - not subclassed
454 * class -> wp -> wp -> wp -> wp - SetClassLong()
456 * 2) window -' / - not subclassed
457 * window -> wp -> wp ' - SetWindowLong()
459 * 3) timer -> wp - SetTimer()
461 * Initially, winproc of the window points to the current winproc
462 * thunk of its class. Subclassing prepends a new thunk to the
463 * window winproc chain at the head of the list. Thus, window thunk
464 * list includes class thunks and the latter are preserved when the
465 * window is destroyed.
468 BOOL
WINPROC_SetProc( WNDPROC
*pFirst
, WNDPROC func
,
469 WINDOWPROCTYPE type
, WINDOWPROCUSER user
)
471 BOOL bRecycle
= FALSE
;
472 WINDOWPROC
*proc
, **ppPrev
;
474 /* Check if function is already in the list */
476 ppPrev
= (WINDOWPROC
**)pFirst
;
477 proc
= WINPROC_GetPtr( func
);
484 if ((*ppPrev
)->user
!= user
)
486 /* terminal thunk is being restored */
488 WINPROC_FreeProc( *pFirst
, (*ppPrev
)->user
);
489 *(WINDOWPROC
**)pFirst
= *ppPrev
;
498 if (((*ppPrev
)->type
== type
) &&
499 (func
== (WNDPROC
)WINPROC_THUNKPROC(*ppPrev
)))
501 if((*ppPrev
)->user
== user
)
507 WINPROC_FreeProc( (WNDPROC
)*ppPrev
, user
);
514 /* WPF_CLASS thunk terminates window thunk list */
515 if ((*ppPrev
)->user
!= user
) break;
516 ppPrev
= &(*ppPrev
)->next
;
521 /* Extract this thunk from the list */
523 *ppPrev
= proc
->next
;
525 else /* Allocate a new one */
527 if (proc
) /* Was already a win proc */
530 func
= (WNDPROC
)WINPROC_THUNKPROC(proc
);
532 proc
= WINPROC_AllocWinProc( func
, type
, user
);
533 if (!proc
) return FALSE
;
536 /* Add the win proc at the head of the list */
538 TRACE("(%p,%p,%d): res=%p\n", *pFirst
, func
, type
, proc
);
539 proc
->next
= *(WINDOWPROC
**)pFirst
;
540 *(WINDOWPROC
**)pFirst
= proc
;
545 /**********************************************************************
548 * Free a list of win procs.
550 void WINPROC_FreeProc( WNDPROC proc
, WINDOWPROCUSER user
)
552 WINDOWPROC
*ptr
= (WINDOWPROC
*)proc
;
555 WINDOWPROC
*next
= ptr
->next
;
556 if (ptr
->user
!= user
) break;
557 TRACE("freeing %p (%d)\n", ptr
, user
);
564 /**********************************************************************
565 * WINPROC_GetProcType
567 * Return the window procedure type.
569 WINDOWPROCTYPE
WINPROC_GetProcType( WNDPROC proc
)
572 (((WINDOWPROC
*)proc
)->magic
!= WINPROC_MAGIC
))
573 return WIN_PROC_INVALID
;
574 return ((WINDOWPROC
*)proc
)->type
;
576 /**********************************************************************
577 * WINPROC_TestCBForStr
579 * Return TRUE if the lparam is a string
581 inline static BOOL
WINPROC_TestCBForStr( HWND hwnd
)
583 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
584 return (!(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) || (style
& CBS_HASSTRINGS
));
586 /**********************************************************************
587 * WINPROC_TestLBForStr
589 * Return TRUE if the lparam is a string
591 inline static BOOL
WINPROC_TestLBForStr( HWND hwnd
)
593 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
594 return (!(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) || (style
& LBS_HASSTRINGS
));
597 /**********************************************************************
598 * WINPROC_MapMsg32ATo32W
600 * Map a message from Ansi to Unicode.
601 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
604 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
605 * the first four bytes are the handle of the icon
606 * when the WM_SETTEXT message has been used to set the icon
608 INT
WINPROC_MapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
613 case WM_ASKCBFORMATNAME
:
615 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
616 *pwparam
* sizeof(WCHAR
) + sizeof(LPARAM
) );
618 *ptr
++ = *plparam
; /* Store previous lParam */
619 *plparam
= (LPARAM
)ptr
;
622 /* lparam is string (0-terminated) */
624 case WM_WININICHANGE
:
625 case WM_DEVMODECHANGE
:
631 DWORD len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)*plparam
, -1, NULL
, 0);
632 WCHAR
*buf
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
633 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)*plparam
, -1, buf
, len
);
634 *plparam
= (LPARAM
)buf
;
635 return (*plparam
? 1 : -1);
637 case WM_GETTEXTLENGTH
:
638 case CB_GETLBTEXTLEN
:
640 return 1; /* need to map result */
644 UNICODE_STRING usBuffer
;
646 { CREATESTRUCTW cs
; /* new structure */
647 LPCWSTR lpszName
; /* allocated Name */
648 LPCWSTR lpszClass
; /* allocated Class */
651 struct s
*xs
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct s
));
653 xs
->cs
= *(CREATESTRUCTW
*)*plparam
;
654 if (HIWORD(xs
->cs
.lpszName
))
656 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)xs
->cs
.lpszName
);
657 xs
->lpszName
= xs
->cs
.lpszName
= usBuffer
.Buffer
;
659 if (HIWORD(xs
->cs
.lpszClass
))
661 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)xs
->cs
.lpszClass
);
662 xs
->lpszClass
= xs
->cs
.lpszClass
= usBuffer
.Buffer
;
664 *plparam
= (LPARAM
)xs
;
669 MDICREATESTRUCTW
*cs
=
670 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
672 *cs
= *(MDICREATESTRUCTW
*)*plparam
;
673 if (HIWORD(cs
->szClass
))
675 UNICODE_STRING usBuffer
;
676 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)cs
->szClass
);
677 cs
->szClass
= usBuffer
.Buffer
;
679 if (HIWORD(cs
->szTitle
))
681 UNICODE_STRING usBuffer
;
682 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)cs
->szTitle
);
683 cs
->szTitle
= usBuffer
.Buffer
;
685 *plparam
= (LPARAM
)cs
;
691 case LB_INSERTSTRING
:
693 case LB_FINDSTRINGEXACT
:
694 case LB_SELECTSTRING
:
695 if(!*plparam
) return 0;
696 if ( WINPROC_TestLBForStr( hwnd
))
698 UNICODE_STRING usBuffer
;
699 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)*plparam
);
700 *plparam
= (LPARAM
)usBuffer
.Buffer
;
702 return (*plparam
? 1 : -1);
704 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
705 { if ( WINPROC_TestLBForStr( hwnd
))
706 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
708 *ptr
++ = *plparam
; /* Store previous lParam */
709 *plparam
= (LPARAM
)ptr
;
716 case CB_INSERTSTRING
:
717 case CB_FINDSTRINGEXACT
:
719 case CB_SELECTSTRING
:
720 if(!*plparam
) return 0;
721 if ( WINPROC_TestCBForStr( hwnd
))
723 UNICODE_STRING usBuffer
;
724 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,(LPCSTR
)*plparam
);
725 *plparam
= (LPARAM
)usBuffer
.Buffer
;
727 return (*plparam
? 1 : -1);
729 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
730 { if ( WINPROC_TestCBForStr( hwnd
))
731 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
733 *ptr
++ = *plparam
; /* Store previous lParam */
734 *plparam
= (LPARAM
)ptr
;
741 { WORD len
= (WORD
)*plparam
;
742 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(WCHAR
) );
744 *ptr
++ = *plparam
; /* Store previous lParam */
745 *((WORD
*) ptr
) = len
; /* Store the length */
746 *plparam
= (LPARAM
)ptr
;
756 case EM_SETPASSWORDCHAR
:
758 BYTE ch
= LOWORD(*pwparam
);
760 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wch
, 1);
761 *pwparam
= MAKEWPARAM( wch
, HIWORD(*pwparam
) );
769 ch
[0] = (*pwparam
>> 8);
770 ch
[1] = *pwparam
& 0xff;
771 MultiByteToWideChar(CP_ACP
, 0, ch
, 2, &wch
, 1);
772 *pwparam
= MAKEWPARAM( wch
, HIWORD(*pwparam
) );
776 case WM_PAINTCLIPBOARD
:
777 case WM_SIZECLIPBOARD
:
778 FIXME_(msg
)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg
, hwnd
), msg
);
780 default: /* No translation needed */
786 /**********************************************************************
787 * WINPROC_UnmapMsg32ATo32W
789 * Unmap a message that was mapped from Ansi to Unicode.
791 LRESULT
WINPROC_UnmapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
797 case WM_ASKCBFORMATNAME
:
799 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
800 if (wParam
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
801 (LPSTR
)*ptr
, wParam
, NULL
, NULL
))
802 ((LPSTR
)*ptr
)[wParam
-1] = 0;
803 HeapFree( GetProcessHeap(), 0, ptr
);
806 case WM_GETTEXTLENGTH
:
807 case CB_GETLBTEXTLEN
:
809 /* there may be one DBCS char for each Unicode char */
815 { CREATESTRUCTW cs
; /* new structure */
816 LPWSTR lpszName
; /* allocated Name */
817 LPWSTR lpszClass
; /* allocated Class */
819 struct s
*xs
= (struct s
*)lParam
;
820 if (xs
->lpszName
) HeapFree( GetProcessHeap(), 0, xs
->lpszName
);
821 if (xs
->lpszClass
) HeapFree( GetProcessHeap(), 0, xs
->lpszClass
);
822 HeapFree( GetProcessHeap(), 0, xs
);
828 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
829 if (HIWORD(cs
->szTitle
))
830 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
831 if (HIWORD(cs
->szClass
))
832 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
833 HeapFree( GetProcessHeap(), 0, cs
);
838 case WM_WININICHANGE
:
839 case WM_DEVMODECHANGE
:
844 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
849 case LB_INSERTSTRING
:
851 case LB_FINDSTRINGEXACT
:
852 case LB_SELECTSTRING
:
853 if ( WINPROC_TestLBForStr( hwnd
))
854 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
858 { if ( WINPROC_TestLBForStr( hwnd
))
859 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
860 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
861 HeapFree( GetProcessHeap(), 0, ptr
);
868 case CB_INSERTSTRING
:
870 case CB_FINDSTRINGEXACT
:
871 case CB_SELECTSTRING
:
872 if ( WINPROC_TestCBForStr( hwnd
))
873 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
877 { if ( WINPROC_TestCBForStr( hwnd
))
878 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
879 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
880 HeapFree( GetProcessHeap(), 0, ptr
);
887 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lParam */
888 WORD len
= *(WORD
*) lParam
;
889 if (len
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
890 (LPSTR
)*ptr
, len
, NULL
, NULL
))
891 ((LPSTR
)*ptr
)[len
-1] = 0;
892 HeapFree( GetProcessHeap(), 0, ptr
);
900 /**********************************************************************
901 * WINPROC_MapMsg32WTo32A
903 * Map a message from Unicode to Ansi.
904 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
906 INT
WINPROC_MapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
911 case WM_ASKCBFORMATNAME
:
913 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
914 *pwparam
+ sizeof(LPARAM
) );
916 *ptr
++ = *plparam
; /* Store previous lParam */
917 *plparam
= (LPARAM
)ptr
;
922 case WM_WININICHANGE
:
923 case WM_DEVMODECHANGE
:
928 if(!*plparam
) return 0;
929 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
930 return (*plparam
? 1 : -1);
935 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
938 *cs
= *(CREATESTRUCTA
*)*plparam
;
939 if (HIWORD(cs
->lpszName
))
940 cs
->lpszName
= HEAP_strdupWtoA( GetProcessHeap(), 0,
941 (LPCWSTR
)cs
->lpszName
);
942 if (HIWORD(cs
->lpszClass
))
943 cs
->lpszClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
944 (LPCWSTR
)cs
->lpszClass
);
945 *plparam
= (LPARAM
)cs
;
950 MDICREATESTRUCTA
*cs
=
951 (MDICREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
953 *cs
= *(MDICREATESTRUCTA
*)*plparam
;
954 if (HIWORD(cs
->szTitle
))
955 cs
->szTitle
= HEAP_strdupWtoA( GetProcessHeap(), 0,
956 (LPCWSTR
)cs
->szTitle
);
957 if (HIWORD(cs
->szClass
))
958 cs
->szClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
959 (LPCWSTR
)cs
->szClass
);
960 *plparam
= (LPARAM
)cs
;
966 case LB_INSERTSTRING
:
968 case LB_FINDSTRINGEXACT
:
969 case LB_SELECTSTRING
:
970 if(!*plparam
) return 0;
971 if ( WINPROC_TestLBForStr( hwnd
))
972 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
973 return (*plparam
? 1 : -1);
975 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
976 { if ( WINPROC_TestLBForStr( hwnd
))
977 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
979 *ptr
++ = *plparam
; /* Store previous lParam */
980 *plparam
= (LPARAM
)ptr
;
987 case CB_INSERTSTRING
:
989 case CB_FINDSTRINGEXACT
:
990 case CB_SELECTSTRING
:
991 if(!*plparam
) return 0;
992 if ( WINPROC_TestCBForStr( hwnd
))
993 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
994 return (*plparam
? 1 : -1);
996 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
997 { if ( WINPROC_TestCBForStr( hwnd
))
998 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
1000 *ptr
++ = *plparam
; /* Store previous lParam */
1001 *plparam
= (LPARAM
)ptr
;
1006 /* Multiline edit */
1008 { WORD len
= (WORD
)*plparam
;
1009 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(CHAR
) );
1010 if (!ptr
) return -1;
1011 *ptr
++ = *plparam
; /* Store previous lParam */
1012 *((WORD
*) ptr
) = len
; /* Store the length */
1013 *plparam
= (LPARAM
)ptr
;
1022 case WM_SYSDEADCHAR
:
1023 case EM_SETPASSWORDCHAR
:
1025 WCHAR wch
= LOWORD(*pwparam
);
1027 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
1028 *pwparam
= MAKEWPARAM( ch
, HIWORD(*pwparam
) );
1034 WCHAR wch
= LOWORD(*pwparam
);
1038 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, ch
, 2, NULL
, NULL
);
1039 *pwparam
= MAKEWPARAM( (ch
[0] << 8) | ch
[1], HIWORD(*pwparam
) );
1043 case WM_PAINTCLIPBOARD
:
1044 case WM_SIZECLIPBOARD
:
1045 FIXME_(msg
)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg
, hwnd
),msg
);
1047 default: /* No translation needed */
1053 /**********************************************************************
1054 * WINPROC_UnmapMsg32WTo32A
1056 * Unmap a message that was mapped from Unicode to Ansi.
1058 void WINPROC_UnmapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1063 case WM_ASKCBFORMATNAME
:
1065 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1068 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, wParam
))
1069 ((LPWSTR
)*ptr
)[wParam
-1] = 0;
1071 HeapFree( GetProcessHeap(), 0, ptr
);
1076 case WM_WININICHANGE
:
1077 case WM_DEVMODECHANGE
:
1082 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1088 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1089 if (HIWORD(cs
->lpszName
))
1090 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszName
);
1091 if (HIWORD(cs
->lpszClass
))
1092 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszClass
);
1093 HeapFree( GetProcessHeap(), 0, cs
);
1099 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1100 if (HIWORD(cs
->szTitle
))
1101 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
1102 if (HIWORD(cs
->szClass
))
1103 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
1104 HeapFree( GetProcessHeap(), 0, cs
);
1110 case LB_INSERTSTRING
:
1112 case LB_FINDSTRINGEXACT
:
1113 case LB_SELECTSTRING
:
1114 if ( WINPROC_TestLBForStr( hwnd
))
1115 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1119 if ( WINPROC_TestLBForStr( hwnd
))
1121 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1122 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1123 HeapFree( GetProcessHeap(), 0, ptr
);
1129 case CB_INSERTSTRING
:
1131 case CB_FINDSTRINGEXACT
:
1132 case CB_SELECTSTRING
:
1133 if ( WINPROC_TestCBForStr( hwnd
))
1134 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1138 if ( WINPROC_TestCBForStr( hwnd
))
1140 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1141 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1142 HeapFree( GetProcessHeap(), 0, ptr
);
1146 /* Multiline edit */
1148 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lparam */
1149 WORD len
= *(WORD
*)ptr
;
1152 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, len
))
1153 ((LPWSTR
)*ptr
)[len
-1] = 0;
1155 HeapFree( GetProcessHeap(), 0, ptr
);
1161 static UINT
convert_handle_16_to_32(HANDLE16 src
, unsigned int flags
)
1164 UINT sz
= GlobalSize16(src
);
1167 if (!(dst
= GlobalAlloc(flags
, sz
)))
1169 ptr16
= GlobalLock16(src
);
1170 ptr32
= GlobalLock(dst
);
1171 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr32
, ptr16
, sz
);
1172 GlobalUnlock16(src
);
1178 /**********************************************************************
1179 * WINPROC_MapMsg16To32A
1181 * Map a message from 16- to 32-bit Ansi.
1182 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1184 INT
WINPROC_MapMsg16To32A( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1185 WPARAM
*pwparam32
, LPARAM
*plparam
)
1187 *pmsg32
= (UINT
)msg16
;
1188 *pwparam32
= (WPARAM
)wParam16
;
1195 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1196 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1200 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1201 *plparam
= (LPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1204 if ( HIWORD(*plparam
) > CTLCOLOR_STATIC
) return -1;
1205 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
1206 *pwparam32
= (WPARAM
)HDC_32(wParam16
);
1207 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1209 case WM_COMPAREITEM
:
1211 COMPAREITEMSTRUCT16
* cis16
= MapSL(*plparam
);
1212 COMPAREITEMSTRUCT
*cis
= (COMPAREITEMSTRUCT
*)
1213 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis
));
1214 if (!cis
) return -1;
1215 cis
->CtlType
= cis16
->CtlType
;
1216 cis
->CtlID
= cis16
->CtlID
;
1217 cis
->hwndItem
= WIN_Handle32( cis16
->hwndItem
);
1218 cis
->itemID1
= cis16
->itemID1
;
1219 cis
->itemData1
= cis16
->itemData1
;
1220 cis
->itemID2
= cis16
->itemID2
;
1221 cis
->itemData2
= cis16
->itemData2
;
1222 cis
->dwLocaleId
= 0; /* FIXME */
1223 *plparam
= (LPARAM
)cis
;
1228 DELETEITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1229 DELETEITEMSTRUCT
*dis
= (DELETEITEMSTRUCT
*)
1230 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis
));
1231 if (!dis
) return -1;
1232 dis
->CtlType
= dis16
->CtlType
;
1233 dis
->CtlID
= dis16
->CtlID
;
1234 dis
->hwndItem
= WIN_Handle32( dis16
->hwndItem
);
1235 dis
->itemData
= dis16
->itemData
;
1236 *plparam
= (LPARAM
)dis
;
1239 case WM_MEASUREITEM
:
1241 MEASUREITEMSTRUCT16
* mis16
= MapSL(*plparam
);
1242 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)
1243 HeapAlloc(GetProcessHeap(), 0,
1244 sizeof(*mis
) + sizeof(LPARAM
));
1245 if (!mis
) return -1;
1246 mis
->CtlType
= mis16
->CtlType
;
1247 mis
->CtlID
= mis16
->CtlID
;
1248 mis
->itemID
= mis16
->itemID
;
1249 mis
->itemWidth
= mis16
->itemWidth
;
1250 mis
->itemHeight
= mis16
->itemHeight
;
1251 mis
->itemData
= mis16
->itemData
;
1252 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1253 *plparam
= (LPARAM
)mis
;
1258 DRAWITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1259 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)HeapAlloc(GetProcessHeap(), 0,
1261 if (!dis
) return -1;
1262 dis
->CtlType
= dis16
->CtlType
;
1263 dis
->CtlID
= dis16
->CtlID
;
1264 dis
->itemID
= dis16
->itemID
;
1265 dis
->itemAction
= dis16
->itemAction
;
1266 dis
->itemState
= dis16
->itemState
;
1267 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND
)HMENU_32(dis16
->hwndItem
)
1268 : WIN_Handle32( dis16
->hwndItem
);
1269 dis
->hDC
= HDC_32(dis16
->hDC
);
1270 dis
->itemData
= dis16
->itemData
;
1271 CONV_RECT16TO32( &dis16
->rcItem
, &dis
->rcItem
);
1272 *plparam
= (LPARAM
)dis
;
1275 case WM_GETMINMAXINFO
:
1277 MINMAXINFO
*mmi
= (MINMAXINFO
*)HeapAlloc( GetProcessHeap(), 0,
1278 sizeof(*mmi
) + sizeof(LPARAM
));
1279 if (!mmi
) return -1;
1280 STRUCT32_MINMAXINFO16to32( MapSL(*plparam
), mmi
);
1281 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1282 *plparam
= (LPARAM
)mmi
;
1287 case WM_WININICHANGE
:
1288 case WM_DEVMODECHANGE
:
1289 case WM_ASKCBFORMATNAME
:
1290 *plparam
= (LPARAM
)MapSL(*plparam
);
1294 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1295 MDICREATESTRUCTA
*cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) + sizeof(LPARAM
) );
1297 STRUCT32_MDICREATESTRUCT16to32A( cs16
, cs
);
1298 cs
->szTitle
= MapSL(cs16
->szTitle
);
1299 cs
->szClass
= MapSL(cs16
->szClass
);
1300 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1301 *plparam
= (LPARAM
)cs
;
1304 case WM_MDIGETACTIVE
:
1305 *plparam
= (LPARAM
)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL
) );
1306 *(BOOL
*)(*plparam
) = 0;
1310 *pmsg32
=WM_MDIREFRESHMENU
;
1311 *pwparam32
= (WPARAM
)HMENU_32(LOWORD(*plparam
));
1312 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1315 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1316 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1319 if((LOWORD(*plparam
) & MF_POPUP
) && (LOWORD(*plparam
) != 0xFFFF))
1321 HMENU hmenu
=HMENU_32(HIWORD(*plparam
));
1322 UINT Pos
=MENU_FindSubMenu( &hmenu
, HMENU_32(wParam16
));
1323 if(Pos
==0xFFFF) Pos
=0; /* NO_SELECTED_ITEM */
1324 *pwparam32
= MAKEWPARAM( Pos
, LOWORD(*plparam
) );
1326 else *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1327 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1329 case WM_MDIACTIVATE
:
1332 *pwparam32
= (WPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1333 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1335 else /* message sent to MDI client */
1336 *pwparam32
= wParam16
;
1340 NCCALCSIZE_PARAMS16
*nc16
;
1341 NCCALCSIZE_PARAMS
*nc
;
1343 nc
= (NCCALCSIZE_PARAMS
*)HeapAlloc( GetProcessHeap(), 0,
1344 sizeof(*nc
) + sizeof(LPARAM
) );
1346 nc16
= MapSL(*plparam
);
1347 CONV_RECT16TO32( &nc16
->rgrc
[0], &nc
->rgrc
[0] );
1350 nc
->lppos
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1351 sizeof(*nc
->lppos
) );
1352 CONV_RECT16TO32( &nc16
->rgrc
[1], &nc
->rgrc
[1] );
1353 CONV_RECT16TO32( &nc16
->rgrc
[2], &nc
->rgrc
[2] );
1354 if (nc
->lppos
) STRUCT32_WINDOWPOS16to32( MapSL(nc16
->lppos
), nc
->lppos
);
1356 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1357 *plparam
= (LPARAM
)nc
;
1363 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1364 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
1365 sizeof(*cs
) + sizeof(LPARAM
) );
1367 STRUCT32_CREATESTRUCT16to32A( cs16
, cs
);
1368 cs
->lpszName
= MapSL(cs16
->lpszName
);
1369 cs
->lpszClass
= MapSL(cs16
->lpszClass
);
1370 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1371 *plparam
= (LPARAM
)cs
;
1374 case WM_PARENTNOTIFY
:
1375 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
1377 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1378 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1381 case WM_WINDOWPOSCHANGING
:
1382 case WM_WINDOWPOSCHANGED
:
1384 WINDOWPOS
*wp
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1385 sizeof(*wp
) + sizeof(LPARAM
) );
1387 STRUCT32_WINDOWPOS16to32( MapSL(*plparam
), wp
);
1388 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1389 *plparam
= (LPARAM
)wp
;
1395 LPMSG16 msg16
= MapSL(*plparam
);
1396 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1398 if (!msg32
) return -1;
1399 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1400 msg32
->lParam
= msg16
->lParam
;
1401 msg32
->time
= msg16
->time
;
1402 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1403 /* this is right, right? */
1404 if (WINPROC_MapMsg16To32A( msg32
->hwnd
, msg16
->message
,msg16
->wParam
,
1405 &msg32
->message
,&msg32
->wParam
,
1406 &msg32
->lParam
)<0) {
1407 HeapFree( GetProcessHeap(), 0, msg32
);
1410 *plparam
= (LPARAM
)msg32
;
1415 *plparam
= (LPARAM
)MapSL(*plparam
);
1417 case WM_ACTIVATEAPP
:
1418 /* We need this when SetActiveWindow sends a Sendmessage16() to
1419 * a 32bit window. Might be superflous with 32bit interprocess
1420 * message queues. */
1421 if (*plparam
) *plparam
= HTASK_32( *plparam
);
1425 MDINEXTMENU
*next
= HeapAlloc( GetProcessHeap(), 0, sizeof(*next
) );
1426 if (!next
) return -1;
1427 next
->hmenuIn
= (HMENU
)*plparam
;
1428 next
->hmenuNext
= 0;
1430 *plparam
= (LPARAM
)next
;
1433 case WM_PAINTCLIPBOARD
:
1434 case WM_SIZECLIPBOARD
:
1435 FIXME_(msg
)("message %04x needs translation\n",msg16
);
1437 case WM_DDE_INITIATE
:
1438 case WM_DDE_TERMINATE
:
1439 case WM_DDE_UNADVISE
:
1440 case WM_DDE_REQUEST
:
1441 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1451 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1452 lo16
= LOWORD(*plparam
);
1453 hi
= HIWORD(*plparam
);
1454 if (lo16
&& !(lo32
= convert_handle_16_to_32(lo16
, GMEM_DDESHARE
)))
1456 *plparam
= PackDDElParam(msg16
, lo32
, hi
);
1458 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1465 *pwparam32
= (WPARAM
)WIN_Handle32(wParam16
);
1467 lo
= LOWORD(*plparam
);
1468 hi
= HIWORD(*plparam
);
1470 if (GlobalGetAtomNameA(hi
, buf
, 2) > 0) flag
|= 1;
1471 if (GlobalSize16(hi
) != 0) flag
|= 2;
1477 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1482 break; /* atom, nothing to do */
1484 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
1487 hi
= convert_handle_16_to_32(hi
, GMEM_DDESHARE
);
1490 *plparam
= PackDDElParam(WM_DDE_ACK
, lo
, hi
);
1492 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1493 case WM_DDE_EXECUTE
:
1494 *plparam
= convert_handle_16_to_32(*plparam
, GMEM_DDESHARE
);
1495 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1496 default: /* No translation needed */
1502 /**********************************************************************
1503 * WINPROC_UnmapMsg16To32A
1505 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1507 LRESULT
WINPROC_UnmapMsg16To32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1512 case WM_COMPAREITEM
:
1515 HeapFree( GetProcessHeap(), 0, (LPVOID
)lParam
);
1517 case WM_MEASUREITEM
:
1519 MEASUREITEMSTRUCT16
*mis16
;
1520 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)lParam
;
1521 lParam
= *(LPARAM
*)(mis
+ 1);
1522 mis16
= MapSL(lParam
);
1523 mis16
->itemWidth
= (UINT16
)mis
->itemWidth
;
1524 mis16
->itemHeight
= (UINT16
)mis
->itemHeight
;
1525 HeapFree( GetProcessHeap(), 0, mis
);
1528 case WM_GETMINMAXINFO
:
1530 MINMAXINFO
*mmi
= (MINMAXINFO
*)lParam
;
1531 lParam
= *(LPARAM
*)(mmi
+ 1);
1532 STRUCT32_MINMAXINFO32to16( mmi
, MapSL(lParam
));
1533 HeapFree( GetProcessHeap(), 0, mmi
);
1538 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1539 lParam
= *(LPARAM
*)(cs
+ 1);
1540 STRUCT32_MDICREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1541 HeapFree( GetProcessHeap(), 0, cs
);
1544 case WM_MDIGETACTIVE
:
1545 result
= MAKELONG( LOWORD(result
), (BOOL16
)(*(BOOL
*)lParam
) );
1546 HeapFree( GetProcessHeap(), 0, (BOOL
*)lParam
);
1550 NCCALCSIZE_PARAMS16
*nc16
;
1551 NCCALCSIZE_PARAMS
*nc
= (NCCALCSIZE_PARAMS
*)lParam
;
1552 lParam
= *(LPARAM
*)(nc
+ 1);
1553 nc16
= MapSL(lParam
);
1554 CONV_RECT32TO16( &nc
->rgrc
[0], &nc16
->rgrc
[0] );
1557 CONV_RECT32TO16( &nc
->rgrc
[1], &nc16
->rgrc
[1] );
1558 CONV_RECT32TO16( &nc
->rgrc
[2], &nc16
->rgrc
[2] );
1561 STRUCT32_WINDOWPOS32to16( nc
->lppos
, MapSL(nc16
->lppos
));
1562 HeapFree( GetProcessHeap(), 0, nc
->lppos
);
1565 HeapFree( GetProcessHeap(), 0, nc
);
1571 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1572 lParam
= *(LPARAM
*)(cs
+ 1);
1573 STRUCT32_CREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1574 HeapFree( GetProcessHeap(), 0, cs
);
1577 case WM_WINDOWPOSCHANGING
:
1578 case WM_WINDOWPOSCHANGED
:
1580 WINDOWPOS
*wp
= (WINDOWPOS
*)lParam
;
1581 lParam
= *(LPARAM
*)(wp
+ 1);
1582 STRUCT32_WINDOWPOS32to16(wp
, MapSL(lParam
));
1583 HeapFree( GetProcessHeap(), 0, wp
);
1589 LPMSG msg32
= (LPMSG
)lParam
;
1591 WINPROC_UnmapMsg16To32A( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1593 HeapFree( GetProcessHeap(), 0, msg32
);
1598 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1599 result
= MAKELONG( HMENU_16(next
->hmenuNext
), HWND_16(next
->hwndNext
) );
1600 HeapFree( GetProcessHeap(), 0, next
);
1608 /**********************************************************************
1609 * WINPROC_MapMsg16To32W
1611 * Map a message from 16- to 32-bit Unicode.
1612 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1614 INT
WINPROC_MapMsg16To32W( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1615 WPARAM
*pwparam32
, LPARAM
*plparam
)
1620 *pmsg32
=(UINT
)msg16
;
1621 *pwparam32
= (WPARAM
)wParam16
;
1626 case WM_WININICHANGE
:
1627 case WM_DEVMODECHANGE
:
1628 case WM_ASKCBFORMATNAME
:
1629 *plparam
= (LPARAM
)MapSL(*plparam
);
1630 return WINPROC_MapMsg32ATo32W( hwnd
, *pmsg32
, pwparam32
, plparam
);
1631 case WM_GETTEXTLENGTH
:
1632 case CB_GETLBTEXTLEN
:
1634 return 1; /* need to map result */
1638 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1639 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1640 sizeof(*cs
) + sizeof(LPARAM
) );
1642 STRUCT32_CREATESTRUCT16to32A( cs16
, (CREATESTRUCTA
*)cs
);
1643 cs
->lpszName
= map_str_16_to_32W(cs16
->lpszName
);
1644 cs
->lpszClass
= map_str_16_to_32W(cs16
->lpszClass
);
1645 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1646 *plparam
= (LPARAM
)cs
;
1651 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1652 MDICREATESTRUCTW
*cs
=
1653 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1654 sizeof(*cs
) + sizeof(LPARAM
) );
1656 STRUCT32_MDICREATESTRUCT16to32A( cs16
, (MDICREATESTRUCTA
*)cs
);
1657 cs
->szTitle
= map_str_16_to_32W(cs16
->szTitle
);
1658 cs
->szClass
= map_str_16_to_32W(cs16
->szClass
);
1659 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1660 *plparam
= (LPARAM
)cs
;
1666 LPMSG16 msg16
= MapSL(*plparam
);
1667 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1669 if (!msg32
) return -1;
1670 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1671 msg32
->lParam
= msg16
->lParam
;
1672 msg32
->time
= msg16
->time
;
1673 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1674 /* this is right, right? */
1675 if (WINPROC_MapMsg16To32W(hwnd
, msg16
->message
,msg16
->wParam
,
1676 &msg32
->message
,&msg32
->wParam
,
1677 &msg32
->lParam
)<0) {
1678 HeapFree( GetProcessHeap(), 0, msg32
);
1681 *plparam
= (LPARAM
)msg32
;
1688 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1689 *pwparam32
= MAKEWPARAM( wch
, HIWORD(*plparam
) );
1690 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1694 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1695 *pwparam32
= MAKEWPARAM( wch
, LOWORD(*plparam
) );
1696 *plparam
= (LPARAM
)HMENU_32(HIWORD(*plparam
));
1701 case WM_SYSDEADCHAR
:
1703 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1709 ch
[0] = (wParam16
>> 8);
1710 ch
[1] = wParam16
& 0xff;
1711 MultiByteToWideChar(CP_ACP
, 0, ch
, 2, &wch
, 1);
1716 default: /* No Unicode translation needed */
1717 return WINPROC_MapMsg16To32A( hwnd
, msg16
, wParam16
, pmsg32
,
1718 pwparam32
, plparam
);
1723 /**********************************************************************
1724 * WINPROC_UnmapMsg16To32W
1726 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1728 LRESULT
WINPROC_UnmapMsg16To32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1735 case WM_GETTEXTLENGTH
:
1736 case CB_GETLBTEXTLEN
:
1738 case WM_ASKCBFORMATNAME
:
1739 return WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
1743 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)lParam
;
1744 lParam
= *(LPARAM
*)(cs
+ 1);
1745 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs
, MapSL(lParam
) );
1746 unmap_str_16_to_32W( cs
->lpszName
);
1747 unmap_str_16_to_32W( cs
->lpszClass
);
1748 HeapFree( GetProcessHeap(), 0, cs
);
1753 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
1754 lParam
= *(LPARAM
*)(cs
+ 1);
1755 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs
, MapSL(lParam
) );
1756 unmap_str_16_to_32W( cs
->szTitle
);
1757 unmap_str_16_to_32W( cs
->szClass
);
1758 HeapFree( GetProcessHeap(), 0, cs
);
1764 LPMSG msg32
= (LPMSG
)lParam
;
1766 WINPROC_UnmapMsg16To32W( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1768 HeapFree( GetProcessHeap(), 0, msg32
);
1772 return WINPROC_UnmapMsg16To32A( hwnd
, msg
, wParam
, lParam
, result
);
1777 static HANDLE16
convert_handle_32_to_16(UINT src
, unsigned int flags
)
1780 UINT sz
= GlobalSize((HANDLE
)src
);
1783 if (!(dst
= GlobalAlloc16(flags
, sz
)))
1785 ptr32
= GlobalLock((HANDLE
)src
);
1786 ptr16
= GlobalLock16(dst
);
1787 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr16
, ptr32
, sz
);
1788 GlobalUnlock((HANDLE
)src
);
1789 GlobalUnlock16(dst
);
1795 /**********************************************************************
1796 * WINPROC_MapMsg32ATo16
1798 * Map a message from 32-bit Ansi to 16-bit.
1799 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1801 INT
WINPROC_MapMsg32ATo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
1802 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
1805 *pmsg16
= (UINT16
)msg32
;
1806 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1814 *pmsg16
= (UINT16
)msg32
+ (BM_GETCHECK16
- BM_GETCHECK
);
1823 case EM_SCROLLCARET
:
1826 case EM_GETLINECOUNT
:
1838 case EM_LINEFROMCHAR
:
1839 case EM_SETTABSTOPS
:
1840 case EM_SETPASSWORDCHAR
:
1841 case EM_EMPTYUNDOBUFFER
:
1842 case EM_GETFIRSTVISIBLELINE
:
1843 case EM_SETREADONLY
:
1844 case EM_SETWORDBREAKPROC
:
1845 case EM_GETWORDBREAKPROC
:
1846 case EM_GETPASSWORDCHAR
:
1847 *pmsg16
= (UINT16
)msg32
+ (EM_GETSEL16
- EM_GETSEL
);
1852 case LB_DELETESTRING
:
1853 case LB_GETANCHORINDEX
:
1854 case LB_GETCARETINDEX
:
1857 case LB_GETHORIZONTALEXTENT
:
1858 case LB_GETITEMDATA
:
1859 case LB_GETITEMHEIGHT
:
1861 case LB_GETSELCOUNT
:
1863 case LB_GETTOPINDEX
:
1864 case LB_RESETCONTENT
:
1865 case LB_SELITEMRANGE
:
1866 case LB_SELITEMRANGEEX
:
1867 case LB_SETANCHORINDEX
:
1868 case LB_SETCARETINDEX
:
1869 case LB_SETCOLUMNWIDTH
:
1871 case LB_SETHORIZONTALEXTENT
:
1872 case LB_SETITEMDATA
:
1873 case LB_SETITEMHEIGHT
:
1875 case LB_SETTOPINDEX
:
1876 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1878 case CB_DELETESTRING
:
1880 case CB_GETLBTEXTLEN
:
1882 case CB_RESETCONTENT
:
1886 case CB_SHOWDROPDOWN
:
1887 case CB_SETITEMDATA
:
1888 case CB_SETITEMHEIGHT
:
1889 case CB_GETITEMHEIGHT
:
1890 case CB_SETEXTENDEDUI
:
1891 case CB_GETEXTENDEDUI
:
1892 case CB_GETDROPPEDSTATE
:
1893 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1896 *pmsg16
= CB_GETEDITSEL16
;
1901 case LB_FINDSTRINGEXACT
:
1902 case LB_INSERTSTRING
:
1903 case LB_SELECTSTRING
:
1906 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1907 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1912 case CB_FINDSTRINGEXACT
:
1913 case CB_INSERTSTRING
:
1914 case CB_SELECTSTRING
:
1916 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1917 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1920 case LB_GETITEMRECT
:
1922 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1923 if (!rect
) return -1;
1924 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1925 *plparam
= MapLS( rect
);
1927 *pmsg16
= LB_GETITEMRECT16
;
1929 case LB_GETSELITEMS
:
1932 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1933 if (!(items
= HeapAlloc( GetProcessHeap(), 0,
1934 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1935 *((LPARAM
*)items
)++ = *plparam
; /* Store the previous lParam */
1936 *plparam
= MapLS( items
);
1938 *pmsg16
= LB_GETSELITEMS16
;
1940 case LB_SETTABSTOPS
:
1945 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1946 if (!(stops
= HeapAlloc( GetProcessHeap(), 0,
1947 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1948 for (i
= 0; i
< *pwparam16
; i
++) stops
[i
] = *((LPINT
)*plparam
+i
);
1949 *plparam
= MapLS( stops
);
1952 *pmsg16
= LB_SETTABSTOPS16
;
1955 case CB_GETDROPPEDCONTROLRECT
:
1957 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1958 if (!rect
) return -1;
1959 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1960 *plparam
= (LPARAM
)MapLS(rect
);
1962 *pmsg16
= CB_GETDROPPEDCONTROLRECT16
;
1966 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1967 *pmsg16
= LB_GETTEXT16
;
1971 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1972 *pmsg16
= CB_GETLBTEXT16
;
1977 *plparam
= MAKELONG( (INT16
)(INT
)wParam32
, (INT16
)*plparam
);
1978 *pmsg16
= EM_SETSEL16
;
1985 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
1989 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
1991 case WM_CTLCOLORMSGBOX
:
1992 case WM_CTLCOLOREDIT
:
1993 case WM_CTLCOLORLISTBOX
:
1994 case WM_CTLCOLORBTN
:
1995 case WM_CTLCOLORDLG
:
1996 case WM_CTLCOLORSCROLLBAR
:
1997 case WM_CTLCOLORSTATIC
:
1998 *pmsg16
= WM_CTLCOLOR
;
1999 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
2000 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
2002 case WM_COMPAREITEM
:
2004 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)*plparam
;
2005 COMPAREITEMSTRUCT16
*cis
= HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16
));
2006 if (!cis
) return -1;
2007 cis
->CtlType
= (UINT16
)cis32
->CtlType
;
2008 cis
->CtlID
= (UINT16
)cis32
->CtlID
;
2009 cis
->hwndItem
= HWND_16( cis32
->hwndItem
);
2010 cis
->itemID1
= (UINT16
)cis32
->itemID1
;
2011 cis
->itemData1
= cis32
->itemData1
;
2012 cis
->itemID2
= (UINT16
)cis32
->itemID2
;
2013 cis
->itemData2
= cis32
->itemData2
;
2014 *plparam
= MapLS( cis
);
2019 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)*plparam
;
2020 DELETEITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16
) );
2021 if (!dis
) return -1;
2022 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
2023 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
2024 dis
->itemID
= (UINT16
)dis32
->itemID
;
2025 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
2026 : HWND_16( dis32
->hwndItem
);
2027 dis
->itemData
= dis32
->itemData
;
2028 *plparam
= MapLS( dis
);
2033 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)*plparam
;
2034 DRAWITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16
) );
2035 if (!dis
) return -1;
2036 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
2037 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
2038 dis
->itemID
= (UINT16
)dis32
->itemID
;
2039 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
2040 dis
->itemState
= (UINT16
)dis32
->itemState
;
2041 dis
->hwndItem
= HWND_16( dis32
->hwndItem
);
2042 dis
->hDC
= HDC_16(dis32
->hDC
);
2043 dis
->itemData
= dis32
->itemData
;
2044 CONV_RECT32TO16( &dis32
->rcItem
, &dis
->rcItem
);
2045 *plparam
= MapLS( dis
);
2048 case WM_MEASUREITEM
:
2050 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)*plparam
;
2051 MEASUREITEMSTRUCT16
*mis
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mis
)+sizeof(LPARAM
));
2052 if (!mis
) return -1;
2053 mis
->CtlType
= (UINT16
)mis32
->CtlType
;
2054 mis
->CtlID
= (UINT16
)mis32
->CtlID
;
2055 mis
->itemID
= (UINT16
)mis32
->itemID
;
2056 mis
->itemWidth
= (UINT16
)mis32
->itemWidth
;
2057 mis
->itemHeight
= (UINT16
)mis32
->itemHeight
;
2058 mis
->itemData
= mis32
->itemData
;
2059 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
2060 *plparam
= MapLS( mis
);
2063 case WM_GETMINMAXINFO
:
2065 MINMAXINFO16
*mmi
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi
) + sizeof(LPARAM
) );
2066 if (!mmi
) return -1;
2067 STRUCT32_MINMAXINFO32to16( (MINMAXINFO
*)*plparam
, mmi
);
2068 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
2069 *plparam
= MapLS( mmi
);
2073 case WM_ASKCBFORMATNAME
:
2076 *pwparam16
= (WPARAM16
)min( wParam32
, 0xff80 ); /* Must be < 64K */
2077 if (!(str
= HeapAlloc( GetProcessHeap(), 0, *pwparam16
+ sizeof(LPARAM
)))) return -1;
2078 *((LPARAM
*)str
)++ = *plparam
; /* Store the previous lParam */
2079 *plparam
= MapLS( str
);
2084 MDICREATESTRUCT16
*cs
;
2085 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)*plparam
;
2087 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2088 STRUCT32_MDICREATESTRUCT32Ato16( cs32
, cs
);
2089 cs
->szTitle
= MapLS( cs32
->szTitle
);
2090 cs
->szClass
= MapLS( cs32
->szClass
);
2091 *plparam
= MapLS( cs
);
2094 case WM_MDIGETACTIVE
:
2097 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
2098 (HMENU16
)LOWORD(*plparam
) );
2099 *pwparam16
= (*plparam
== 0);
2102 if(HIWORD(wParam32
) & MF_POPUP
)
2105 if (((UINT
)HIWORD(wParam32
) != 0xFFFF) || (*plparam
))
2107 if((hmenu
= GetSubMenu((HMENU
)*plparam
, *pwparam16
)))
2108 *pwparam16
=HMENU_16(hmenu
);
2113 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2115 case WM_MDIACTIVATE
:
2116 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2118 *pwparam16
= ((HWND
)*plparam
== hwnd
);
2119 *plparam
= MAKELPARAM( (HWND16
)LOWORD(*plparam
),
2120 (HWND16
)LOWORD(wParam32
) );
2124 *pwparam16
= HWND_16( (HWND
)wParam32
);
2130 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)*plparam
;
2131 NCCALCSIZE_PARAMS16
*nc
= HeapAlloc( GetProcessHeap(), 0, sizeof(*nc
) + sizeof(LPARAM
));
2134 CONV_RECT32TO16( &nc32
->rgrc
[0], &nc
->rgrc
[0] );
2138 CONV_RECT32TO16( &nc32
->rgrc
[1], &nc
->rgrc
[1] );
2139 CONV_RECT32TO16( &nc32
->rgrc
[2], &nc
->rgrc
[2] );
2140 if (!(wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16
) )))
2142 HeapFree( GetProcessHeap(), 0, nc
);
2145 STRUCT32_WINDOWPOS32to16( nc32
->lppos
, wp
);
2146 nc
->lppos
= MapLS( wp
);
2148 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
2149 *plparam
= MapLS( nc
);
2156 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)*plparam
;
2158 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2159 STRUCT32_CREATESTRUCT32Ato16( cs32
, cs
);
2160 cs
->lpszName
= MapLS( cs32
->lpszName
);
2161 cs
->lpszClass
= MapLS( cs32
->lpszClass
);
2162 *plparam
= MapLS( cs
);
2165 case WM_PARENTNOTIFY
:
2166 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
2167 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
2168 /* else nothing to do */
2171 *plparam
= MapLS( (NMHDR
*)*plparam
); /* NMHDR is already 32-bit */
2174 case WM_WININICHANGE
:
2175 case WM_DEVMODECHANGE
:
2176 *plparam
= MapLS( (LPSTR
)*plparam
);
2178 case WM_WINDOWPOSCHANGING
:
2179 case WM_WINDOWPOSCHANGED
:
2181 WINDOWPOS16
*wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(*wp
) + sizeof(LPARAM
) );
2183 STRUCT32_WINDOWPOS32to16( (WINDOWPOS
*)*plparam
, wp
);
2184 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
2185 *plparam
= MapLS( wp
);
2190 LPMSG msg32
= (LPMSG
) *plparam
;
2191 LPMSG16 msg16
= HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16
) );
2193 if (!msg16
) return -1;
2194 msg16
->hwnd
= HWND_16( msg32
->hwnd
);
2195 msg16
->lParam
= msg32
->lParam
;
2196 msg16
->time
= msg32
->time
;
2197 CONV_POINT32TO16(&msg32
->pt
,&msg16
->pt
);
2198 /* this is right, right? */
2199 if (WINPROC_MapMsg32ATo16(msg32
->hwnd
,msg32
->message
,msg32
->wParam
,
2200 &msg16
->message
,&msg16
->wParam
, &msg16
->lParam
)<0)
2202 HeapFree( GetProcessHeap(), 0, msg16
);
2205 *plparam
= MapLS( msg16
);
2210 case WM_ACTIVATEAPP
:
2211 if (*plparam
) *plparam
= HTASK_16( (HANDLE
)*plparam
);
2215 MDINEXTMENU
*next
= (MDINEXTMENU
*)*plparam
;
2216 *plparam
= (LPARAM
)next
->hmenuIn
;
2219 case WM_PAINTCLIPBOARD
:
2220 case WM_SIZECLIPBOARD
:
2221 FIXME_(msg
)("message %04x needs translation\n", msg32
);
2223 /* following messages should not be sent to 16-bit apps */
2226 case WM_CAPTURECHANGED
:
2227 case WM_STYLECHANGING
:
2228 case WM_STYLECHANGED
:
2230 case WM_DDE_INITIATE
:
2231 case WM_DDE_TERMINATE
:
2232 case WM_DDE_UNADVISE
:
2233 case WM_DDE_REQUEST
:
2234 *pwparam16
= HWND_16((HWND
)wParam32
);
2243 *pwparam16
= HWND_16((HWND
)wParam32
);
2244 UnpackDDElParam(msg32
, *plparam
, &lo32
, &hi
);
2245 if (lo32
&& !(lo16
= convert_handle_32_to_16(lo32
, GMEM_DDESHARE
)))
2247 *plparam
= MAKELPARAM(lo16
, hi
);
2249 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2256 *pwparam16
= HWND_16((HWND
)wParam32
);
2258 UnpackDDElParam(msg32
, *plparam
, &lo
, &hi
);
2260 if (GlobalGetAtomNameA((ATOM
)hi
, buf
, sizeof(buf
)) > 0) flag
|= 1;
2261 if (GlobalSize((HANDLE
)hi
) != 0) flag
|= 2;
2267 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
2272 break; /* atom, nothing to do */
2274 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
2277 hi
= convert_handle_32_to_16(hi
, GMEM_DDESHARE
);
2280 *plparam
= MAKELPARAM(lo
, hi
);
2282 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2283 case WM_DDE_EXECUTE
:
2284 *plparam
= convert_handle_32_to_16(*plparam
, GMEM_DDESHARE
);
2285 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2286 default: /* No translation needed */
2292 /**********************************************************************
2293 * WINPROC_UnmapMsg32ATo16
2295 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2297 void WINPROC_UnmapMsg32ATo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2306 case LB_FINDSTRINGEXACT
:
2307 case LB_INSERTSTRING
:
2308 case LB_SELECTSTRING
:
2312 case CB_FINDSTRINGEXACT
:
2313 case CB_INSERTSTRING
:
2314 case CB_SELECTSTRING
:
2318 case WM_WININICHANGE
:
2319 case WM_DEVMODECHANGE
:
2320 UnMapLS( (SEGPTR
)p16
->lParam
);
2322 case LB_SETTABSTOPS
:
2323 case WM_COMPAREITEM
:
2327 void *ptr
= MapSL( p16
->lParam
);
2328 UnMapLS( p16
->lParam
);
2329 HeapFree( GetProcessHeap(), 0, ptr
);
2332 case CB_GETDROPPEDCONTROLRECT
:
2333 case LB_GETITEMRECT
:
2335 RECT16
*rect
= MapSL(p16
->lParam
);
2336 UnMapLS( p16
->lParam
);
2337 p16
->lParam
= *(LPARAM
*)(rect
+ 1);
2338 CONV_RECT16TO32( rect
, (RECT
*)(p16
->lParam
));
2339 HeapFree( GetProcessHeap(), 0, rect
);
2342 case LB_GETSELITEMS
:
2345 LPINT16 items
= MapSL(p16
->lParam
);
2346 UnMapLS( p16
->lParam
);
2347 p16
->lParam
= *((LPARAM
*)items
- 1);
2348 for (i
= 0; i
< p16
->wParam
; i
++) *((LPINT
)(p16
->lParam
) + i
) = items
[i
];
2349 HeapFree( GetProcessHeap(), 0, (LPARAM
*)items
- 1 );
2355 *((PUINT
)(wParam
)) = LOWORD(p16
->lResult
);
2357 *((PUINT
)(lParam
)) = HIWORD(p16
->lResult
); /* FIXME: substract 1? */
2360 case WM_MEASUREITEM
:
2362 MEASUREITEMSTRUCT16
*mis
= MapSL(p16
->lParam
);
2363 MEASUREITEMSTRUCT
*mis32
= *(MEASUREITEMSTRUCT
**)(mis
+ 1);
2364 mis32
->itemWidth
= mis
->itemWidth
;
2365 mis32
->itemHeight
= mis
->itemHeight
;
2366 UnMapLS( p16
->lParam
);
2367 HeapFree( GetProcessHeap(), 0, mis
);
2370 case WM_GETMINMAXINFO
:
2372 MINMAXINFO16
*mmi
= MapSL(p16
->lParam
);
2373 UnMapLS( p16
->lParam
);
2374 p16
->lParam
= *(LPARAM
*)(mmi
+ 1);
2375 STRUCT32_MINMAXINFO16to32( mmi
, (MINMAXINFO
*)(p16
->lParam
) );
2376 HeapFree( GetProcessHeap(), 0, mmi
);
2380 case WM_ASKCBFORMATNAME
:
2382 LPSTR str
= MapSL(p16
->lParam
);
2383 UnMapLS( p16
->lParam
);
2384 p16
->lParam
= *((LPARAM
*)str
- 1);
2385 lstrcpynA( (LPSTR
)(p16
->lParam
), str
, p16
->wParam
);
2386 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2391 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2392 UnMapLS( cs
->szTitle
);
2393 UnMapLS( cs
->szClass
);
2394 UnMapLS( p16
->lParam
);
2395 HeapFree( GetProcessHeap(), 0, cs
);
2398 case WM_MDIGETACTIVE
:
2399 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(p16
->lResult
);
2400 p16
->lResult
= (LRESULT
)WIN_Handle32( LOWORD(p16
->lResult
) );
2404 NCCALCSIZE_PARAMS
*nc32
;
2405 NCCALCSIZE_PARAMS16
*nc
= MapSL(p16
->lParam
);
2406 UnMapLS( p16
->lParam
);
2407 p16
->lParam
= *(LPARAM
*)(nc
+ 1);
2408 nc32
= (NCCALCSIZE_PARAMS
*)(p16
->lParam
);
2409 CONV_RECT16TO32( &nc
->rgrc
[0], &nc32
->rgrc
[0] );
2412 WINDOWPOS16
*pos
= MapSL(nc
->lppos
);
2413 UnMapLS( nc
->lppos
);
2414 CONV_RECT16TO32( &nc
->rgrc
[1], &nc32
->rgrc
[1] );
2415 CONV_RECT16TO32( &nc
->rgrc
[2], &nc32
->rgrc
[2] );
2416 STRUCT32_WINDOWPOS16to32( pos
, nc32
->lppos
);
2417 HeapFree( GetProcessHeap(), 0, pos
);
2419 HeapFree( GetProcessHeap(), 0, nc
);
2425 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2426 UnMapLS( p16
->lParam
);
2427 UnMapLS( cs
->lpszName
);
2428 UnMapLS( cs
->lpszClass
);
2429 HeapFree( GetProcessHeap(), 0, cs
);
2432 case WM_WINDOWPOSCHANGING
:
2433 case WM_WINDOWPOSCHANGED
:
2435 WINDOWPOS16
*wp
= MapSL(p16
->lParam
);
2436 UnMapLS( p16
->lParam
);
2437 p16
->lParam
= *(LPARAM
*)(wp
+ 1);
2438 STRUCT32_WINDOWPOS16to32( wp
, (WINDOWPOS
*)p16
->lParam
);
2439 HeapFree( GetProcessHeap(), 0, wp
);
2443 UnMapLS(p16
->lParam
);
2448 LPMSG16 msg16
= MapSL(p16
->lParam
);
2450 UnMapLS( p16
->lParam
);
2451 msgp16
.wParam
=msg16
->wParam
;
2452 msgp16
.lParam
=msg16
->lParam
;
2453 WINPROC_UnmapMsg32ATo16(((LPMSG
)lParam
)->hwnd
, ((LPMSG
)lParam
)->message
,
2454 ((LPMSG
)lParam
)->wParam
, ((LPMSG
)lParam
)->lParam
,
2456 HeapFree( GetProcessHeap(), 0, msg16
);
2461 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
2462 next
->hmenuNext
= HMENU_32( LOWORD(p16
->lResult
) );
2463 next
->hwndNext
= WIN_Handle32( HIWORD(p16
->lResult
) );
2471 /**********************************************************************
2472 * WINPROC_MapMsg32WTo16
2474 * Map a message from 32-bit Unicode to 16-bit.
2475 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2477 INT
WINPROC_MapMsg32WTo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
2478 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
2484 *pmsg16
= LOWORD(msg32
);
2485 *pwparam16
= LOWORD(wParam32
);
2490 case LB_FINDSTRINGEXACT
:
2491 case LB_INSERTSTRING
:
2492 case LB_SELECTSTRING
:
2495 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2496 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2501 case CB_FINDSTRINGEXACT
:
2502 case CB_INSERTSTRING
:
2503 case CB_SELECTSTRING
:
2505 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2506 *pmsg16
= (UINT16
)msg32
+ (CB_ADDSTRING16
- CB_ADDSTRING
);
2513 CREATESTRUCTW
*cs32
= (CREATESTRUCTW
*)*plparam
;
2515 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2516 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs32
, cs
);
2517 cs
->lpszName
= map_str_32W_to_16( cs32
->lpszName
);
2518 cs
->lpszClass
= map_str_32W_to_16( cs32
->lpszClass
);
2519 *plparam
= MapLS(cs
);
2524 MDICREATESTRUCT16
*cs
;
2525 MDICREATESTRUCTW
*cs32
= (MDICREATESTRUCTW
*)*plparam
;
2527 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2528 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs32
, cs
);
2529 cs
->szTitle
= map_str_32W_to_16( cs32
->szTitle
);
2530 cs
->szClass
= map_str_32W_to_16( cs32
->szClass
);
2531 *plparam
= MapLS(cs
);
2535 case WM_WININICHANGE
:
2536 case WM_DEVMODECHANGE
:
2537 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2541 if ( WINPROC_TestLBForStr( hwnd
))
2543 LPSTR str
= HeapAlloc( GetProcessHeap(), 0, 256 ); /* FIXME: fixed sized buffer */
2544 if (!str
) return -1;
2545 *pmsg16
= (msg32
== LB_GETTEXT
)? LB_GETTEXT16
: CB_GETLBTEXT16
;
2546 *plparam
= (LPARAM
)MapLS(str
);
2551 wch
= LOWORD(wParam32
);
2552 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2554 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
2557 wch
= LOWORD(wParam32
);
2558 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2560 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2565 case WM_SYSDEADCHAR
:
2567 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2577 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, ch
, 2, NULL
, NULL
);
2578 *pwparam16
= (ch
[0] << 8) | ch
[1];
2582 default: /* No Unicode translation needed (?) */
2583 return WINPROC_MapMsg32ATo16( hwnd
, msg32
, wParam32
, pmsg16
,
2584 pwparam16
, plparam
);
2589 /**********************************************************************
2590 * WINPROC_UnmapMsg32WTo16
2592 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2594 void WINPROC_UnmapMsg32WTo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2601 case LB_FINDSTRINGEXACT
:
2602 case LB_INSERTSTRING
:
2603 case LB_SELECTSTRING
:
2608 case CB_FINDSTRINGEXACT
:
2609 case CB_INSERTSTRING
:
2610 case CB_SELECTSTRING
:
2613 case WM_WININICHANGE
:
2614 case WM_DEVMODECHANGE
:
2615 unmap_str_32W_to_16( p16
->lParam
);
2620 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2621 UnMapLS( p16
->lParam
);
2622 unmap_str_32W_to_16( cs
->lpszName
);
2623 unmap_str_32W_to_16( cs
->lpszClass
);
2624 HeapFree( GetProcessHeap(), 0, cs
);
2629 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2630 UnMapLS( p16
->lParam
);
2631 unmap_str_32W_to_16( cs
->szTitle
);
2632 unmap_str_32W_to_16( cs
->szClass
);
2633 HeapFree( GetProcessHeap(), 0, cs
);
2637 case WM_ASKCBFORMATNAME
:
2639 LPSTR str
= MapSL(p16
->lParam
);
2640 UnMapLS( p16
->lParam
);
2641 p16
->lParam
= *((LPARAM
*)str
- 1);
2642 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)p16
->lParam
, 0x7fffffff );
2643 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2648 if ( WINPROC_TestLBForStr( hwnd
))
2650 LPSTR str
= MapSL(p16
->lParam
);
2651 UnMapLS( p16
->lParam
);
2652 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)lParam
, 0x7fffffff );
2653 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
);
2657 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, p16
);
2663 /**********************************************************************
2664 * WINPROC_CallProc32ATo32W
2666 * Call a window procedure, translating args from Ansi to Unicode.
2668 static LRESULT
WINPROC_CallProc32ATo32W( WNDPROC func
, HWND hwnd
,
2669 UINT msg
, WPARAM wParam
,
2675 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2676 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2678 if( (unmap
= WINPROC_MapMsg32ATo32W( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
2679 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2680 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2683 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2684 if (unmap
) result
= WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
2689 /**********************************************************************
2690 * WINPROC_CallProc32WTo32A
2692 * Call a window procedure, translating args from Unicode to Ansi.
2694 static LRESULT
WINPROC_CallProc32WTo32A( WNDPROC func
, HWND hwnd
,
2695 UINT msg
, WPARAM wParam
,
2701 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2702 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2704 if ((unmap
= WINPROC_MapMsg32WTo32A( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
2705 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2706 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2709 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2710 if( unmap
) WINPROC_UnmapMsg32WTo32A( hwnd
, msg
, wParam
, lParam
);
2715 /**********************************************************************
2716 * __wine_call_wndproc_32A (USER.1010)
2718 LRESULT WINAPI
__wine_call_wndproc_32A( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
2724 HWND hwnd32
= WIN_Handle32( hwnd
);
2726 if (WINPROC_MapMsg16To32A( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2728 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
2729 return WINPROC_UnmapMsg16To32A( hwnd32
, msg32
, wParam32
, lParam
, result
);
2733 /**********************************************************************
2734 * __wine_call_wndproc_32W (USER.1011)
2736 LRESULT WINAPI
__wine_call_wndproc_32W( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
2742 HWND hwnd32
= WIN_Handle32( hwnd
);
2744 if (WINPROC_MapMsg16To32W( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2746 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
2747 return WINPROC_UnmapMsg16To32W( hwnd32
, msg32
, wParam32
, lParam
, result
);
2751 /**********************************************************************
2752 * WINPROC_CallProc32ATo16
2754 * Call a 16-bit window procedure, translating the 32-bit args.
2756 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
2757 UINT msg
, WPARAM wParam
,
2763 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2764 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2766 mp16
.lParam
= lParam
;
2767 if (WINPROC_MapMsg32ATo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
, &mp16
.lParam
) == -1)
2769 mp16
.lResult
= WINPROC_CallWndProc16( func
, HWND_16(hwnd
), msg16
,
2770 mp16
.wParam
, mp16
.lParam
);
2771 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2772 return mp16
.lResult
;
2776 /**********************************************************************
2777 * WINPROC_CallProc32WTo16
2779 * Call a 16-bit window procedure, translating the 32-bit args.
2781 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
2782 UINT msg
, WPARAM wParam
,
2788 TRACE_(msg
)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
2789 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2791 mp16
.lParam
= lParam
;
2792 if (WINPROC_MapMsg32WTo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
,
2793 &mp16
.lParam
) == -1)
2795 mp16
.lResult
= WINPROC_CallWndProc16( func
, HWND_16(hwnd
), msg16
,
2796 mp16
.wParam
, mp16
.lParam
);
2797 WINPROC_UnmapMsg32WTo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2798 return mp16
.lResult
;
2802 /**********************************************************************
2803 * CallWindowProc (USER.122)
2805 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
2806 WPARAM16 wParam
, LPARAM lParam
)
2810 if (!func
) return 0;
2812 if (!(proc
= WINPROC_GetPtr( (WNDPROC
)func
)))
2813 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2816 func
= WINPROC_GetProc( (WNDPROC
)proc
, WIN_PROC_16
);
2817 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2823 if (!proc
->thunk
.t_from32
.proc
) return 0;
2824 return WINPROC_CallWndProc16( proc
->thunk
.t_from32
.proc
,
2825 hwnd
, msg
, wParam
, lParam
);
2827 if (!proc
->thunk
.t_from16
.proc
) return 0;
2828 return __wine_call_wndproc_32A( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
2830 if (!proc
->thunk
.t_from16
.proc
) return 0;
2831 return __wine_call_wndproc_32W( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
2833 WARN_(relay
)("Invalid proc %p\n", proc
);
2839 /**********************************************************************
2840 * CallWindowProcA (USER32.@)
2842 * The CallWindowProc() function invokes the windows procedure _func_,
2843 * with _hwnd_ as the target window, the message specified by _msg_, and
2844 * the message parameters _wParam_ and _lParam_.
2846 * Some kinds of argument conversion may be done, I'm not sure what.
2848 * CallWindowProc() may be used for windows subclassing. Use
2849 * SetWindowLong() to set a new windows procedure for windows of the
2850 * subclass, and handle subclassed messages in the new windows
2851 * procedure. The new windows procedure may then use CallWindowProc()
2852 * with _func_ set to the parent class's windows procedure to dispatch
2853 * the message to the superclass.
2857 * The return value is message dependent.
2863 LRESULT WINAPI
CallWindowProcA(
2864 WNDPROC func
, /* [in] window procedure */
2865 HWND hwnd
, /* [in] target window */
2866 UINT msg
, /* [in] message */
2867 WPARAM wParam
, /* [in] message dependent parameter */
2868 LPARAM lParam
/* [in] message dependent parameter */
2870 WINDOWPROC
*proc
= WINPROC_GetPtr( func
);
2872 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2875 func
= WINPROC_GetProc( (WNDPROC
)proc
, WIN_PROC_32A
);
2876 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2882 if (!proc
->thunk
.t_from32
.proc
) return 0;
2883 return WINPROC_CallProc32ATo16( proc
->thunk
.t_from32
.proc
,
2884 hwnd
, msg
, wParam
, lParam
);
2886 if (!proc
->thunk
.t_from16
.proc
) return 0;
2887 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2888 hwnd
, msg
, wParam
, lParam
);
2890 if (!proc
->thunk
.t_from16
.proc
) return 0;
2891 return WINPROC_CallProc32ATo32W( proc
->thunk
.t_from16
.proc
,
2892 hwnd
, msg
, wParam
, lParam
);
2894 WARN_(relay
)("Invalid proc %p\n", proc
);
2900 /**********************************************************************
2901 * CallWindowProcW (USER32.@)
2903 LRESULT WINAPI
CallWindowProcW( WNDPROC func
, HWND hwnd
, UINT msg
,
2904 WPARAM wParam
, LPARAM lParam
)
2906 WINDOWPROC
*proc
= WINPROC_GetPtr( func
);
2908 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2911 func
= WINPROC_GetProc( (WNDPROC
)proc
, WIN_PROC_32W
);
2912 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2918 if (!proc
->thunk
.t_from32
.proc
) return 0;
2919 return WINPROC_CallProc32WTo16( proc
->thunk
.t_from32
.proc
,
2920 hwnd
, msg
, wParam
, lParam
);
2922 if (!proc
->thunk
.t_from16
.proc
) return 0;
2923 return WINPROC_CallProc32WTo32A( proc
->thunk
.t_from16
.proc
,
2924 hwnd
, msg
, wParam
, lParam
);
2926 if (!proc
->thunk
.t_from16
.proc
) return 0;
2927 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2928 hwnd
, msg
, wParam
, lParam
);
2930 WARN_(relay
)("Invalid proc %p\n", proc
);