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"
30 #include "wine/winbase16.h"
31 #include "wine/winuser16.h"
32 #include "stackframe.h"
33 #include "selectors.h"
39 #include "wine/debug.h"
45 WINE_DECLARE_DEBUG_CHANNEL(msg
);
46 WINE_DECLARE_DEBUG_CHANNEL(relay
);
47 WINE_DECLARE_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 static HANDLE WinProcHeap
;
113 static WORD WinProcSel
;
116 /**********************************************************************
119 BOOL
WINPROC_Init(void)
121 WinProcHeap
= HeapCreate( 0, 0x10000, 0x10000 );
122 WinProcSel
= SELECTOR_AllocBlock( (void *)WinProcHeap
, 0x10000,
123 WINE_LDT_FLAGS_CODE
| WINE_LDT_FLAGS_32BIT
);
124 if (!WinProcHeap
|| !WinProcSel
)
126 WARN_(relay
)("Unable to create winproc heap\n" );
134 /* Some window procedures modify register they shouldn't, or are not
135 * properly declared stdcall; so we need a small assembly wrapper to
137 extern LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
138 WPARAM wParam
, LPARAM lParam
);
139 __ASM_GLOBAL_FUNC( WINPROC_wrapper
,
149 "movl 8(%ebp),%eax\n\t"
151 "leal -12(%ebp),%esp\n\t"
158 static inline LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
159 WPARAM wParam
, LPARAM lParam
)
161 return proc( hwnd
, msg
, wParam
, lParam
);
163 #endif /* __i386__ */
165 /**********************************************************************
166 * WINPROC_CallWndProc32
168 * Call a 32-bit WndProc.
170 static LRESULT
WINPROC_CallWndProc( WNDPROC proc
, HWND hwnd
, UINT msg
,
171 WPARAM wParam
, LPARAM lParam
)
176 hwnd
= WIN_GetFullHandle( hwnd
);
178 DPRINTF( "%08lx:Call window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
179 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
180 /* To avoid any deadlocks, all the locks on the windows structures
181 must be suspended before the control is passed to the application */
182 iWndsLocks
= WIN_SuspendWndsLock();
183 retvalue
= WINPROC_wrapper( proc
, hwnd
, msg
, wParam
, lParam
);
184 WIN_RestoreWndsLock(iWndsLocks
);
187 DPRINTF( "%08lx:Ret window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
188 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
, retvalue
);
192 /***********************************************************************
193 * WINPROC_CallWndProc16
195 * Call a 16-bit window procedure
197 static LRESULT WINAPI
WINPROC_CallWndProc16( WNDPROC16 proc
, HWND16 hwnd
,
198 UINT16 msg
, WPARAM16 wParam
,
205 TEB
*teb
= NtCurrentTeb();
208 /* Window procedures want ax = hInstance, ds = es = ss */
210 memset(&context
, '\0', sizeof(context
));
211 context
.SegDs
= context
.SegEs
= SELECTOROF(teb
->cur_stack
);
212 if (!(context
.Eax
= GetWindowWord16( hwnd
, GWL_HINSTANCE
))) context
.Eax
= context
.SegDs
;
213 context
.SegCs
= SELECTOROF(proc
);
214 context
.Eip
= OFFSETOF(proc
);
215 context
.Ebp
= OFFSETOF(teb
->cur_stack
)
216 + (WORD
)&((STACK16FRAME
*)0)->bp
;
220 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
221 work if structures passed in lParam are placed in the stack/data
222 segment. Programmers easily make the mistake of converting lParam
223 to a near rather than a far pointer, since Windows apparently
224 allows this. We copy the structures to the 16 bit stack; this is
225 ugly but makes these programs work. */
230 offset
= sizeof(CREATESTRUCT16
); break;
232 offset
= sizeof(DRAWITEMSTRUCT16
); break;
234 offset
= sizeof(COMPAREITEMSTRUCT16
); break;
238 void *s
= MapSL(lParam
);
239 lParam
= stack16_push( offset
);
240 memcpy( MapSL(lParam
), s
, offset
);
244 iWndsLocks
= WIN_SuspendWndsLock();
246 args
= (WORD
*)THREAD_STACK16(teb
) - 5;
247 args
[0] = LOWORD(lParam
);
248 args
[1] = HIWORD(lParam
);
253 wine_call_to_16_regs_short( &context
, 5 * sizeof(WORD
) );
254 ret
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
255 if (offset
) stack16_pop( offset
);
257 WIN_RestoreWndsLock(iWndsLocks
);
263 /**********************************************************************
266 * Return a pointer to the win proc.
268 static WINDOWPROC
*WINPROC_GetPtr( WNDPROC16 handle
)
273 /* ptr cannot be < 64K */
274 if (!HIWORD(handle
)) return NULL
;
276 /* Check for a linear pointer */
278 ptr
= (BYTE
*)handle
;
279 /* First check if it is the jmp address */
280 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->jmp
);
281 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
283 /* Now it must be the thunk address */
284 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
285 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
288 /* Check for a segmented pointer */
290 if (!IsBadReadPtr16( (SEGPTR
)handle
, sizeof(proc
->thunk
) ))
292 ptr
= MapSL( (SEGPTR
)handle
);
293 /* It must be the thunk address */
294 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
295 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
303 /**********************************************************************
304 * WINPROC_AllocWinProc
306 * Allocate a new window procedure.
308 static WINDOWPROC
*WINPROC_AllocWinProc( WNDPROC16 func
, WINDOWPROCTYPE type
,
309 WINDOWPROCUSER user
)
311 static FARPROC16 relay_32A
, relay_32W
;
313 WINDOWPROC
*proc
, *oldproc
;
315 /* Allocate a window procedure */
317 if (!(proc
= HeapAlloc( WinProcHeap
, 0, sizeof(WINDOWPROC
) ))) return 0;
319 /* Check if the function is already a win proc */
321 if ((oldproc
= WINPROC_GetPtr( func
)))
330 proc
->thunk
.t_from32
.popl_eax
= 0x58; /* popl %eax */
331 proc
->thunk
.t_from32
.pushl_func
= 0x68; /* pushl $proc */
332 proc
->thunk
.t_from32
.proc
= func
;
333 proc
->thunk
.t_from32
.pushl_eax
= 0x50; /* pushl %eax */
334 proc
->thunk
.t_from32
.jmp
= 0xe9; /* jmp relay*/
335 proc
->thunk
.t_from32
.relay
= /* relative jump */
336 (void(*)())((DWORD
)WINPROC_CallProc32ATo16
-
337 (DWORD
)(&proc
->thunk
.t_from32
.relay
+ 1));
340 if (!relay_32A
) relay_32A
= GetProcAddress16( GetModuleHandle16("user"),
341 "__wine_call_wndproc_32A" );
342 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
343 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
344 proc
->thunk
.t_from16
.proc
= (WNDPROC
)func
;
345 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
346 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
347 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32A
);
348 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32A
);
349 proc
->jmp
.jmp
= 0xe9;
350 /* Fixup relative jump */
351 proc
->jmp
.proc
= (WNDPROC
)((DWORD
)func
- (DWORD
)(&proc
->jmp
.proc
+ 1));
354 if (!relay_32W
) relay_32W
= GetProcAddress16( GetModuleHandle16("user"),
355 "__wine_call_wndproc_32W" );
356 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
357 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
358 proc
->thunk
.t_from16
.proc
= (WNDPROC
)func
;
359 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
360 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
361 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32W
);
362 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32W
);
363 proc
->jmp
.jmp
= 0xe9;
364 /* Fixup relative jump */
365 proc
->jmp
.proc
= (WNDPROC
)((DWORD
)func
- (DWORD
)(&proc
->jmp
.proc
+ 1));
368 /* Should not happen */
371 proc
->magic
= WINPROC_MAGIC
;
376 TRACE_(win
)("(%08x,%d): returning %08x\n",
377 (UINT
)func
, type
, (UINT
)proc
);
382 /**********************************************************************
385 * Get a window procedure pointer that can be passed to the Windows program.
387 WNDPROC16
WINPROC_GetProc( HWINDOWPROC proc
, WINDOWPROCTYPE type
)
389 WINDOWPROC
*ptr
= (WINDOWPROC
*)proc
;
391 if (!proc
) return NULL
;
392 if (type
== WIN_PROC_16
) /* We want a 16:16 address */
394 if (ptr
->type
== WIN_PROC_16
)
395 return ptr
->thunk
.t_from32
.proc
;
397 return (WNDPROC16
)MAKESEGPTR( WinProcSel
, (char *)&ptr
->thunk
- (char *)WinProcHeap
);
399 else /* We want a 32-bit address */
401 if (ptr
->type
== WIN_PROC_16
)
402 return (WNDPROC16
)&ptr
->thunk
;
403 else if (type
!= ptr
->type
)
404 /* Have to return the jmp address if types don't match */
405 return (WNDPROC16
)&ptr
->jmp
;
407 /* Some Win16 programs want to get back the proc they set */
408 return (WNDPROC16
)ptr
->thunk
.t_from16
.proc
;
413 /**********************************************************************
416 * Set the window procedure for a window or class. There are
417 * three tree classes of winproc callbacks:
419 * 1) class -> wp - not subclassed
420 * class -> wp -> wp -> wp -> wp - SetClassLong()
422 * 2) window -' / - not subclassed
423 * window -> wp -> wp ' - SetWindowLong()
425 * 3) timer -> wp - SetTimer()
427 * Initially, winproc of the window points to the current winproc
428 * thunk of its class. Subclassing prepends a new thunk to the
429 * window winproc chain at the head of the list. Thus, window thunk
430 * list includes class thunks and the latter are preserved when the
431 * window is destroyed.
434 BOOL
WINPROC_SetProc( HWINDOWPROC
*pFirst
, WNDPROC16 func
,
435 WINDOWPROCTYPE type
, WINDOWPROCUSER user
)
437 BOOL bRecycle
= FALSE
;
438 WINDOWPROC
*proc
, **ppPrev
;
440 /* Check if function is already in the list */
442 ppPrev
= (WINDOWPROC
**)pFirst
;
443 proc
= WINPROC_GetPtr( func
);
450 if ((*ppPrev
)->user
!= user
)
452 /* terminal thunk is being restored */
454 WINPROC_FreeProc( *pFirst
, (*ppPrev
)->user
);
455 *(WINDOWPROC
**)pFirst
= *ppPrev
;
464 if (((*ppPrev
)->type
== type
) &&
465 (func
== WINPROC_THUNKPROC(*ppPrev
)))
467 if((*ppPrev
)->user
== user
)
473 WINPROC_FreeProc( *ppPrev
, user
);
480 /* WPF_CLASS thunk terminates window thunk list */
481 if ((*ppPrev
)->user
!= user
) break;
482 ppPrev
= &(*ppPrev
)->next
;
487 /* Extract this thunk from the list */
489 *ppPrev
= proc
->next
;
491 else /* Allocate a new one */
493 if (proc
) /* Was already a win proc */
496 func
= WINPROC_THUNKPROC(proc
);
498 proc
= WINPROC_AllocWinProc( func
, type
, user
);
499 if (!proc
) return FALSE
;
502 /* Add the win proc at the head of the list */
504 TRACE_(win
)("(%08x,%08x,%d): res=%08x\n",
505 (UINT
)*pFirst
, (UINT
)func
, type
, (UINT
)proc
);
506 proc
->next
= *(WINDOWPROC
**)pFirst
;
507 *(WINDOWPROC
**)pFirst
= proc
;
512 /**********************************************************************
515 * Free a list of win procs.
517 void WINPROC_FreeProc( HWINDOWPROC proc
, WINDOWPROCUSER user
)
521 WINDOWPROC
*next
= ((WINDOWPROC
*)proc
)->next
;
522 if (((WINDOWPROC
*)proc
)->user
!= user
) break;
523 TRACE_(win
)("freeing %08x\n", (UINT
)proc
);
524 HeapFree( WinProcHeap
, 0, proc
);
530 /**********************************************************************
531 * WINPROC_GetProcType
533 * Return the window procedure type.
535 WINDOWPROCTYPE
WINPROC_GetProcType( HWINDOWPROC proc
)
538 (((WINDOWPROC
*)proc
)->magic
!= WINPROC_MAGIC
))
539 return WIN_PROC_INVALID
;
540 return ((WINDOWPROC
*)proc
)->type
;
542 /**********************************************************************
543 * WINPROC_TestCBForStr
545 * Return TRUE if the lparam is a string
547 inline static BOOL
WINPROC_TestCBForStr( HWND hwnd
)
549 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
550 return (!(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) || (style
& CBS_HASSTRINGS
));
552 /**********************************************************************
553 * WINPROC_TestLBForStr
555 * Return TRUE if the lparam is a string
557 inline static BOOL
WINPROC_TestLBForStr( HWND hwnd
)
559 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
560 return (!(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) || (style
& LBS_HASSTRINGS
));
563 /**********************************************************************
564 * WINPROC_MapMsg32ATo32W
566 * Map a message from Ansi to Unicode.
567 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
570 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
571 * the first four bytes are the handle of the icon
572 * when the WM_SETTEXT message has been used to set the icon
574 INT
WINPROC_MapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
579 case WM_ASKCBFORMATNAME
:
581 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
582 *pwparam
* sizeof(WCHAR
) + sizeof(LPARAM
) );
584 *ptr
++ = *plparam
; /* Store previous lParam */
585 *plparam
= (LPARAM
)ptr
;
588 /* lparam is string (0-terminated) */
590 case WM_WININICHANGE
:
591 case WM_DEVMODECHANGE
:
596 if(!*plparam
) return 0;
597 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
598 return (*plparam
? 1 : -1);
599 case WM_GETTEXTLENGTH
:
600 case CB_GETLBTEXTLEN
:
602 return 1; /* need to map result */
607 { CREATESTRUCTW cs
; /* new structure */
608 LPCWSTR lpszName
; /* allocated Name */
609 LPCWSTR lpszClass
; /* allocated Class */
612 struct s
*xs
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct s
));
614 xs
->cs
= *(CREATESTRUCTW
*)*plparam
;
615 if (HIWORD(xs
->cs
.lpszName
))
616 xs
->lpszName
= xs
->cs
.lpszName
= HEAP_strdupAtoW( GetProcessHeap(), 0,
617 (LPCSTR
)xs
->cs
.lpszName
);
618 if (HIWORD(xs
->cs
.lpszClass
))
619 xs
->lpszClass
= xs
->cs
.lpszClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
620 (LPCSTR
)xs
->cs
.lpszClass
);
621 *plparam
= (LPARAM
)xs
;
626 MDICREATESTRUCTW
*cs
=
627 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
629 *cs
= *(MDICREATESTRUCTW
*)*plparam
;
630 if (HIWORD(cs
->szClass
))
631 cs
->szClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
632 (LPCSTR
)cs
->szClass
);
633 if (HIWORD(cs
->szTitle
))
634 cs
->szTitle
= HEAP_strdupAtoW( GetProcessHeap(), 0,
635 (LPCSTR
)cs
->szTitle
);
636 *plparam
= (LPARAM
)cs
;
642 case LB_INSERTSTRING
:
644 case LB_FINDSTRINGEXACT
:
645 case LB_SELECTSTRING
:
646 if(!*plparam
) return 0;
647 if ( WINPROC_TestLBForStr( hwnd
))
648 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
649 return (*plparam
? 1 : -1);
651 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
652 { if ( WINPROC_TestLBForStr( hwnd
))
653 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
655 *ptr
++ = *plparam
; /* Store previous lParam */
656 *plparam
= (LPARAM
)ptr
;
663 case CB_INSERTSTRING
:
664 case CB_FINDSTRINGEXACT
:
666 case CB_SELECTSTRING
:
667 if(!*plparam
) return 0;
668 if ( WINPROC_TestCBForStr( hwnd
))
669 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
670 return (*plparam
? 1 : -1);
672 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
673 { if ( WINPROC_TestCBForStr( hwnd
))
674 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
676 *ptr
++ = *plparam
; /* Store previous lParam */
677 *plparam
= (LPARAM
)ptr
;
684 { WORD len
= (WORD
)*plparam
;
685 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(WCHAR
) );
687 *ptr
++ = *plparam
; /* Store previous lParam */
688 *((WORD
*) ptr
) = len
; /* Store the length */
689 *plparam
= (LPARAM
)ptr
;
699 case EM_SETPASSWORDCHAR
:
701 BYTE ch
= LOWORD(*pwparam
);
703 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wch
, 1);
704 *pwparam
= MAKEWPARAM( wch
, HIWORD(*pwparam
) );
708 case WM_PAINTCLIPBOARD
:
709 case WM_SIZECLIPBOARD
:
710 FIXME_(msg
)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg
, hwnd
), msg
);
712 default: /* No translation needed */
718 /**********************************************************************
719 * WINPROC_UnmapMsg32ATo32W
721 * Unmap a message that was mapped from Ansi to Unicode.
723 LRESULT
WINPROC_UnmapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
729 case WM_ASKCBFORMATNAME
:
731 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
732 if (wParam
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
733 (LPSTR
)*ptr
, wParam
, NULL
, NULL
))
734 ((LPSTR
)*ptr
)[wParam
-1] = 0;
735 HeapFree( GetProcessHeap(), 0, ptr
);
738 case WM_GETTEXTLENGTH
:
739 case CB_GETLBTEXTLEN
:
741 /* there may be one DBCS char for each Unicode char */
747 { CREATESTRUCTW cs
; /* new structure */
748 LPWSTR lpszName
; /* allocated Name */
749 LPWSTR lpszClass
; /* allocated Class */
751 struct s
*xs
= (struct s
*)lParam
;
752 if (xs
->lpszName
) HeapFree( GetProcessHeap(), 0, xs
->lpszName
);
753 if (xs
->lpszClass
) HeapFree( GetProcessHeap(), 0, xs
->lpszClass
);
754 HeapFree( GetProcessHeap(), 0, xs
);
760 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
761 if (HIWORD(cs
->szTitle
))
762 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
763 if (HIWORD(cs
->szClass
))
764 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
765 HeapFree( GetProcessHeap(), 0, cs
);
770 case WM_WININICHANGE
:
771 case WM_DEVMODECHANGE
:
776 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
781 case LB_INSERTSTRING
:
783 case LB_FINDSTRINGEXACT
:
784 case LB_SELECTSTRING
:
785 if ( WINPROC_TestLBForStr( hwnd
))
786 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
790 { if ( WINPROC_TestLBForStr( hwnd
))
791 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
792 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
793 HeapFree( GetProcessHeap(), 0, ptr
);
800 case CB_INSERTSTRING
:
802 case CB_FINDSTRINGEXACT
:
803 case CB_SELECTSTRING
:
804 if ( WINPROC_TestCBForStr( hwnd
))
805 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
809 { if ( WINPROC_TestCBForStr( hwnd
))
810 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
811 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
812 HeapFree( GetProcessHeap(), 0, ptr
);
819 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lParam */
820 WORD len
= *(WORD
*) lParam
;
821 if (len
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
822 (LPSTR
)*ptr
, len
, NULL
, NULL
))
823 ((LPSTR
)*ptr
)[len
-1] = 0;
824 HeapFree( GetProcessHeap(), 0, ptr
);
832 /**********************************************************************
833 * WINPROC_MapMsg32WTo32A
835 * Map a message from Unicode to Ansi.
836 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
838 INT
WINPROC_MapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
843 case WM_ASKCBFORMATNAME
:
845 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
846 *pwparam
+ sizeof(LPARAM
) );
848 *ptr
++ = *plparam
; /* Store previous lParam */
849 *plparam
= (LPARAM
)ptr
;
854 case WM_WININICHANGE
:
855 case WM_DEVMODECHANGE
:
860 if(!*plparam
) return 0;
861 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
862 return (*plparam
? 1 : -1);
867 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
870 *cs
= *(CREATESTRUCTA
*)*plparam
;
871 if (HIWORD(cs
->lpszName
))
872 cs
->lpszName
= HEAP_strdupWtoA( GetProcessHeap(), 0,
873 (LPCWSTR
)cs
->lpszName
);
874 if (HIWORD(cs
->lpszClass
))
875 cs
->lpszClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
876 (LPCWSTR
)cs
->lpszClass
);
877 *plparam
= (LPARAM
)cs
;
882 MDICREATESTRUCTA
*cs
=
883 (MDICREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
885 *cs
= *(MDICREATESTRUCTA
*)*plparam
;
886 if (HIWORD(cs
->szTitle
))
887 cs
->szTitle
= HEAP_strdupWtoA( GetProcessHeap(), 0,
888 (LPCWSTR
)cs
->szTitle
);
889 if (HIWORD(cs
->szClass
))
890 cs
->szClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
891 (LPCWSTR
)cs
->szClass
);
892 *plparam
= (LPARAM
)cs
;
898 case LB_INSERTSTRING
:
900 case LB_FINDSTRINGEXACT
:
901 case LB_SELECTSTRING
:
902 if(!*plparam
) return 0;
903 if ( WINPROC_TestLBForStr( hwnd
))
904 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
905 return (*plparam
? 1 : -1);
907 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
908 { if ( WINPROC_TestLBForStr( hwnd
))
909 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
911 *ptr
++ = *plparam
; /* Store previous lParam */
912 *plparam
= (LPARAM
)ptr
;
919 case CB_INSERTSTRING
:
921 case CB_FINDSTRINGEXACT
:
922 case CB_SELECTSTRING
:
923 if(!*plparam
) return 0;
924 if ( WINPROC_TestCBForStr( hwnd
))
925 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
926 return (*plparam
? 1 : -1);
928 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
929 { if ( WINPROC_TestCBForStr( hwnd
))
930 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
932 *ptr
++ = *plparam
; /* Store previous lParam */
933 *plparam
= (LPARAM
)ptr
;
940 { WORD len
= (WORD
)*plparam
;
941 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(CHAR
) );
943 *ptr
++ = *plparam
; /* Store previous lParam */
944 *((WORD
*) ptr
) = len
; /* Store the length */
945 *plparam
= (LPARAM
)ptr
;
955 case EM_SETPASSWORDCHAR
:
957 WCHAR wch
= LOWORD(*pwparam
);
959 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
960 *pwparam
= MAKEWPARAM( ch
, HIWORD(*pwparam
) );
964 case WM_PAINTCLIPBOARD
:
965 case WM_SIZECLIPBOARD
:
966 FIXME_(msg
)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg
, hwnd
),msg
);
968 default: /* No translation needed */
974 /**********************************************************************
975 * WINPROC_UnmapMsg32WTo32A
977 * Unmap a message that was mapped from Unicode to Ansi.
979 void WINPROC_UnmapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
984 case WM_ASKCBFORMATNAME
:
986 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
989 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, wParam
))
990 ((LPWSTR
)*ptr
)[wParam
-1] = 0;
992 HeapFree( GetProcessHeap(), 0, ptr
);
997 case WM_WININICHANGE
:
998 case WM_DEVMODECHANGE
:
1003 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1009 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1010 if (HIWORD(cs
->lpszName
))
1011 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszName
);
1012 if (HIWORD(cs
->lpszClass
))
1013 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszClass
);
1014 HeapFree( GetProcessHeap(), 0, cs
);
1020 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1021 if (HIWORD(cs
->szTitle
))
1022 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
1023 if (HIWORD(cs
->szClass
))
1024 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
1025 HeapFree( GetProcessHeap(), 0, cs
);
1031 case LB_INSERTSTRING
:
1033 case LB_FINDSTRINGEXACT
:
1034 case LB_SELECTSTRING
:
1035 if ( WINPROC_TestLBForStr( hwnd
))
1036 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1040 if ( WINPROC_TestLBForStr( hwnd
))
1042 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1043 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1044 HeapFree( GetProcessHeap(), 0, ptr
);
1050 case CB_INSERTSTRING
:
1052 case CB_FINDSTRINGEXACT
:
1053 case CB_SELECTSTRING
:
1054 if ( WINPROC_TestCBForStr( hwnd
))
1055 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1059 if ( WINPROC_TestCBForStr( hwnd
))
1061 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1062 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1063 HeapFree( GetProcessHeap(), 0, ptr
);
1067 /* Multiline edit */
1069 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lparam */
1070 WORD len
= *(WORD
*)ptr
;
1073 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, len
))
1074 ((LPWSTR
)*ptr
)[len
-1] = 0;
1076 HeapFree( GetProcessHeap(), 0, ptr
);
1082 static HANDLE
convert_handle_16_to_32(HANDLE16 src
, unsigned int flags
)
1085 UINT sz
= GlobalSize16(src
);
1088 if (!(dst
= GlobalAlloc(flags
, sz
)))
1090 ptr16
= GlobalLock16(src
);
1091 ptr32
= GlobalLock(dst
);
1092 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr32
, ptr16
, sz
);
1093 GlobalUnlock16(src
);
1099 /**********************************************************************
1100 * WINPROC_MapMsg16To32A
1102 * Map a message from 16- to 32-bit Ansi.
1103 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1105 INT
WINPROC_MapMsg16To32A( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1106 WPARAM
*pwparam32
, LPARAM
*plparam
)
1108 *pmsg32
= (UINT
)msg16
;
1109 *pwparam32
= (WPARAM
)wParam16
;
1116 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1117 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1121 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1122 *plparam
= (LPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1125 if ( HIWORD(*plparam
) > CTLCOLOR_STATIC
) return -1;
1126 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
1127 *pwparam32
= (WPARAM
)(HDC
)wParam16
;
1128 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1130 case WM_COMPAREITEM
:
1132 COMPAREITEMSTRUCT16
* cis16
= MapSL(*plparam
);
1133 COMPAREITEMSTRUCT
*cis
= (COMPAREITEMSTRUCT
*)
1134 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis
));
1135 if (!cis
) return -1;
1136 cis
->CtlType
= cis16
->CtlType
;
1137 cis
->CtlID
= cis16
->CtlID
;
1138 cis
->hwndItem
= WIN_Handle32( cis16
->hwndItem
);
1139 cis
->itemID1
= cis16
->itemID1
;
1140 cis
->itemData1
= cis16
->itemData1
;
1141 cis
->itemID2
= cis16
->itemID2
;
1142 cis
->itemData2
= cis16
->itemData2
;
1143 cis
->dwLocaleId
= 0; /* FIXME */
1144 *plparam
= (LPARAM
)cis
;
1149 DELETEITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1150 DELETEITEMSTRUCT
*dis
= (DELETEITEMSTRUCT
*)
1151 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis
));
1152 if (!dis
) return -1;
1153 dis
->CtlType
= dis16
->CtlType
;
1154 dis
->CtlID
= dis16
->CtlID
;
1155 dis
->hwndItem
= WIN_Handle32( dis16
->hwndItem
);
1156 dis
->itemData
= dis16
->itemData
;
1157 *plparam
= (LPARAM
)dis
;
1160 case WM_MEASUREITEM
:
1162 MEASUREITEMSTRUCT16
* mis16
= MapSL(*plparam
);
1163 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)
1164 HeapAlloc(GetProcessHeap(), 0,
1165 sizeof(*mis
) + sizeof(LPARAM
));
1166 if (!mis
) return -1;
1167 mis
->CtlType
= mis16
->CtlType
;
1168 mis
->CtlID
= mis16
->CtlID
;
1169 mis
->itemID
= mis16
->itemID
;
1170 mis
->itemWidth
= mis16
->itemWidth
;
1171 mis
->itemHeight
= mis16
->itemHeight
;
1172 mis
->itemData
= mis16
->itemData
;
1173 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1174 *plparam
= (LPARAM
)mis
;
1179 DRAWITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1180 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)HeapAlloc(GetProcessHeap(), 0,
1182 if (!dis
) return -1;
1183 dis
->CtlType
= dis16
->CtlType
;
1184 dis
->CtlID
= dis16
->CtlID
;
1185 dis
->itemID
= dis16
->itemID
;
1186 dis
->itemAction
= dis16
->itemAction
;
1187 dis
->itemState
= dis16
->itemState
;
1188 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND
)(HMENU
)dis16
->hwndItem
1189 : WIN_Handle32( dis16
->hwndItem
);
1190 dis
->hDC
= dis16
->hDC
;
1191 dis
->itemData
= dis16
->itemData
;
1192 CONV_RECT16TO32( &dis16
->rcItem
, &dis
->rcItem
);
1193 *plparam
= (LPARAM
)dis
;
1196 case WM_GETMINMAXINFO
:
1198 MINMAXINFO
*mmi
= (MINMAXINFO
*)HeapAlloc( GetProcessHeap(), 0,
1199 sizeof(*mmi
) + sizeof(LPARAM
));
1200 if (!mmi
) return -1;
1201 STRUCT32_MINMAXINFO16to32( MapSL(*plparam
), mmi
);
1202 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1203 *plparam
= (LPARAM
)mmi
;
1208 case WM_WININICHANGE
:
1209 case WM_DEVMODECHANGE
:
1210 case WM_ASKCBFORMATNAME
:
1211 *plparam
= (LPARAM
)MapSL(*plparam
);
1215 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1216 MDICREATESTRUCTA
*cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) + sizeof(LPARAM
) );
1218 STRUCT32_MDICREATESTRUCT16to32A( cs16
, cs
);
1219 cs
->szTitle
= MapSL(cs16
->szTitle
);
1220 cs
->szClass
= MapSL(cs16
->szClass
);
1221 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1222 *plparam
= (LPARAM
)cs
;
1225 case WM_MDIGETACTIVE
:
1226 *plparam
= (LPARAM
)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL
) );
1227 *(BOOL
*)(*plparam
) = 0;
1231 *pmsg32
=WM_MDIREFRESHMENU
;
1232 *pwparam32
= (WPARAM
)(HMENU
)LOWORD(*plparam
);
1233 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1236 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1237 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1240 if((LOWORD(*plparam
) & MF_POPUP
) && (LOWORD(*plparam
) != 0xFFFF))
1242 HMENU hmenu
=(HMENU
)HIWORD(*plparam
);
1243 UINT Pos
=MENU_FindSubMenu( &hmenu
, wParam16
);
1244 if(Pos
==0xFFFF) Pos
=0; /* NO_SELECTED_ITEM */
1245 *pwparam32
= MAKEWPARAM( Pos
, LOWORD(*plparam
) );
1247 else *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1248 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1250 case WM_MDIACTIVATE
:
1253 *pwparam32
= (WPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1254 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1256 else /* message sent to MDI client */
1257 *pwparam32
= wParam16
;
1261 NCCALCSIZE_PARAMS16
*nc16
;
1262 NCCALCSIZE_PARAMS
*nc
;
1264 nc
= (NCCALCSIZE_PARAMS
*)HeapAlloc( GetProcessHeap(), 0,
1265 sizeof(*nc
) + sizeof(LPARAM
) );
1267 nc16
= MapSL(*plparam
);
1268 CONV_RECT16TO32( &nc16
->rgrc
[0], &nc
->rgrc
[0] );
1271 nc
->lppos
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1272 sizeof(*nc
->lppos
) );
1273 CONV_RECT16TO32( &nc16
->rgrc
[1], &nc
->rgrc
[1] );
1274 CONV_RECT16TO32( &nc16
->rgrc
[2], &nc
->rgrc
[2] );
1275 if (nc
->lppos
) STRUCT32_WINDOWPOS16to32( MapSL(nc16
->lppos
), nc
->lppos
);
1277 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1278 *plparam
= (LPARAM
)nc
;
1284 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1285 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
1286 sizeof(*cs
) + sizeof(LPARAM
) );
1288 STRUCT32_CREATESTRUCT16to32A( cs16
, cs
);
1289 cs
->lpszName
= MapSL(cs16
->lpszName
);
1290 cs
->lpszClass
= MapSL(cs16
->lpszClass
);
1291 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1292 *plparam
= (LPARAM
)cs
;
1295 case WM_PARENTNOTIFY
:
1296 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
1298 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1299 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1302 case WM_WINDOWPOSCHANGING
:
1303 case WM_WINDOWPOSCHANGED
:
1305 WINDOWPOS
*wp
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1306 sizeof(*wp
) + sizeof(LPARAM
) );
1308 STRUCT32_WINDOWPOS16to32( MapSL(*plparam
), wp
);
1309 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1310 *plparam
= (LPARAM
)wp
;
1316 LPMSG16 msg16
= MapSL(*plparam
);
1317 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1319 if (!msg32
) return -1;
1320 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1321 msg32
->lParam
= msg16
->lParam
;
1322 msg32
->time
= msg16
->time
;
1323 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1324 /* this is right, right? */
1325 if (WINPROC_MapMsg16To32A( msg32
->hwnd
, msg16
->message
,msg16
->wParam
,
1326 &msg32
->message
,&msg32
->wParam
,
1327 &msg32
->lParam
)<0) {
1328 HeapFree( GetProcessHeap(), 0, msg32
);
1331 *plparam
= (LPARAM
)msg32
;
1336 *plparam
= (LPARAM
)MapSL(*plparam
);
1338 case WM_ACTIVATEAPP
:
1340 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1341 a 32bit window. Might be superflous with 32bit interprocess
1344 HTASK16 htask
= (HTASK16
) *plparam
;
1345 DWORD idThread
= (DWORD
)TASK_GetPtr(htask
)->teb
->tid
;
1346 *plparam
= (LPARAM
) idThread
;
1351 MDINEXTMENU
*next
= HeapAlloc( GetProcessHeap(), 0, sizeof(*next
) );
1352 if (!next
) return -1;
1353 next
->hmenuIn
= *plparam
;
1354 next
->hmenuNext
= 0;
1356 *plparam
= (LPARAM
)next
;
1359 case WM_PAINTCLIPBOARD
:
1360 case WM_SIZECLIPBOARD
:
1361 FIXME_(msg
)("message %04x needs translation\n",msg16
);
1363 case WM_DDE_INITIATE
:
1364 case WM_DDE_TERMINATE
:
1365 case WM_DDE_UNADVISE
:
1366 case WM_DDE_REQUEST
:
1367 *pwparam32
= WIN_Handle32(wParam16
);
1377 *pwparam32
= WIN_Handle32(wParam16
);
1378 lo16
= LOWORD(*plparam
);
1379 hi
= HIWORD(*plparam
);
1380 if (lo16
&& !(lo32
= convert_handle_16_to_32(lo16
, GMEM_DDESHARE
)))
1382 *plparam
= PackDDElParam(msg16
, lo32
, hi
);
1384 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1391 *pwparam32
= WIN_Handle32(wParam16
);
1393 lo
= LOWORD(*plparam
);
1394 hi
= HIWORD(*plparam
);
1396 if (GlobalGetAtomNameA(hi
, buf
, 2) > 0) flag
|= 1;
1397 if (GlobalSize16(hi
) != 0) flag
|= 2;
1403 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
1408 break; /* atom, nothing to do */
1410 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
1413 hi
= convert_handle_16_to_32(hi
, GMEM_DDESHARE
);
1416 *plparam
= PackDDElParam(WM_DDE_ACK
, lo
, hi
);
1418 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1419 case WM_DDE_EXECUTE
:
1420 *plparam
= convert_handle_16_to_32(*plparam
, GMEM_DDESHARE
);
1421 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
1422 default: /* No translation needed */
1428 /**********************************************************************
1429 * WINPROC_UnmapMsg16To32A
1431 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1433 LRESULT
WINPROC_UnmapMsg16To32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1438 case WM_COMPAREITEM
:
1441 HeapFree( GetProcessHeap(), 0, (LPVOID
)lParam
);
1443 case WM_MEASUREITEM
:
1445 MEASUREITEMSTRUCT16
*mis16
;
1446 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)lParam
;
1447 lParam
= *(LPARAM
*)(mis
+ 1);
1448 mis16
= MapSL(lParam
);
1449 mis16
->itemWidth
= (UINT16
)mis
->itemWidth
;
1450 mis16
->itemHeight
= (UINT16
)mis
->itemHeight
;
1451 HeapFree( GetProcessHeap(), 0, mis
);
1454 case WM_GETMINMAXINFO
:
1456 MINMAXINFO
*mmi
= (MINMAXINFO
*)lParam
;
1457 lParam
= *(LPARAM
*)(mmi
+ 1);
1458 STRUCT32_MINMAXINFO32to16( mmi
, MapSL(lParam
));
1459 HeapFree( GetProcessHeap(), 0, mmi
);
1464 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1465 lParam
= *(LPARAM
*)(cs
+ 1);
1466 STRUCT32_MDICREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1467 HeapFree( GetProcessHeap(), 0, cs
);
1470 case WM_MDIGETACTIVE
:
1471 result
= MAKELONG( LOWORD(result
), (BOOL16
)(*(BOOL
*)lParam
) );
1472 HeapFree( GetProcessHeap(), 0, (BOOL
*)lParam
);
1476 NCCALCSIZE_PARAMS16
*nc16
;
1477 NCCALCSIZE_PARAMS
*nc
= (NCCALCSIZE_PARAMS
*)lParam
;
1478 lParam
= *(LPARAM
*)(nc
+ 1);
1479 nc16
= MapSL(lParam
);
1480 CONV_RECT32TO16( &nc
->rgrc
[0], &nc16
->rgrc
[0] );
1483 CONV_RECT32TO16( &nc
->rgrc
[1], &nc16
->rgrc
[1] );
1484 CONV_RECT32TO16( &nc
->rgrc
[2], &nc16
->rgrc
[2] );
1487 STRUCT32_WINDOWPOS32to16( nc
->lppos
, MapSL(nc16
->lppos
));
1488 HeapFree( GetProcessHeap(), 0, nc
->lppos
);
1491 HeapFree( GetProcessHeap(), 0, nc
);
1497 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1498 lParam
= *(LPARAM
*)(cs
+ 1);
1499 STRUCT32_CREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1500 HeapFree( GetProcessHeap(), 0, cs
);
1503 case WM_WINDOWPOSCHANGING
:
1504 case WM_WINDOWPOSCHANGED
:
1506 WINDOWPOS
*wp
= (WINDOWPOS
*)lParam
;
1507 lParam
= *(LPARAM
*)(wp
+ 1);
1508 STRUCT32_WINDOWPOS32to16(wp
, MapSL(lParam
));
1509 HeapFree( GetProcessHeap(), 0, wp
);
1515 LPMSG msg32
= (LPMSG
)lParam
;
1517 WINPROC_UnmapMsg16To32A( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1519 HeapFree( GetProcessHeap(), 0, msg32
);
1524 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1525 result
= MAKELONG( next
->hmenuNext
, WIN_Handle16(next
->hwndNext
) );
1526 HeapFree( GetProcessHeap(), 0, next
);
1534 /**********************************************************************
1535 * WINPROC_MapMsg16To32W
1537 * Map a message from 16- to 32-bit Unicode.
1538 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1540 INT
WINPROC_MapMsg16To32W( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1541 WPARAM
*pwparam32
, LPARAM
*plparam
)
1546 *pmsg32
=(UINT
)msg16
;
1547 *pwparam32
= (WPARAM
)wParam16
;
1552 case WM_WININICHANGE
:
1553 case WM_DEVMODECHANGE
:
1554 case WM_ASKCBFORMATNAME
:
1555 *plparam
= (LPARAM
)MapSL(*plparam
);
1556 return WINPROC_MapMsg32ATo32W( hwnd
, *pmsg32
, pwparam32
, plparam
);
1557 case WM_GETTEXTLENGTH
:
1558 case CB_GETLBTEXTLEN
:
1560 return 1; /* need to map result */
1564 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1565 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1566 sizeof(*cs
) + sizeof(LPARAM
) );
1568 STRUCT32_CREATESTRUCT16to32A( cs16
, (CREATESTRUCTA
*)cs
);
1569 cs
->lpszName
= map_str_16_to_32W(cs16
->lpszName
);
1570 cs
->lpszClass
= map_str_16_to_32W(cs16
->lpszClass
);
1571 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1572 *plparam
= (LPARAM
)cs
;
1577 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1578 MDICREATESTRUCTW
*cs
=
1579 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1580 sizeof(*cs
) + sizeof(LPARAM
) );
1582 STRUCT32_MDICREATESTRUCT16to32A( cs16
, (MDICREATESTRUCTA
*)cs
);
1583 cs
->szTitle
= map_str_16_to_32W(cs16
->szTitle
);
1584 cs
->szClass
= map_str_16_to_32W(cs16
->szClass
);
1585 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1586 *plparam
= (LPARAM
)cs
;
1592 LPMSG16 msg16
= MapSL(*plparam
);
1593 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1595 if (!msg32
) return -1;
1596 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1597 msg32
->lParam
= msg16
->lParam
;
1598 msg32
->time
= msg16
->time
;
1599 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1600 /* this is right, right? */
1601 if (WINPROC_MapMsg16To32W(hwnd
, msg16
->message
,msg16
->wParam
,
1602 &msg32
->message
,&msg32
->wParam
,
1603 &msg32
->lParam
)<0) {
1604 HeapFree( GetProcessHeap(), 0, msg32
);
1607 *plparam
= (LPARAM
)msg32
;
1614 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1615 *pwparam32
= MAKEWPARAM( wch
, HIWORD(*plparam
) );
1616 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1620 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1621 *pwparam32
= MAKEWPARAM( wch
, LOWORD(*plparam
) );
1622 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1627 case WM_SYSDEADCHAR
:
1629 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1633 default: /* No Unicode translation needed */
1634 return WINPROC_MapMsg16To32A( hwnd
, msg16
, wParam16
, pmsg32
,
1635 pwparam32
, plparam
);
1640 /**********************************************************************
1641 * WINPROC_UnmapMsg16To32W
1643 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1645 LRESULT
WINPROC_UnmapMsg16To32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1652 case WM_GETTEXTLENGTH
:
1653 case CB_GETLBTEXTLEN
:
1655 case WM_ASKCBFORMATNAME
:
1656 return WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
1660 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)lParam
;
1661 lParam
= *(LPARAM
*)(cs
+ 1);
1662 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs
, MapSL(lParam
) );
1663 unmap_str_16_to_32W( cs
->lpszName
);
1664 unmap_str_16_to_32W( cs
->lpszClass
);
1665 HeapFree( GetProcessHeap(), 0, cs
);
1670 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
1671 lParam
= *(LPARAM
*)(cs
+ 1);
1672 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs
, MapSL(lParam
) );
1673 unmap_str_16_to_32W( cs
->szTitle
);
1674 unmap_str_16_to_32W( cs
->szClass
);
1675 HeapFree( GetProcessHeap(), 0, cs
);
1681 LPMSG msg32
= (LPMSG
)lParam
;
1683 WINPROC_UnmapMsg16To32W( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1685 HeapFree( GetProcessHeap(), 0, msg32
);
1689 return WINPROC_UnmapMsg16To32A( hwnd
, msg
, wParam
, lParam
, result
);
1694 static HANDLE16
convert_handle_32_to_16(HANDLE src
, unsigned int flags
)
1697 UINT sz
= GlobalSize(src
);
1700 if (!(dst
= GlobalAlloc16(flags
, sz
)))
1702 ptr32
= GlobalLock(src
);
1703 ptr16
= GlobalLock16(dst
);
1704 if (ptr16
!= NULL
&& ptr32
!= NULL
) memcpy(ptr16
, ptr32
, sz
);
1706 GlobalUnlock16(dst
);
1712 /**********************************************************************
1713 * WINPROC_MapMsg32ATo16
1715 * Map a message from 32-bit Ansi to 16-bit.
1716 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1718 INT
WINPROC_MapMsg32ATo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
1719 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
1722 *pmsg16
= (UINT16
)msg32
;
1723 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1731 *pmsg16
= (UINT16
)msg32
+ (BM_GETCHECK16
- BM_GETCHECK
);
1740 case EM_SCROLLCARET
:
1743 case EM_GETLINECOUNT
:
1755 case EM_LINEFROMCHAR
:
1756 case EM_SETTABSTOPS
:
1757 case EM_SETPASSWORDCHAR
:
1758 case EM_EMPTYUNDOBUFFER
:
1759 case EM_GETFIRSTVISIBLELINE
:
1760 case EM_SETREADONLY
:
1761 case EM_SETWORDBREAKPROC
:
1762 case EM_GETWORDBREAKPROC
:
1763 case EM_GETPASSWORDCHAR
:
1764 *pmsg16
= (UINT16
)msg32
+ (EM_GETSEL16
- EM_GETSEL
);
1769 case LB_DELETESTRING
:
1770 case LB_GETANCHORINDEX
:
1771 case LB_GETCARETINDEX
:
1774 case LB_GETHORIZONTALEXTENT
:
1775 case LB_GETITEMDATA
:
1776 case LB_GETITEMHEIGHT
:
1778 case LB_GETSELCOUNT
:
1780 case LB_GETTOPINDEX
:
1781 case LB_RESETCONTENT
:
1782 case LB_SELITEMRANGE
:
1783 case LB_SELITEMRANGEEX
:
1784 case LB_SETANCHORINDEX
:
1785 case LB_SETCARETINDEX
:
1786 case LB_SETCOLUMNWIDTH
:
1788 case LB_SETHORIZONTALEXTENT
:
1789 case LB_SETITEMDATA
:
1790 case LB_SETITEMHEIGHT
:
1792 case LB_SETTOPINDEX
:
1793 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1795 case CB_DELETESTRING
:
1797 case CB_GETLBTEXTLEN
:
1799 case CB_RESETCONTENT
:
1803 case CB_SHOWDROPDOWN
:
1804 case CB_SETITEMDATA
:
1805 case CB_SETITEMHEIGHT
:
1806 case CB_GETITEMHEIGHT
:
1807 case CB_SETEXTENDEDUI
:
1808 case CB_GETEXTENDEDUI
:
1809 case CB_GETDROPPEDSTATE
:
1810 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1813 *pmsg16
= CB_GETEDITSEL16
;
1818 case LB_FINDSTRINGEXACT
:
1819 case LB_INSERTSTRING
:
1820 case LB_SELECTSTRING
:
1823 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1824 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1829 case CB_FINDSTRINGEXACT
:
1830 case CB_INSERTSTRING
:
1831 case CB_SELECTSTRING
:
1833 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1834 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1837 case LB_GETITEMRECT
:
1839 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1840 if (!rect
) return -1;
1841 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1842 *plparam
= MapLS( rect
);
1844 *pmsg16
= LB_GETITEMRECT16
;
1846 case LB_GETSELITEMS
:
1849 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1850 if (!(items
= HeapAlloc( GetProcessHeap(), 0,
1851 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1852 *((LPARAM
*)items
)++ = *plparam
; /* Store the previous lParam */
1853 *plparam
= MapLS( items
);
1855 *pmsg16
= LB_GETSELITEMS16
;
1857 case LB_SETTABSTOPS
:
1862 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1863 if (!(stops
= HeapAlloc( GetProcessHeap(), 0,
1864 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1865 for (i
= 0; i
< *pwparam16
; i
++) stops
[i
] = *((LPINT
)*plparam
+i
);
1866 *plparam
= MapLS( stops
);
1869 *pmsg16
= LB_SETTABSTOPS16
;
1872 case CB_GETDROPPEDCONTROLRECT
:
1874 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1875 if (!rect
) return -1;
1876 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1877 *plparam
= (LPARAM
)MapLS(rect
);
1879 *pmsg16
= CB_GETDROPPEDCONTROLRECT16
;
1883 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1884 *pmsg16
= LB_GETTEXT16
;
1888 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1889 *pmsg16
= CB_GETLBTEXT16
;
1894 *plparam
= MAKELONG( (INT16
)(INT
)wParam32
, (INT16
)*plparam
);
1895 *pmsg16
= EM_SETSEL16
;
1902 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
1906 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
1908 case WM_CTLCOLORMSGBOX
:
1909 case WM_CTLCOLOREDIT
:
1910 case WM_CTLCOLORLISTBOX
:
1911 case WM_CTLCOLORBTN
:
1912 case WM_CTLCOLORDLG
:
1913 case WM_CTLCOLORSCROLLBAR
:
1914 case WM_CTLCOLORSTATIC
:
1915 *pmsg16
= WM_CTLCOLOR
;
1916 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
1917 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
1919 case WM_COMPAREITEM
:
1921 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)*plparam
;
1922 COMPAREITEMSTRUCT16
*cis
= HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16
));
1923 if (!cis
) return -1;
1924 cis
->CtlType
= (UINT16
)cis32
->CtlType
;
1925 cis
->CtlID
= (UINT16
)cis32
->CtlID
;
1926 cis
->hwndItem
= WIN_Handle16( cis32
->hwndItem
);
1927 cis
->itemID1
= (UINT16
)cis32
->itemID1
;
1928 cis
->itemData1
= cis32
->itemData1
;
1929 cis
->itemID2
= (UINT16
)cis32
->itemID2
;
1930 cis
->itemData2
= cis32
->itemData2
;
1931 *plparam
= MapLS( cis
);
1936 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)*plparam
;
1937 DELETEITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16
) );
1938 if (!dis
) return -1;
1939 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1940 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1941 dis
->itemID
= (UINT16
)dis32
->itemID
;
1942 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
1943 : WIN_Handle16( dis32
->hwndItem
);
1944 dis
->itemData
= dis32
->itemData
;
1945 *plparam
= MapLS( dis
);
1950 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)*plparam
;
1951 DRAWITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16
) );
1952 if (!dis
) return -1;
1953 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1954 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1955 dis
->itemID
= (UINT16
)dis32
->itemID
;
1956 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
1957 dis
->itemState
= (UINT16
)dis32
->itemState
;
1958 dis
->hwndItem
= WIN_Handle16( dis32
->hwndItem
);
1959 dis
->hDC
= (HDC16
)dis32
->hDC
;
1960 dis
->itemData
= dis32
->itemData
;
1961 CONV_RECT32TO16( &dis32
->rcItem
, &dis
->rcItem
);
1962 *plparam
= MapLS( dis
);
1965 case WM_MEASUREITEM
:
1967 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)*plparam
;
1968 MEASUREITEMSTRUCT16
*mis
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mis
)+sizeof(LPARAM
));
1969 if (!mis
) return -1;
1970 mis
->CtlType
= (UINT16
)mis32
->CtlType
;
1971 mis
->CtlID
= (UINT16
)mis32
->CtlID
;
1972 mis
->itemID
= (UINT16
)mis32
->itemID
;
1973 mis
->itemWidth
= (UINT16
)mis32
->itemWidth
;
1974 mis
->itemHeight
= (UINT16
)mis32
->itemHeight
;
1975 mis
->itemData
= mis32
->itemData
;
1976 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1977 *plparam
= MapLS( mis
);
1980 case WM_GETMINMAXINFO
:
1982 MINMAXINFO16
*mmi
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi
) + sizeof(LPARAM
) );
1983 if (!mmi
) return -1;
1984 STRUCT32_MINMAXINFO32to16( (MINMAXINFO
*)*plparam
, mmi
);
1985 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1986 *plparam
= MapLS( mmi
);
1990 case WM_ASKCBFORMATNAME
:
1993 *pwparam16
= (WPARAM16
)min( wParam32
, 0xff80 ); /* Must be < 64K */
1994 if (!(str
= HeapAlloc( GetProcessHeap(), 0, *pwparam16
+ sizeof(LPARAM
)))) return -1;
1995 *((LPARAM
*)str
)++ = *plparam
; /* Store the previous lParam */
1996 *plparam
= MapLS( str
);
2001 MDICREATESTRUCT16
*cs
;
2002 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)*plparam
;
2004 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2005 STRUCT32_MDICREATESTRUCT32Ato16( cs32
, cs
);
2006 cs
->szTitle
= MapLS( cs32
->szTitle
);
2007 cs
->szClass
= MapLS( cs32
->szClass
);
2008 *plparam
= MapLS( cs
);
2011 case WM_MDIGETACTIVE
:
2014 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
2015 (HMENU16
)LOWORD(*plparam
) );
2016 *pwparam16
= (*plparam
== 0);
2019 if(HIWORD(wParam32
) & MF_POPUP
)
2022 if (((UINT
)HIWORD(wParam32
) != 0xFFFF) || (*plparam
))
2024 if((hmenu
= GetSubMenu((HMENU16
)*plparam
, *pwparam16
)))
2030 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2032 case WM_MDIACTIVATE
:
2033 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
2035 *pwparam16
= ((HWND
)*plparam
== hwnd
);
2036 *plparam
= MAKELPARAM( (HWND16
)LOWORD(*plparam
),
2037 (HWND16
)LOWORD(wParam32
) );
2041 *pwparam16
= WIN_Handle16( (HWND
)wParam32
);
2047 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)*plparam
;
2048 NCCALCSIZE_PARAMS16
*nc
= HeapAlloc( GetProcessHeap(), 0, sizeof(*nc
) + sizeof(LPARAM
));
2051 CONV_RECT32TO16( &nc32
->rgrc
[0], &nc
->rgrc
[0] );
2055 CONV_RECT32TO16( &nc32
->rgrc
[1], &nc
->rgrc
[1] );
2056 CONV_RECT32TO16( &nc32
->rgrc
[2], &nc
->rgrc
[2] );
2057 if (!(wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16
) )))
2059 HeapFree( GetProcessHeap(), 0, nc
);
2062 STRUCT32_WINDOWPOS32to16( nc32
->lppos
, wp
);
2063 nc
->lppos
= MapLS( wp
);
2065 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
2066 *plparam
= MapLS( nc
);
2073 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)*plparam
;
2075 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2076 STRUCT32_CREATESTRUCT32Ato16( cs32
, cs
);
2077 cs
->lpszName
= MapLS( cs32
->lpszName
);
2078 cs
->lpszClass
= MapLS( cs32
->lpszClass
);
2079 *plparam
= MapLS( cs
);
2082 case WM_PARENTNOTIFY
:
2083 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
2084 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
2085 /* else nothing to do */
2088 *plparam
= MapLS( (NMHDR
*)*plparam
); /* NMHDR is already 32-bit */
2091 case WM_WININICHANGE
:
2092 case WM_DEVMODECHANGE
:
2093 *plparam
= MapLS( (LPSTR
)*plparam
);
2095 case WM_WINDOWPOSCHANGING
:
2096 case WM_WINDOWPOSCHANGED
:
2098 WINDOWPOS16
*wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(*wp
) + sizeof(LPARAM
) );
2100 STRUCT32_WINDOWPOS32to16( (WINDOWPOS
*)*plparam
, wp
);
2101 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
2102 *plparam
= MapLS( wp
);
2107 LPMSG msg32
= (LPMSG
) *plparam
;
2108 LPMSG16 msg16
= HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16
) );
2110 if (!msg16
) return -1;
2111 msg16
->hwnd
= WIN_Handle16( msg32
->hwnd
);
2112 msg16
->lParam
= msg32
->lParam
;
2113 msg16
->time
= msg32
->time
;
2114 CONV_POINT32TO16(&msg32
->pt
,&msg16
->pt
);
2115 /* this is right, right? */
2116 if (WINPROC_MapMsg32ATo16(msg32
->hwnd
,msg32
->message
,msg32
->wParam
,
2117 &msg16
->message
,&msg16
->wParam
, &msg16
->lParam
)<0)
2119 HeapFree( GetProcessHeap(), 0, msg16
);
2122 *plparam
= MapLS( msg16
);
2127 case WM_ACTIVATEAPP
:
2128 if (*plparam
) *plparam
= (LPARAM
)THREAD_IdToTEB((DWORD
) *plparam
)->htask16
;
2132 MDINEXTMENU
*next
= (MDINEXTMENU
*)*plparam
;
2133 *plparam
= next
->hmenuIn
;
2136 case WM_PAINTCLIPBOARD
:
2137 case WM_SIZECLIPBOARD
:
2138 FIXME_(msg
)("message %04x needs translation\n", msg32
);
2140 /* following messages should not be sent to 16-bit apps */
2143 case WM_CAPTURECHANGED
:
2144 case WM_STYLECHANGING
:
2145 case WM_STYLECHANGED
:
2147 case WM_DDE_INITIATE
:
2148 case WM_DDE_TERMINATE
:
2149 case WM_DDE_UNADVISE
:
2150 case WM_DDE_REQUEST
:
2151 *pwparam16
= WIN_Handle16(wParam32
);
2160 *pwparam16
= WIN_Handle16(wParam32
);
2161 UnpackDDElParam(msg32
, *plparam
, &lo32
, &hi
);
2162 if (lo32
&& !(lo16
= convert_handle_32_to_16(lo32
, GMEM_DDESHARE
)))
2164 *plparam
= MAKELPARAM(lo16
, hi
);
2166 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2173 *pwparam16
= WIN_Handle16(wParam32
);
2175 UnpackDDElParam(msg32
, *plparam
, &lo
, &hi
);
2177 if (GlobalGetAtomNameA((ATOM
)hi
, buf
, sizeof(buf
)) > 0) flag
|= 1;
2178 if (GlobalSize(hi
) != 0) flag
|= 2;
2184 MESSAGE("DDE_ACK: neither atom nor handle!!!\n");
2189 break; /* atom, nothing to do */
2191 MESSAGE("DDE_ACK: %x both atom and handle... choosing handle\n", hi
);
2194 hi
= convert_handle_32_to_16(hi
, GMEM_DDESHARE
);
2197 *plparam
= MAKELPARAM(lo
, hi
);
2199 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2200 case WM_DDE_EXECUTE
:
2201 *plparam
= convert_handle_32_to_16(*plparam
, GMEM_DDESHARE
);
2202 return 0; /* FIXME don't know how to free allocated memory (handle) !! */
2203 default: /* No translation needed */
2209 /**********************************************************************
2210 * WINPROC_UnmapMsg32ATo16
2212 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2214 void WINPROC_UnmapMsg32ATo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2223 case LB_FINDSTRINGEXACT
:
2224 case LB_INSERTSTRING
:
2225 case LB_SELECTSTRING
:
2229 case CB_FINDSTRINGEXACT
:
2230 case CB_INSERTSTRING
:
2231 case CB_SELECTSTRING
:
2235 case WM_WININICHANGE
:
2236 case WM_DEVMODECHANGE
:
2237 UnMapLS( (SEGPTR
)p16
->lParam
);
2239 case LB_SETTABSTOPS
:
2240 case WM_COMPAREITEM
:
2244 void *ptr
= MapSL( p16
->lParam
);
2245 UnMapLS( p16
->lParam
);
2246 HeapFree( GetProcessHeap(), 0, ptr
);
2249 case CB_GETDROPPEDCONTROLRECT
:
2250 case LB_GETITEMRECT
:
2252 RECT16
*rect
= MapSL(p16
->lParam
);
2253 UnMapLS( p16
->lParam
);
2254 p16
->lParam
= *(LPARAM
*)(rect
+ 1);
2255 CONV_RECT16TO32( rect
, (RECT
*)(p16
->lParam
));
2256 HeapFree( GetProcessHeap(), 0, rect
);
2259 case LB_GETSELITEMS
:
2262 LPINT16 items
= MapSL(p16
->lParam
);
2263 UnMapLS( p16
->lParam
);
2264 p16
->lParam
= *((LPARAM
*)items
- 1);
2265 for (i
= 0; i
< p16
->wParam
; i
++) *((LPINT
)(p16
->lParam
) + i
) = items
[i
];
2266 HeapFree( GetProcessHeap(), 0, (LPARAM
*)items
- 1 );
2272 *((LPUINT
)(wParam
)) = LOWORD(p16
->lResult
);
2274 *((LPUINT
)(lParam
)) = HIWORD(p16
->lResult
); /* FIXME: substract 1? */
2277 case WM_MEASUREITEM
:
2279 MEASUREITEMSTRUCT16
*mis
= MapSL(p16
->lParam
);
2280 MEASUREITEMSTRUCT
*mis32
= *(MEASUREITEMSTRUCT
**)(mis
+ 1);
2281 mis32
->itemWidth
= mis
->itemWidth
;
2282 mis32
->itemHeight
= mis
->itemHeight
;
2283 UnMapLS( p16
->lParam
);
2284 HeapFree( GetProcessHeap(), 0, mis
);
2287 case WM_GETMINMAXINFO
:
2289 MINMAXINFO16
*mmi
= MapSL(p16
->lParam
);
2290 UnMapLS( p16
->lParam
);
2291 p16
->lParam
= *(LPARAM
*)(mmi
+ 1);
2292 STRUCT32_MINMAXINFO16to32( mmi
, (MINMAXINFO
*)(p16
->lParam
) );
2293 HeapFree( GetProcessHeap(), 0, mmi
);
2297 case WM_ASKCBFORMATNAME
:
2299 LPSTR str
= MapSL(p16
->lParam
);
2300 UnMapLS( p16
->lParam
);
2301 p16
->lParam
= *((LPARAM
*)str
- 1);
2302 lstrcpynA( (LPSTR
)(p16
->lParam
), str
, p16
->wParam
);
2303 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2308 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2309 UnMapLS( cs
->szTitle
);
2310 UnMapLS( cs
->szClass
);
2311 UnMapLS( p16
->lParam
);
2312 HeapFree( GetProcessHeap(), 0, cs
);
2315 case WM_MDIGETACTIVE
:
2316 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(p16
->lResult
);
2317 p16
->lResult
= (LRESULT
)WIN_Handle32( LOWORD(p16
->lResult
) );
2321 NCCALCSIZE_PARAMS
*nc32
;
2322 NCCALCSIZE_PARAMS16
*nc
= MapSL(p16
->lParam
);
2323 UnMapLS( p16
->lParam
);
2324 p16
->lParam
= *(LPARAM
*)(nc
+ 1);
2325 nc32
= (NCCALCSIZE_PARAMS
*)(p16
->lParam
);
2326 CONV_RECT16TO32( &nc
->rgrc
[0], &nc32
->rgrc
[0] );
2329 WINDOWPOS16
*pos
= MapSL(nc
->lppos
);
2330 UnMapLS( nc
->lppos
);
2331 CONV_RECT16TO32( &nc
->rgrc
[1], &nc32
->rgrc
[1] );
2332 CONV_RECT16TO32( &nc
->rgrc
[2], &nc32
->rgrc
[2] );
2333 STRUCT32_WINDOWPOS16to32( pos
, nc32
->lppos
);
2334 HeapFree( GetProcessHeap(), 0, pos
);
2336 HeapFree( GetProcessHeap(), 0, nc
);
2342 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2343 UnMapLS( p16
->lParam
);
2344 UnMapLS( cs
->lpszName
);
2345 UnMapLS( cs
->lpszClass
);
2346 HeapFree( GetProcessHeap(), 0, cs
);
2349 case WM_WINDOWPOSCHANGING
:
2350 case WM_WINDOWPOSCHANGED
:
2352 WINDOWPOS16
*wp
= MapSL(p16
->lParam
);
2353 UnMapLS( p16
->lParam
);
2354 p16
->lParam
= *(LPARAM
*)(wp
+ 1);
2355 STRUCT32_WINDOWPOS16to32( wp
, (WINDOWPOS
*)p16
->lParam
);
2356 HeapFree( GetProcessHeap(), 0, wp
);
2360 UnMapLS(p16
->lParam
);
2365 LPMSG16 msg16
= MapSL(p16
->lParam
);
2367 UnMapLS( p16
->lParam
);
2368 msgp16
.wParam
=msg16
->wParam
;
2369 msgp16
.lParam
=msg16
->lParam
;
2370 WINPROC_UnmapMsg32ATo16(((LPMSG
)lParam
)->hwnd
, ((LPMSG
)lParam
)->message
,
2371 ((LPMSG
)lParam
)->wParam
, ((LPMSG
)lParam
)->lParam
,
2373 HeapFree( GetProcessHeap(), 0, msg16
);
2378 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
2379 next
->hmenuNext
= LOWORD(p16
->lResult
);
2380 next
->hwndNext
= WIN_Handle32( HIWORD(p16
->lResult
) );
2388 /**********************************************************************
2389 * WINPROC_MapMsg32WTo16
2391 * Map a message from 32-bit Unicode to 16-bit.
2392 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2394 INT
WINPROC_MapMsg32WTo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
2395 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
2401 *pmsg16
= LOWORD(msg32
);
2402 *pwparam16
= LOWORD(wParam32
);
2407 case LB_FINDSTRINGEXACT
:
2408 case LB_INSERTSTRING
:
2409 case LB_SELECTSTRING
:
2412 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2413 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2418 case CB_FINDSTRINGEXACT
:
2419 case CB_INSERTSTRING
:
2420 case CB_SELECTSTRING
:
2422 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2423 *pmsg16
= (UINT16
)msg32
+ (CB_ADDSTRING16
- CB_ADDSTRING
);
2430 CREATESTRUCTW
*cs32
= (CREATESTRUCTW
*)*plparam
;
2432 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2433 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs32
, cs
);
2434 cs
->lpszName
= map_str_32W_to_16( cs32
->lpszName
);
2435 cs
->lpszClass
= map_str_32W_to_16( cs32
->lpszClass
);
2436 *plparam
= MapLS(cs
);
2441 MDICREATESTRUCT16
*cs
;
2442 MDICREATESTRUCTW
*cs32
= (MDICREATESTRUCTW
*)*plparam
;
2444 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2445 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs32
, cs
);
2446 cs
->szTitle
= map_str_32W_to_16( cs32
->szTitle
);
2447 cs
->szClass
= map_str_32W_to_16( cs32
->szClass
);
2448 *plparam
= MapLS(cs
);
2452 case WM_WININICHANGE
:
2453 case WM_DEVMODECHANGE
:
2454 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2458 if ( WINPROC_TestLBForStr( hwnd
))
2460 LPSTR str
= HeapAlloc( GetProcessHeap(), 0, 256 ); /* FIXME: fixed sized buffer */
2461 if (!str
) return -1;
2462 *pmsg16
= (msg32
== LB_GETTEXT
)? LB_GETTEXT16
: CB_GETLBTEXT16
;
2463 *plparam
= (LPARAM
)MapLS(str
);
2468 wch
= LOWORD(wParam32
);
2469 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2471 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
2474 wch
= LOWORD(wParam32
);
2475 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2477 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2482 case WM_SYSDEADCHAR
:
2484 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2488 default: /* No Unicode translation needed (?) */
2489 return WINPROC_MapMsg32ATo16( hwnd
, msg32
, wParam32
, pmsg16
,
2490 pwparam16
, plparam
);
2495 /**********************************************************************
2496 * WINPROC_UnmapMsg32WTo16
2498 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2500 void WINPROC_UnmapMsg32WTo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2507 case LB_FINDSTRINGEXACT
:
2508 case LB_INSERTSTRING
:
2509 case LB_SELECTSTRING
:
2514 case CB_FINDSTRINGEXACT
:
2515 case CB_INSERTSTRING
:
2516 case CB_SELECTSTRING
:
2519 case WM_WININICHANGE
:
2520 case WM_DEVMODECHANGE
:
2521 unmap_str_32W_to_16( p16
->lParam
);
2526 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2527 UnMapLS( p16
->lParam
);
2528 unmap_str_32W_to_16( cs
->lpszName
);
2529 unmap_str_32W_to_16( cs
->lpszClass
);
2530 HeapFree( GetProcessHeap(), 0, cs
);
2535 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2536 UnMapLS( p16
->lParam
);
2537 unmap_str_32W_to_16( cs
->szTitle
);
2538 unmap_str_32W_to_16( cs
->szClass
);
2539 HeapFree( GetProcessHeap(), 0, cs
);
2543 case WM_ASKCBFORMATNAME
:
2545 LPSTR str
= MapSL(p16
->lParam
);
2546 UnMapLS( p16
->lParam
);
2547 p16
->lParam
= *((LPARAM
*)str
- 1);
2548 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)p16
->lParam
, 0x7fffffff );
2549 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2554 if ( WINPROC_TestLBForStr( hwnd
))
2556 LPSTR str
= MapSL(p16
->lParam
);
2557 UnMapLS( p16
->lParam
);
2558 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)lParam
, 0x7fffffff );
2559 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
);
2563 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, p16
);
2569 /**********************************************************************
2570 * WINPROC_CallProc32ATo32W
2572 * Call a window procedure, translating args from Ansi to Unicode.
2574 static LRESULT
WINPROC_CallProc32ATo32W( WNDPROC func
, HWND hwnd
,
2575 UINT msg
, WPARAM wParam
,
2581 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2582 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2584 if( (unmap
= WINPROC_MapMsg32ATo32W( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
2585 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2586 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2589 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2590 if (unmap
) result
= WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
2595 /**********************************************************************
2596 * WINPROC_CallProc32WTo32A
2598 * Call a window procedure, translating args from Unicode to Ansi.
2600 static LRESULT
WINPROC_CallProc32WTo32A( WNDPROC func
, HWND hwnd
,
2601 UINT msg
, WPARAM wParam
,
2607 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2608 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2610 if ((unmap
= WINPROC_MapMsg32WTo32A( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
2611 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2612 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2615 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2616 if( unmap
) WINPROC_UnmapMsg32WTo32A( hwnd
, msg
, wParam
, lParam
);
2621 /**********************************************************************
2622 * __wine_call_wndproc_32A (USER.1010)
2624 LRESULT WINAPI
__wine_call_wndproc_32A( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
2630 HWND hwnd32
= WIN_Handle32( hwnd
);
2632 if (WINPROC_MapMsg16To32A( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2634 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
2635 return WINPROC_UnmapMsg16To32A( hwnd32
, msg32
, wParam32
, lParam
, result
);
2639 /**********************************************************************
2640 * __wine_call_wndproc_32W (USER.1011)
2642 LRESULT WINAPI
__wine_call_wndproc_32W( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
2648 HWND hwnd32
= WIN_Handle32( hwnd
);
2650 if (WINPROC_MapMsg16To32W( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2652 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
2653 return WINPROC_UnmapMsg16To32W( hwnd32
, msg32
, wParam32
, lParam
, result
);
2657 /**********************************************************************
2658 * WINPROC_CallProc32ATo16
2660 * Call a 16-bit window procedure, translating the 32-bit args.
2662 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
2663 UINT msg
, WPARAM wParam
,
2669 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2670 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2672 mp16
.lParam
= lParam
;
2673 if (WINPROC_MapMsg32ATo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
, &mp16
.lParam
) == -1)
2675 mp16
.lResult
= WINPROC_CallWndProc16( func
, WIN_Handle16(hwnd
), msg16
,
2676 mp16
.wParam
, mp16
.lParam
);
2677 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2678 return mp16
.lResult
;
2682 /**********************************************************************
2683 * WINPROC_CallProc32WTo16
2685 * Call a 16-bit window procedure, translating the 32-bit args.
2687 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
2688 UINT msg
, WPARAM wParam
,
2694 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2695 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2697 mp16
.lParam
= lParam
;
2698 if (WINPROC_MapMsg32WTo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
,
2699 &mp16
.lParam
) == -1)
2701 mp16
.lResult
= WINPROC_CallWndProc16( func
, WIN_Handle16(hwnd
), msg16
,
2702 mp16
.wParam
, mp16
.lParam
);
2703 WINPROC_UnmapMsg32WTo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2704 return mp16
.lResult
;
2708 /**********************************************************************
2709 * CallWindowProc (USER.122)
2710 * CallWindowProc16 (USER32.@)
2712 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
2713 WPARAM16 wParam
, LPARAM lParam
)
2717 if (!func
) return 0;
2719 if (!(proc
= WINPROC_GetPtr( func
)))
2720 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2723 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_16
);
2724 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2730 if (!proc
->thunk
.t_from32
.proc
) return 0;
2731 return WINPROC_CallWndProc16( proc
->thunk
.t_from32
.proc
,
2732 hwnd
, msg
, wParam
, lParam
);
2734 if (!proc
->thunk
.t_from16
.proc
) return 0;
2735 return __wine_call_wndproc_32A( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
2737 if (!proc
->thunk
.t_from16
.proc
) return 0;
2738 return __wine_call_wndproc_32W( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
2740 WARN_(relay
)("Invalid proc %p\n", proc
);
2746 /**********************************************************************
2747 * CallWindowProcA (USER32.@)
2749 * The CallWindowProc() function invokes the windows procedure _func_,
2750 * with _hwnd_ as the target window, the message specified by _msg_, and
2751 * the message parameters _wParam_ and _lParam_.
2753 * Some kinds of argument conversion may be done, I'm not sure what.
2755 * CallWindowProc() may be used for windows subclassing. Use
2756 * SetWindowLong() to set a new windows procedure for windows of the
2757 * subclass, and handle subclassed messages in the new windows
2758 * procedure. The new windows procedure may then use CallWindowProc()
2759 * with _func_ set to the parent class's windows procedure to dispatch
2760 * the message to the superclass.
2764 * The return value is message dependent.
2770 LRESULT WINAPI
CallWindowProcA(
2771 WNDPROC func
, /* [in] window procedure */
2772 HWND hwnd
, /* [in] target window */
2773 UINT msg
, /* [in] message */
2774 WPARAM wParam
, /* [in] message dependent parameter */
2775 LPARAM lParam
/* [in] message dependent parameter */
2777 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2779 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2782 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32A
);
2783 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2789 if (!proc
->thunk
.t_from32
.proc
) return 0;
2790 return WINPROC_CallProc32ATo16( proc
->thunk
.t_from32
.proc
,
2791 hwnd
, msg
, wParam
, lParam
);
2793 if (!proc
->thunk
.t_from16
.proc
) return 0;
2794 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2795 hwnd
, msg
, wParam
, lParam
);
2797 if (!proc
->thunk
.t_from16
.proc
) return 0;
2798 return WINPROC_CallProc32ATo32W( proc
->thunk
.t_from16
.proc
,
2799 hwnd
, msg
, wParam
, lParam
);
2801 WARN_(relay
)("Invalid proc %p\n", proc
);
2807 /**********************************************************************
2808 * CallWindowProcW (USER32.@)
2810 LRESULT WINAPI
CallWindowProcW( WNDPROC func
, HWND hwnd
, UINT msg
,
2811 WPARAM wParam
, LPARAM lParam
)
2813 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2815 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2818 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32W
);
2819 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2825 if (!proc
->thunk
.t_from32
.proc
) return 0;
2826 return WINPROC_CallProc32WTo16( proc
->thunk
.t_from32
.proc
,
2827 hwnd
, msg
, wParam
, lParam
);
2829 if (!proc
->thunk
.t_from16
.proc
) return 0;
2830 return WINPROC_CallProc32WTo32A( proc
->thunk
.t_from16
.proc
,
2831 hwnd
, msg
, wParam
, lParam
);
2833 if (!proc
->thunk
.t_from16
.proc
) return 0;
2834 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2835 hwnd
, msg
, wParam
, lParam
);
2837 WARN_(relay
)("Invalid proc %p\n", proc
);