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"
44 WINE_DECLARE_DEBUG_CHANNEL(msg
);
45 WINE_DECLARE_DEBUG_CHANNEL(relay
);
46 WINE_DECLARE_DEBUG_CHANNEL(win
);
50 /* Window procedure 16-to-32-bit thunk */
53 BYTE popl_eax
; /* popl %eax (return address) */
54 BYTE pushl_func
; /* pushl $proc */
56 BYTE pushl_eax
; /* pushl %eax */
57 BYTE ljmp
; /* ljmp relay*/
58 DWORD relay_offset
; /* __wine_call_wndproc_32A/W */
60 } WINPROC_THUNK_FROM16
;
62 /* Window procedure 32-to-16-bit thunk */
65 BYTE popl_eax
; /* popl %eax (return address) */
66 BYTE pushl_func
; /* pushl $proc */
68 BYTE pushl_eax
; /* pushl %eax */
69 BYTE jmp
; /* jmp relay (relative jump)*/
70 void (*relay
)(); /* WINPROC_CallProc32ATo16() */
71 } WINPROC_THUNK_FROM32
;
73 /* Simple jmp to call 32-bit procedure directly */
76 BYTE jmp
; /* jmp proc (relative jump) */
83 WINPROC_THUNK_FROM16 t_from16
;
84 WINPROC_THUNK_FROM32 t_from32
;
87 typedef struct tagWINDOWPROC
89 WINPROC_THUNK thunk
; /* Thunk */
90 WINPROC_JUMP jmp
; /* Jump */
91 struct tagWINDOWPROC
*next
; /* Next window proc */
92 UINT magic
; /* Magic number */
93 WINDOWPROCTYPE type
; /* Function type */
94 WINDOWPROCUSER user
; /* Function user */
97 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
99 #define WINPROC_THUNKPROC(pproc) \
100 (((pproc)->type == WIN_PROC_16) ? \
101 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
102 (WNDPROC16)((pproc)->thunk.t_from16.proc))
104 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
105 UINT msg
, WPARAM wParam
,
107 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
108 UINT msg
, WPARAM wParam
,
111 static HANDLE WinProcHeap
;
112 static WORD WinProcSel
;
115 /**********************************************************************
118 BOOL
WINPROC_Init(void)
120 WinProcHeap
= HeapCreate( 0, 0x10000, 0x10000 );
121 WinProcSel
= SELECTOR_AllocBlock( (void *)WinProcHeap
, 0x10000,
122 WINE_LDT_FLAGS_CODE
| WINE_LDT_FLAGS_32BIT
);
123 if (!WinProcHeap
|| !WinProcSel
)
125 WARN_(relay
)("Unable to create winproc heap\n" );
133 /* Some window procedures modify register they shouldn't, or are not
134 * properly declared stdcall; so we need a small assembly wrapper to
136 extern LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
137 WPARAM wParam
, LPARAM lParam
);
138 __ASM_GLOBAL_FUNC( WINPROC_wrapper
,
148 "movl 8(%ebp),%eax\n\t"
150 "leal -12(%ebp),%esp\n\t"
157 static inline LRESULT
WINPROC_wrapper( WNDPROC proc
, HWND hwnd
, UINT msg
,
158 WPARAM wParam
, LPARAM lParam
)
160 return proc( hwnd
, msg
, wParam
, lParam
);
162 #endif /* __i386__ */
164 /**********************************************************************
165 * WINPROC_CallWndProc32
167 * Call a 32-bit WndProc.
169 static LRESULT
WINPROC_CallWndProc( WNDPROC proc
, HWND hwnd
, UINT msg
,
170 WPARAM wParam
, LPARAM lParam
)
175 hwnd
= WIN_GetFullHandle( hwnd
);
177 DPRINTF( "%08lx:Call window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
178 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
179 /* To avoid any deadlocks, all the locks on the windows structures
180 must be suspended before the control is passed to the application */
181 iWndsLocks
= WIN_SuspendWndsLock();
182 retvalue
= WINPROC_wrapper( proc
, hwnd
, msg
, wParam
, lParam
);
183 WIN_RestoreWndsLock(iWndsLocks
);
186 DPRINTF( "%08lx:Ret window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
187 GetCurrentThreadId(), proc
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
, retvalue
);
191 /***********************************************************************
192 * WINPROC_CallWndProc16
194 * Call a 16-bit window procedure
196 static LRESULT WINAPI
WINPROC_CallWndProc16( WNDPROC16 proc
, HWND16 hwnd
,
197 UINT16 msg
, WPARAM16 wParam
,
204 TEB
*teb
= NtCurrentTeb();
207 /* Window procedures want ax = hInstance, ds = es = ss */
209 memset(&context
, '\0', sizeof(context
));
210 context
.SegDs
= context
.SegEs
= SELECTOROF(teb
->cur_stack
);
211 if (!(context
.Eax
= GetWindowWord16( hwnd
, GWL_HINSTANCE
))) context
.Eax
= context
.SegDs
;
212 context
.SegCs
= SELECTOROF(proc
);
213 context
.Eip
= OFFSETOF(proc
);
214 context
.Ebp
= OFFSETOF(teb
->cur_stack
)
215 + (WORD
)&((STACK16FRAME
*)0)->bp
;
219 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
220 work if structures passed in lParam are placed in the stack/data
221 segment. Programmers easily make the mistake of converting lParam
222 to a near rather than a far pointer, since Windows apparently
223 allows this. We copy the structures to the 16 bit stack; this is
224 ugly but makes these programs work. */
229 offset
= sizeof(CREATESTRUCT16
); break;
231 offset
= sizeof(DRAWITEMSTRUCT16
); break;
233 offset
= sizeof(COMPAREITEMSTRUCT16
); break;
237 void *s
= MapSL(lParam
);
238 lParam
= stack16_push( offset
);
239 memcpy( MapSL(lParam
), s
, offset
);
243 iWndsLocks
= WIN_SuspendWndsLock();
245 args
= (WORD
*)THREAD_STACK16(teb
) - 5;
246 args
[0] = LOWORD(lParam
);
247 args
[1] = HIWORD(lParam
);
252 wine_call_to_16_regs_short( &context
, 5 * sizeof(WORD
) );
253 ret
= MAKELONG( LOWORD(context
.Eax
), LOWORD(context
.Edx
) );
254 if (offset
) stack16_pop( offset
);
256 WIN_RestoreWndsLock(iWndsLocks
);
262 /**********************************************************************
265 * Return a pointer to the win proc.
267 static WINDOWPROC
*WINPROC_GetPtr( WNDPROC16 handle
)
272 /* ptr cannot be < 64K */
273 if (!HIWORD(handle
)) return NULL
;
275 /* Check for a linear pointer */
277 ptr
= (BYTE
*)handle
;
278 /* First check if it is the jmp address */
279 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->jmp
);
280 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
282 /* Now it must be the thunk address */
283 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
284 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
287 /* Check for a segmented pointer */
289 if (!IsBadReadPtr16( (SEGPTR
)handle
, sizeof(proc
->thunk
) ))
291 ptr
= MapSL( (SEGPTR
)handle
);
292 /* It must be the thunk address */
293 proc
= (WINDOWPROC
*)(ptr
- (int)&((WINDOWPROC
*)0)->thunk
);
294 if (HeapValidate( WinProcHeap
, 0, proc
) && (proc
->magic
== WINPROC_MAGIC
))
302 /**********************************************************************
303 * WINPROC_AllocWinProc
305 * Allocate a new window procedure.
307 static WINDOWPROC
*WINPROC_AllocWinProc( WNDPROC16 func
, WINDOWPROCTYPE type
,
308 WINDOWPROCUSER user
)
310 static FARPROC16 relay_32A
, relay_32W
;
312 WINDOWPROC
*proc
, *oldproc
;
314 /* Allocate a window procedure */
316 if (!(proc
= HeapAlloc( WinProcHeap
, 0, sizeof(WINDOWPROC
) ))) return 0;
318 /* Check if the function is already a win proc */
320 if ((oldproc
= WINPROC_GetPtr( func
)))
329 proc
->thunk
.t_from32
.popl_eax
= 0x58; /* popl %eax */
330 proc
->thunk
.t_from32
.pushl_func
= 0x68; /* pushl $proc */
331 proc
->thunk
.t_from32
.proc
= func
;
332 proc
->thunk
.t_from32
.pushl_eax
= 0x50; /* pushl %eax */
333 proc
->thunk
.t_from32
.jmp
= 0xe9; /* jmp relay*/
334 proc
->thunk
.t_from32
.relay
= /* relative jump */
335 (void(*)())((DWORD
)WINPROC_CallProc32ATo16
-
336 (DWORD
)(&proc
->thunk
.t_from32
.relay
+ 1));
339 if (!relay_32A
) relay_32A
= GetProcAddress16( GetModuleHandle16("user"),
340 "__wine_call_wndproc_32A" );
341 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
342 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
343 proc
->thunk
.t_from16
.proc
= (WNDPROC
)func
;
344 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
345 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
346 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32A
);
347 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32A
);
348 proc
->jmp
.jmp
= 0xe9;
349 /* Fixup relative jump */
350 proc
->jmp
.proc
= (WNDPROC
)((DWORD
)func
- (DWORD
)(&proc
->jmp
.proc
+ 1));
353 if (!relay_32W
) relay_32W
= GetProcAddress16( GetModuleHandle16("user"),
354 "__wine_call_wndproc_32W" );
355 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
356 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
357 proc
->thunk
.t_from16
.proc
= (WNDPROC
)func
;
358 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
359 proc
->thunk
.t_from16
.ljmp
= 0xea; /* ljmp relay*/
360 proc
->thunk
.t_from16
.relay_offset
= OFFSETOF(relay_32W
);
361 proc
->thunk
.t_from16
.relay_sel
= SELECTOROF(relay_32W
);
362 proc
->jmp
.jmp
= 0xe9;
363 /* Fixup relative jump */
364 proc
->jmp
.proc
= (WNDPROC
)((DWORD
)func
- (DWORD
)(&proc
->jmp
.proc
+ 1));
367 /* Should not happen */
370 proc
->magic
= WINPROC_MAGIC
;
375 TRACE_(win
)("(%08x,%d): returning %08x\n",
376 (UINT
)func
, type
, (UINT
)proc
);
381 /**********************************************************************
384 * Get a window procedure pointer that can be passed to the Windows program.
386 WNDPROC16
WINPROC_GetProc( HWINDOWPROC proc
, WINDOWPROCTYPE type
)
388 WINDOWPROC
*ptr
= (WINDOWPROC
*)proc
;
390 if (!proc
) return NULL
;
391 if (type
== WIN_PROC_16
) /* We want a 16:16 address */
393 if (ptr
->type
== WIN_PROC_16
)
394 return ptr
->thunk
.t_from32
.proc
;
396 return (WNDPROC16
)MAKESEGPTR( WinProcSel
, (char *)&ptr
->thunk
- (char *)WinProcHeap
);
398 else /* We want a 32-bit address */
400 if (ptr
->type
== WIN_PROC_16
)
401 return (WNDPROC16
)&ptr
->thunk
;
402 else if (type
!= ptr
->type
)
403 /* Have to return the jmp address if types don't match */
404 return (WNDPROC16
)&ptr
->jmp
;
406 /* Some Win16 programs want to get back the proc they set */
407 return (WNDPROC16
)ptr
->thunk
.t_from16
.proc
;
412 /**********************************************************************
415 * Set the window procedure for a window or class. There are
416 * three tree classes of winproc callbacks:
418 * 1) class -> wp - not subclassed
419 * class -> wp -> wp -> wp -> wp - SetClassLong()
421 * 2) window -' / - not subclassed
422 * window -> wp -> wp ' - SetWindowLong()
424 * 3) timer -> wp - SetTimer()
426 * Initially, winproc of the window points to the current winproc
427 * thunk of its class. Subclassing prepends a new thunk to the
428 * window winproc chain at the head of the list. Thus, window thunk
429 * list includes class thunks and the latter are preserved when the
430 * window is destroyed.
433 BOOL
WINPROC_SetProc( HWINDOWPROC
*pFirst
, WNDPROC16 func
,
434 WINDOWPROCTYPE type
, WINDOWPROCUSER user
)
436 BOOL bRecycle
= FALSE
;
437 WINDOWPROC
*proc
, **ppPrev
;
439 /* Check if function is already in the list */
441 ppPrev
= (WINDOWPROC
**)pFirst
;
442 proc
= WINPROC_GetPtr( func
);
449 if ((*ppPrev
)->user
!= user
)
451 /* terminal thunk is being restored */
453 WINPROC_FreeProc( *pFirst
, (*ppPrev
)->user
);
454 *(WINDOWPROC
**)pFirst
= *ppPrev
;
463 if (((*ppPrev
)->type
== type
) &&
464 (func
== WINPROC_THUNKPROC(*ppPrev
)))
466 if((*ppPrev
)->user
== user
)
472 WINPROC_FreeProc( *ppPrev
, user
);
479 /* WPF_CLASS thunk terminates window thunk list */
480 if ((*ppPrev
)->user
!= user
) break;
481 ppPrev
= &(*ppPrev
)->next
;
486 /* Extract this thunk from the list */
488 *ppPrev
= proc
->next
;
490 else /* Allocate a new one */
492 if (proc
) /* Was already a win proc */
495 func
= WINPROC_THUNKPROC(proc
);
497 proc
= WINPROC_AllocWinProc( func
, type
, user
);
498 if (!proc
) return FALSE
;
501 /* Add the win proc at the head of the list */
503 TRACE_(win
)("(%08x,%08x,%d): res=%08x\n",
504 (UINT
)*pFirst
, (UINT
)func
, type
, (UINT
)proc
);
505 proc
->next
= *(WINDOWPROC
**)pFirst
;
506 *(WINDOWPROC
**)pFirst
= proc
;
511 /**********************************************************************
514 * Free a list of win procs.
516 void WINPROC_FreeProc( HWINDOWPROC proc
, WINDOWPROCUSER user
)
520 WINDOWPROC
*next
= ((WINDOWPROC
*)proc
)->next
;
521 if (((WINDOWPROC
*)proc
)->user
!= user
) break;
522 TRACE_(win
)("freeing %08x\n", (UINT
)proc
);
523 HeapFree( WinProcHeap
, 0, proc
);
529 /**********************************************************************
530 * WINPROC_GetProcType
532 * Return the window procedure type.
534 WINDOWPROCTYPE
WINPROC_GetProcType( HWINDOWPROC proc
)
537 (((WINDOWPROC
*)proc
)->magic
!= WINPROC_MAGIC
))
538 return WIN_PROC_INVALID
;
539 return ((WINDOWPROC
*)proc
)->type
;
541 /**********************************************************************
542 * WINPROC_TestCBForStr
544 * Return TRUE if the lparam is a string
546 inline static BOOL
WINPROC_TestCBForStr( HWND hwnd
)
548 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
549 return (!(style
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) || (style
& CBS_HASSTRINGS
));
551 /**********************************************************************
552 * WINPROC_TestLBForStr
554 * Return TRUE if the lparam is a string
556 inline static BOOL
WINPROC_TestLBForStr( HWND hwnd
)
558 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
559 return (!(style
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) || (style
& LBS_HASSTRINGS
));
562 /**********************************************************************
563 * WINPROC_MapMsg32ATo32W
565 * Map a message from Ansi to Unicode.
566 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
569 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
570 * the first four bytes are the handle of the icon
571 * when the WM_SETTEXT message has been used to set the icon
573 INT
WINPROC_MapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
578 case WM_ASKCBFORMATNAME
:
580 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
581 *pwparam
* sizeof(WCHAR
) + sizeof(LPARAM
) );
583 *ptr
++ = *plparam
; /* Store previous lParam */
584 *plparam
= (LPARAM
)ptr
;
587 /* lparam is string (0-terminated) */
589 case WM_WININICHANGE
:
590 case WM_DEVMODECHANGE
:
595 if(!*plparam
) return 0;
596 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
597 return (*plparam
? 1 : -1);
598 case WM_GETTEXTLENGTH
:
599 case CB_GETLBTEXTLEN
:
601 return 1; /* need to map result */
606 { CREATESTRUCTW cs
; /* new structure */
607 LPCWSTR lpszName
; /* allocated Name */
608 LPCWSTR lpszClass
; /* allocated Class */
611 struct s
*xs
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct s
));
613 xs
->cs
= *(CREATESTRUCTW
*)*plparam
;
614 if (HIWORD(xs
->cs
.lpszName
))
615 xs
->lpszName
= xs
->cs
.lpszName
= HEAP_strdupAtoW( GetProcessHeap(), 0,
616 (LPCSTR
)xs
->cs
.lpszName
);
617 if (HIWORD(xs
->cs
.lpszClass
))
618 xs
->lpszClass
= xs
->cs
.lpszClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
619 (LPCSTR
)xs
->cs
.lpszClass
);
620 *plparam
= (LPARAM
)xs
;
625 MDICREATESTRUCTW
*cs
=
626 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
628 *cs
= *(MDICREATESTRUCTW
*)*plparam
;
629 if (HIWORD(cs
->szClass
))
630 cs
->szClass
= HEAP_strdupAtoW( GetProcessHeap(), 0,
631 (LPCSTR
)cs
->szClass
);
632 if (HIWORD(cs
->szTitle
))
633 cs
->szTitle
= HEAP_strdupAtoW( GetProcessHeap(), 0,
634 (LPCSTR
)cs
->szTitle
);
635 *plparam
= (LPARAM
)cs
;
641 case LB_INSERTSTRING
:
643 case LB_FINDSTRINGEXACT
:
644 case LB_SELECTSTRING
:
645 if(!*plparam
) return 0;
646 if ( WINPROC_TestLBForStr( hwnd
))
647 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
648 return (*plparam
? 1 : -1);
650 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
651 { if ( WINPROC_TestLBForStr( hwnd
))
652 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
654 *ptr
++ = *plparam
; /* Store previous lParam */
655 *plparam
= (LPARAM
)ptr
;
662 case CB_INSERTSTRING
:
663 case CB_FINDSTRINGEXACT
:
665 case CB_SELECTSTRING
:
666 if(!*plparam
) return 0;
667 if ( WINPROC_TestCBForStr( hwnd
))
668 *plparam
= (LPARAM
)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR
)*plparam
);
669 return (*plparam
? 1 : -1);
671 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
672 { if ( WINPROC_TestCBForStr( hwnd
))
673 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR
) + sizeof(LPARAM
) );
675 *ptr
++ = *plparam
; /* Store previous lParam */
676 *plparam
= (LPARAM
)ptr
;
683 { WORD len
= (WORD
)*plparam
;
684 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(WCHAR
) );
686 *ptr
++ = *plparam
; /* Store previous lParam */
687 *((WORD
*) ptr
) = len
; /* Store the length */
688 *plparam
= (LPARAM
)ptr
;
698 case EM_SETPASSWORDCHAR
:
700 BYTE ch
= LOWORD(*pwparam
);
702 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wch
, 1);
703 *pwparam
= MAKEWPARAM( wch
, HIWORD(*pwparam
) );
707 case WM_PAINTCLIPBOARD
:
708 case WM_SIZECLIPBOARD
:
709 FIXME_(msg
)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg
, hwnd
), msg
);
711 default: /* No translation needed */
717 /**********************************************************************
718 * WINPROC_UnmapMsg32ATo32W
720 * Unmap a message that was mapped from Ansi to Unicode.
722 LRESULT
WINPROC_UnmapMsg32ATo32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
728 case WM_ASKCBFORMATNAME
:
730 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
731 if (wParam
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
732 (LPSTR
)*ptr
, wParam
, NULL
, NULL
))
733 ((LPSTR
)*ptr
)[wParam
-1] = 0;
734 HeapFree( GetProcessHeap(), 0, ptr
);
737 case WM_GETTEXTLENGTH
:
738 case CB_GETLBTEXTLEN
:
740 /* there may be one DBCS char for each Unicode char */
746 { CREATESTRUCTW cs
; /* new structure */
747 LPWSTR lpszName
; /* allocated Name */
748 LPWSTR lpszClass
; /* allocated Class */
750 struct s
*xs
= (struct s
*)lParam
;
751 if (xs
->lpszName
) HeapFree( GetProcessHeap(), 0, xs
->lpszName
);
752 if (xs
->lpszClass
) HeapFree( GetProcessHeap(), 0, xs
->lpszClass
);
753 HeapFree( GetProcessHeap(), 0, xs
);
759 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
760 if (HIWORD(cs
->szTitle
))
761 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
762 if (HIWORD(cs
->szClass
))
763 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
764 HeapFree( GetProcessHeap(), 0, cs
);
769 case WM_WININICHANGE
:
770 case WM_DEVMODECHANGE
:
775 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
780 case LB_INSERTSTRING
:
782 case LB_FINDSTRINGEXACT
:
783 case LB_SELECTSTRING
:
784 if ( WINPROC_TestLBForStr( hwnd
))
785 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
789 { if ( WINPROC_TestLBForStr( hwnd
))
790 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
791 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
792 HeapFree( GetProcessHeap(), 0, ptr
);
799 case CB_INSERTSTRING
:
801 case CB_FINDSTRINGEXACT
:
802 case CB_SELECTSTRING
:
803 if ( WINPROC_TestCBForStr( hwnd
))
804 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
808 { if ( WINPROC_TestCBForStr( hwnd
))
809 { LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
810 WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1, (LPSTR
)*ptr
, 0x7fffffff, NULL
, NULL
);
811 HeapFree( GetProcessHeap(), 0, ptr
);
818 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lParam */
819 WORD len
= *(WORD
*) lParam
;
820 if (len
> 0 && !WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)lParam
, -1,
821 (LPSTR
)*ptr
, len
, NULL
, NULL
))
822 ((LPSTR
)*ptr
)[len
-1] = 0;
823 HeapFree( GetProcessHeap(), 0, ptr
);
831 /**********************************************************************
832 * WINPROC_MapMsg32WTo32A
834 * Map a message from Unicode to Ansi.
835 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
837 INT
WINPROC_MapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM
*pwparam
, LPARAM
*plparam
)
842 case WM_ASKCBFORMATNAME
:
844 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0,
845 *pwparam
+ sizeof(LPARAM
) );
847 *ptr
++ = *plparam
; /* Store previous lParam */
848 *plparam
= (LPARAM
)ptr
;
853 case WM_WININICHANGE
:
854 case WM_DEVMODECHANGE
:
859 if(!*plparam
) return 0;
860 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
861 return (*plparam
? 1 : -1);
866 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
869 *cs
= *(CREATESTRUCTA
*)*plparam
;
870 if (HIWORD(cs
->lpszName
))
871 cs
->lpszName
= HEAP_strdupWtoA( GetProcessHeap(), 0,
872 (LPCWSTR
)cs
->lpszName
);
873 if (HIWORD(cs
->lpszClass
))
874 cs
->lpszClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
875 (LPCWSTR
)cs
->lpszClass
);
876 *plparam
= (LPARAM
)cs
;
881 MDICREATESTRUCTA
*cs
=
882 (MDICREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) );
884 *cs
= *(MDICREATESTRUCTA
*)*plparam
;
885 if (HIWORD(cs
->szTitle
))
886 cs
->szTitle
= HEAP_strdupWtoA( GetProcessHeap(), 0,
887 (LPCWSTR
)cs
->szTitle
);
888 if (HIWORD(cs
->szClass
))
889 cs
->szClass
= HEAP_strdupWtoA( GetProcessHeap(), 0,
890 (LPCWSTR
)cs
->szClass
);
891 *plparam
= (LPARAM
)cs
;
897 case LB_INSERTSTRING
:
899 case LB_FINDSTRINGEXACT
:
900 case LB_SELECTSTRING
:
901 if(!*plparam
) return 0;
902 if ( WINPROC_TestLBForStr( hwnd
))
903 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
904 return (*plparam
? 1 : -1);
906 case LB_GETTEXT
: /* FIXME: fixed sized buffer */
907 { if ( WINPROC_TestLBForStr( hwnd
))
908 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
910 *ptr
++ = *plparam
; /* Store previous lParam */
911 *plparam
= (LPARAM
)ptr
;
918 case CB_INSERTSTRING
:
920 case CB_FINDSTRINGEXACT
:
921 case CB_SELECTSTRING
:
922 if(!*plparam
) return 0;
923 if ( WINPROC_TestCBForStr( hwnd
))
924 *plparam
= (LPARAM
)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)*plparam
);
925 return (*plparam
? 1 : -1);
927 case CB_GETLBTEXT
: /* FIXME: fixed sized buffer */
928 { if ( WINPROC_TestCBForStr( hwnd
))
929 { LPARAM
*ptr
= (LPARAM
*)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM
) );
931 *ptr
++ = *plparam
; /* Store previous lParam */
932 *plparam
= (LPARAM
)ptr
;
939 { WORD len
= (WORD
)*plparam
;
940 LPARAM
*ptr
= (LPARAM
*) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM
) + sizeof (WORD
) + len
*sizeof(CHAR
) );
942 *ptr
++ = *plparam
; /* Store previous lParam */
943 *((WORD
*) ptr
) = len
; /* Store the length */
944 *plparam
= (LPARAM
)ptr
;
954 case EM_SETPASSWORDCHAR
:
956 WCHAR wch
= LOWORD(*pwparam
);
958 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
959 *pwparam
= MAKEWPARAM( ch
, HIWORD(*pwparam
) );
963 case WM_PAINTCLIPBOARD
:
964 case WM_SIZECLIPBOARD
:
965 FIXME_(msg
)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg
, hwnd
),msg
);
967 default: /* No translation needed */
973 /**********************************************************************
974 * WINPROC_UnmapMsg32WTo32A
976 * Unmap a message that was mapped from Unicode to Ansi.
978 void WINPROC_UnmapMsg32WTo32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
983 case WM_ASKCBFORMATNAME
:
985 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
988 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, wParam
))
989 ((LPWSTR
)*ptr
)[wParam
-1] = 0;
991 HeapFree( GetProcessHeap(), 0, ptr
);
996 case WM_WININICHANGE
:
997 case WM_DEVMODECHANGE
:
1002 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1008 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1009 if (HIWORD(cs
->lpszName
))
1010 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszName
);
1011 if (HIWORD(cs
->lpszClass
))
1012 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->lpszClass
);
1013 HeapFree( GetProcessHeap(), 0, cs
);
1019 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1020 if (HIWORD(cs
->szTitle
))
1021 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szTitle
);
1022 if (HIWORD(cs
->szClass
))
1023 HeapFree( GetProcessHeap(), 0, (LPVOID
)cs
->szClass
);
1024 HeapFree( GetProcessHeap(), 0, cs
);
1030 case LB_INSERTSTRING
:
1032 case LB_FINDSTRINGEXACT
:
1033 case LB_SELECTSTRING
:
1034 if ( WINPROC_TestLBForStr( hwnd
))
1035 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1039 if ( WINPROC_TestLBForStr( hwnd
))
1041 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1042 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1043 HeapFree( GetProcessHeap(), 0, ptr
);
1049 case CB_INSERTSTRING
:
1051 case CB_FINDSTRINGEXACT
:
1052 case CB_SELECTSTRING
:
1053 if ( WINPROC_TestCBForStr( hwnd
))
1054 HeapFree( GetProcessHeap(), 0, (void *)lParam
);
1058 if ( WINPROC_TestCBForStr( hwnd
))
1060 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
1061 MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, 0x7fffffff );
1062 HeapFree( GetProcessHeap(), 0, ptr
);
1066 /* Multiline edit */
1068 { LPARAM
* ptr
= (LPARAM
*)lParam
- 1; /* get the old lparam */
1069 WORD len
= *(WORD
*)ptr
;
1072 if (!MultiByteToWideChar( CP_ACP
, 0, (LPSTR
)lParam
, -1, (LPWSTR
)*ptr
, len
))
1073 ((LPWSTR
)*ptr
)[len
-1] = 0;
1075 HeapFree( GetProcessHeap(), 0, ptr
);
1082 /**********************************************************************
1083 * WINPROC_MapMsg16To32A
1085 * Map a message from 16- to 32-bit Ansi.
1086 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1088 INT
WINPROC_MapMsg16To32A( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1089 WPARAM
*pwparam32
, LPARAM
*plparam
)
1091 *pmsg32
= (UINT
)msg16
;
1092 *pwparam32
= (WPARAM
)wParam16
;
1099 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1100 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1104 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1105 *plparam
= (LPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1108 if ( HIWORD(*plparam
) > CTLCOLOR_STATIC
) return -1;
1109 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
1110 *pwparam32
= (WPARAM
)(HDC
)wParam16
;
1111 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1113 case WM_COMPAREITEM
:
1115 COMPAREITEMSTRUCT16
* cis16
= MapSL(*plparam
);
1116 COMPAREITEMSTRUCT
*cis
= (COMPAREITEMSTRUCT
*)
1117 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis
));
1118 if (!cis
) return -1;
1119 cis
->CtlType
= cis16
->CtlType
;
1120 cis
->CtlID
= cis16
->CtlID
;
1121 cis
->hwndItem
= WIN_Handle32( cis16
->hwndItem
);
1122 cis
->itemID1
= cis16
->itemID1
;
1123 cis
->itemData1
= cis16
->itemData1
;
1124 cis
->itemID2
= cis16
->itemID2
;
1125 cis
->itemData2
= cis16
->itemData2
;
1126 cis
->dwLocaleId
= 0; /* FIXME */
1127 *plparam
= (LPARAM
)cis
;
1132 DELETEITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1133 DELETEITEMSTRUCT
*dis
= (DELETEITEMSTRUCT
*)
1134 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis
));
1135 if (!dis
) return -1;
1136 dis
->CtlType
= dis16
->CtlType
;
1137 dis
->CtlID
= dis16
->CtlID
;
1138 dis
->hwndItem
= WIN_Handle32( dis16
->hwndItem
);
1139 dis
->itemData
= dis16
->itemData
;
1140 *plparam
= (LPARAM
)dis
;
1143 case WM_MEASUREITEM
:
1145 MEASUREITEMSTRUCT16
* mis16
= MapSL(*plparam
);
1146 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)
1147 HeapAlloc(GetProcessHeap(), 0,
1148 sizeof(*mis
) + sizeof(LPARAM
));
1149 if (!mis
) return -1;
1150 mis
->CtlType
= mis16
->CtlType
;
1151 mis
->CtlID
= mis16
->CtlID
;
1152 mis
->itemID
= mis16
->itemID
;
1153 mis
->itemWidth
= mis16
->itemWidth
;
1154 mis
->itemHeight
= mis16
->itemHeight
;
1155 mis
->itemData
= mis16
->itemData
;
1156 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1157 *plparam
= (LPARAM
)mis
;
1162 DRAWITEMSTRUCT16
* dis16
= MapSL(*plparam
);
1163 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)HeapAlloc(GetProcessHeap(), 0,
1165 if (!dis
) return -1;
1166 dis
->CtlType
= dis16
->CtlType
;
1167 dis
->CtlID
= dis16
->CtlID
;
1168 dis
->itemID
= dis16
->itemID
;
1169 dis
->itemAction
= dis16
->itemAction
;
1170 dis
->itemState
= dis16
->itemState
;
1171 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND
)(HMENU
)dis16
->hwndItem
1172 : WIN_Handle32( dis16
->hwndItem
);
1173 dis
->hDC
= dis16
->hDC
;
1174 dis
->itemData
= dis16
->itemData
;
1175 CONV_RECT16TO32( &dis16
->rcItem
, &dis
->rcItem
);
1176 *plparam
= (LPARAM
)dis
;
1179 case WM_GETMINMAXINFO
:
1181 MINMAXINFO
*mmi
= (MINMAXINFO
*)HeapAlloc( GetProcessHeap(), 0,
1182 sizeof(*mmi
) + sizeof(LPARAM
));
1183 if (!mmi
) return -1;
1184 STRUCT32_MINMAXINFO16to32( MapSL(*plparam
), mmi
);
1185 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1186 *plparam
= (LPARAM
)mmi
;
1191 case WM_WININICHANGE
:
1192 case WM_DEVMODECHANGE
:
1193 case WM_ASKCBFORMATNAME
:
1194 *plparam
= (LPARAM
)MapSL(*plparam
);
1198 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1199 MDICREATESTRUCTA
*cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(*cs
) + sizeof(LPARAM
) );
1201 STRUCT32_MDICREATESTRUCT16to32A( cs16
, cs
);
1202 cs
->szTitle
= MapSL(cs16
->szTitle
);
1203 cs
->szClass
= MapSL(cs16
->szClass
);
1204 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1205 *plparam
= (LPARAM
)cs
;
1208 case WM_MDIGETACTIVE
:
1209 *plparam
= (LPARAM
)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL
) );
1210 *(BOOL
*)(*plparam
) = 0;
1214 *pmsg32
=WM_MDIREFRESHMENU
;
1215 *pwparam32
= (WPARAM
)(HMENU
)LOWORD(*plparam
);
1216 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1219 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1220 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1223 if((LOWORD(*plparam
) & MF_POPUP
) && (LOWORD(*plparam
) != 0xFFFF))
1225 HMENU hmenu
=(HMENU
)HIWORD(*plparam
);
1226 UINT Pos
=MENU_FindSubMenu( &hmenu
, wParam16
);
1227 if(Pos
==0xFFFF) Pos
=0; /* NO_SELECTED_ITEM */
1228 *pwparam32
= MAKEWPARAM( Pos
, LOWORD(*plparam
) );
1230 else *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
1231 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1233 case WM_MDIACTIVATE
:
1236 *pwparam32
= (WPARAM
)WIN_Handle32( HIWORD(*plparam
) );
1237 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1239 else /* message sent to MDI client */
1240 *pwparam32
= wParam16
;
1244 NCCALCSIZE_PARAMS16
*nc16
;
1245 NCCALCSIZE_PARAMS
*nc
;
1247 nc
= (NCCALCSIZE_PARAMS
*)HeapAlloc( GetProcessHeap(), 0,
1248 sizeof(*nc
) + sizeof(LPARAM
) );
1250 nc16
= MapSL(*plparam
);
1251 CONV_RECT16TO32( &nc16
->rgrc
[0], &nc
->rgrc
[0] );
1254 nc
->lppos
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1255 sizeof(*nc
->lppos
) );
1256 CONV_RECT16TO32( &nc16
->rgrc
[1], &nc
->rgrc
[1] );
1257 CONV_RECT16TO32( &nc16
->rgrc
[2], &nc
->rgrc
[2] );
1258 if (nc
->lppos
) STRUCT32_WINDOWPOS16to32( MapSL(nc16
->lppos
), nc
->lppos
);
1260 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1261 *plparam
= (LPARAM
)nc
;
1267 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1268 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)HeapAlloc( GetProcessHeap(), 0,
1269 sizeof(*cs
) + sizeof(LPARAM
) );
1271 STRUCT32_CREATESTRUCT16to32A( cs16
, cs
);
1272 cs
->lpszName
= MapSL(cs16
->lpszName
);
1273 cs
->lpszClass
= MapSL(cs16
->lpszClass
);
1274 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1275 *plparam
= (LPARAM
)cs
;
1278 case WM_PARENTNOTIFY
:
1279 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
1281 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
1282 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1285 case WM_WINDOWPOSCHANGING
:
1286 case WM_WINDOWPOSCHANGED
:
1288 WINDOWPOS
*wp
= (WINDOWPOS
*)HeapAlloc( GetProcessHeap(), 0,
1289 sizeof(*wp
) + sizeof(LPARAM
) );
1291 STRUCT32_WINDOWPOS16to32( MapSL(*plparam
), wp
);
1292 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1293 *plparam
= (LPARAM
)wp
;
1299 LPMSG16 msg16
= MapSL(*plparam
);
1300 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1302 if (!msg32
) return -1;
1303 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1304 msg32
->lParam
= msg16
->lParam
;
1305 msg32
->time
= msg16
->time
;
1306 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1307 /* this is right, right? */
1308 if (WINPROC_MapMsg16To32A( msg32
->hwnd
, msg16
->message
,msg16
->wParam
,
1309 &msg32
->message
,&msg32
->wParam
,
1310 &msg32
->lParam
)<0) {
1311 HeapFree( GetProcessHeap(), 0, msg32
);
1314 *plparam
= (LPARAM
)msg32
;
1319 *plparam
= (LPARAM
)MapSL(*plparam
);
1321 case WM_ACTIVATEAPP
:
1323 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1324 a 32bit window. Might be superflous with 32bit interprocess
1327 HTASK16 htask
= (HTASK16
) *plparam
;
1328 DWORD idThread
= (DWORD
)TASK_GetPtr(htask
)->teb
->tid
;
1329 *plparam
= (LPARAM
) idThread
;
1334 MDINEXTMENU
*next
= HeapAlloc( GetProcessHeap(), 0, sizeof(*next
) );
1335 if (!next
) return -1;
1336 next
->hmenuIn
= *plparam
;
1337 next
->hmenuNext
= 0;
1339 *plparam
= (LPARAM
)next
;
1342 case WM_PAINTCLIPBOARD
:
1343 case WM_SIZECLIPBOARD
:
1344 FIXME_(msg
)("message %04x needs translation\n",msg16
);
1347 default: /* No translation needed */
1353 /**********************************************************************
1354 * WINPROC_UnmapMsg16To32A
1356 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1358 LRESULT
WINPROC_UnmapMsg16To32A( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1363 case WM_COMPAREITEM
:
1366 HeapFree( GetProcessHeap(), 0, (LPVOID
)lParam
);
1368 case WM_MEASUREITEM
:
1370 MEASUREITEMSTRUCT16
*mis16
;
1371 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*)lParam
;
1372 lParam
= *(LPARAM
*)(mis
+ 1);
1373 mis16
= MapSL(lParam
);
1374 mis16
->itemWidth
= (UINT16
)mis
->itemWidth
;
1375 mis16
->itemHeight
= (UINT16
)mis
->itemHeight
;
1376 HeapFree( GetProcessHeap(), 0, mis
);
1379 case WM_GETMINMAXINFO
:
1381 MINMAXINFO
*mmi
= (MINMAXINFO
*)lParam
;
1382 lParam
= *(LPARAM
*)(mmi
+ 1);
1383 STRUCT32_MINMAXINFO32to16( mmi
, MapSL(lParam
));
1384 HeapFree( GetProcessHeap(), 0, mmi
);
1389 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)lParam
;
1390 lParam
= *(LPARAM
*)(cs
+ 1);
1391 STRUCT32_MDICREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1392 HeapFree( GetProcessHeap(), 0, cs
);
1395 case WM_MDIGETACTIVE
:
1396 result
= MAKELONG( LOWORD(result
), (BOOL16
)(*(BOOL
*)lParam
) );
1397 HeapFree( GetProcessHeap(), 0, (BOOL
*)lParam
);
1401 NCCALCSIZE_PARAMS16
*nc16
;
1402 NCCALCSIZE_PARAMS
*nc
= (NCCALCSIZE_PARAMS
*)lParam
;
1403 lParam
= *(LPARAM
*)(nc
+ 1);
1404 nc16
= MapSL(lParam
);
1405 CONV_RECT32TO16( &nc
->rgrc
[0], &nc16
->rgrc
[0] );
1408 CONV_RECT32TO16( &nc
->rgrc
[1], &nc16
->rgrc
[1] );
1409 CONV_RECT32TO16( &nc
->rgrc
[2], &nc16
->rgrc
[2] );
1412 STRUCT32_WINDOWPOS32to16( nc
->lppos
, MapSL(nc16
->lppos
));
1413 HeapFree( GetProcessHeap(), 0, nc
->lppos
);
1416 HeapFree( GetProcessHeap(), 0, nc
);
1422 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lParam
;
1423 lParam
= *(LPARAM
*)(cs
+ 1);
1424 STRUCT32_CREATESTRUCT32Ato16( cs
, MapSL(lParam
) );
1425 HeapFree( GetProcessHeap(), 0, cs
);
1428 case WM_WINDOWPOSCHANGING
:
1429 case WM_WINDOWPOSCHANGED
:
1431 WINDOWPOS
*wp
= (WINDOWPOS
*)lParam
;
1432 lParam
= *(LPARAM
*)(wp
+ 1);
1433 STRUCT32_WINDOWPOS32to16(wp
, MapSL(lParam
));
1434 HeapFree( GetProcessHeap(), 0, wp
);
1440 LPMSG msg32
= (LPMSG
)lParam
;
1442 WINPROC_UnmapMsg16To32A( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1444 HeapFree( GetProcessHeap(), 0, msg32
);
1449 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
1450 result
= MAKELONG( next
->hmenuNext
, WIN_Handle16(next
->hwndNext
) );
1451 HeapFree( GetProcessHeap(), 0, next
);
1459 /**********************************************************************
1460 * WINPROC_MapMsg16To32W
1462 * Map a message from 16- to 32-bit Unicode.
1463 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1465 INT
WINPROC_MapMsg16To32W( HWND hwnd
, UINT16 msg16
, WPARAM16 wParam16
, UINT
*pmsg32
,
1466 WPARAM
*pwparam32
, LPARAM
*plparam
)
1471 *pmsg32
=(UINT
)msg16
;
1472 *pwparam32
= (WPARAM
)wParam16
;
1477 case WM_WININICHANGE
:
1478 case WM_DEVMODECHANGE
:
1479 case WM_ASKCBFORMATNAME
:
1480 *plparam
= (LPARAM
)MapSL(*plparam
);
1481 return WINPROC_MapMsg32ATo32W( hwnd
, *pmsg32
, pwparam32
, plparam
);
1482 case WM_GETTEXTLENGTH
:
1483 case CB_GETLBTEXTLEN
:
1485 return 1; /* need to map result */
1489 CREATESTRUCT16
*cs16
= MapSL(*plparam
);
1490 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1491 sizeof(*cs
) + sizeof(LPARAM
) );
1493 STRUCT32_CREATESTRUCT16to32A( cs16
, (CREATESTRUCTA
*)cs
);
1494 cs
->lpszName
= map_str_16_to_32W(cs16
->lpszName
);
1495 cs
->lpszClass
= map_str_16_to_32W(cs16
->lpszClass
);
1496 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1497 *plparam
= (LPARAM
)cs
;
1502 MDICREATESTRUCT16
*cs16
= MapSL(*plparam
);
1503 MDICREATESTRUCTW
*cs
=
1504 (MDICREATESTRUCTW
*)HeapAlloc( GetProcessHeap(), 0,
1505 sizeof(*cs
) + sizeof(LPARAM
) );
1507 STRUCT32_MDICREATESTRUCT16to32A( cs16
, (MDICREATESTRUCTA
*)cs
);
1508 cs
->szTitle
= map_str_16_to_32W(cs16
->szTitle
);
1509 cs
->szClass
= map_str_16_to_32W(cs16
->szClass
);
1510 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
1511 *plparam
= (LPARAM
)cs
;
1517 LPMSG16 msg16
= MapSL(*plparam
);
1518 LPMSG msg32
= (LPMSG
)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG
) );
1520 if (!msg32
) return -1;
1521 msg32
->hwnd
= WIN_Handle32( msg16
->hwnd
);
1522 msg32
->lParam
= msg16
->lParam
;
1523 msg32
->time
= msg16
->time
;
1524 CONV_POINT16TO32(&msg16
->pt
,&msg32
->pt
);
1525 /* this is right, right? */
1526 if (WINPROC_MapMsg16To32W(hwnd
, msg16
->message
,msg16
->wParam
,
1527 &msg32
->message
,&msg32
->wParam
,
1528 &msg32
->lParam
)<0) {
1529 HeapFree( GetProcessHeap(), 0, msg32
);
1532 *plparam
= (LPARAM
)msg32
;
1539 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1540 *pwparam32
= MAKEWPARAM( wch
, HIWORD(*plparam
) );
1541 *plparam
= (LPARAM
)WIN_Handle32( LOWORD(*plparam
) );
1545 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1546 *pwparam32
= MAKEWPARAM( wch
, LOWORD(*plparam
) );
1547 *plparam
= (LPARAM
)(HMENU
)HIWORD(*plparam
);
1552 case WM_SYSDEADCHAR
:
1554 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &wch
, 1);
1558 default: /* No Unicode translation needed */
1559 return WINPROC_MapMsg16To32A( hwnd
, msg16
, wParam16
, pmsg32
,
1560 pwparam32
, plparam
);
1565 /**********************************************************************
1566 * WINPROC_UnmapMsg16To32W
1568 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1570 LRESULT
WINPROC_UnmapMsg16To32W( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
1577 case WM_GETTEXTLENGTH
:
1578 case CB_GETLBTEXTLEN
:
1580 case WM_ASKCBFORMATNAME
:
1581 return WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
1585 CREATESTRUCTW
*cs
= (CREATESTRUCTW
*)lParam
;
1586 lParam
= *(LPARAM
*)(cs
+ 1);
1587 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs
, MapSL(lParam
) );
1588 unmap_str_16_to_32W( cs
->lpszName
);
1589 unmap_str_16_to_32W( cs
->lpszClass
);
1590 HeapFree( GetProcessHeap(), 0, cs
);
1595 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)lParam
;
1596 lParam
= *(LPARAM
*)(cs
+ 1);
1597 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs
, MapSL(lParam
) );
1598 unmap_str_16_to_32W( cs
->szTitle
);
1599 unmap_str_16_to_32W( cs
->szClass
);
1600 HeapFree( GetProcessHeap(), 0, cs
);
1606 LPMSG msg32
= (LPMSG
)lParam
;
1608 WINPROC_UnmapMsg16To32W( hwnd
, msg32
->message
, msg32
->wParam
, msg32
->lParam
,
1610 HeapFree( GetProcessHeap(), 0, msg32
);
1614 return WINPROC_UnmapMsg16To32A( hwnd
, msg
, wParam
, lParam
, result
);
1620 /**********************************************************************
1621 * WINPROC_MapMsg32ATo16
1623 * Map a message from 32-bit Ansi to 16-bit.
1624 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1626 INT
WINPROC_MapMsg32ATo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
1627 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
1630 *pmsg16
= (UINT16
)msg32
;
1631 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1639 *pmsg16
= (UINT16
)msg32
+ (BM_GETCHECK16
- BM_GETCHECK
);
1648 case EM_SCROLLCARET
:
1651 case EM_GETLINECOUNT
:
1663 case EM_LINEFROMCHAR
:
1664 case EM_SETTABSTOPS
:
1665 case EM_SETPASSWORDCHAR
:
1666 case EM_EMPTYUNDOBUFFER
:
1667 case EM_GETFIRSTVISIBLELINE
:
1668 case EM_SETREADONLY
:
1669 case EM_SETWORDBREAKPROC
:
1670 case EM_GETWORDBREAKPROC
:
1671 case EM_GETPASSWORDCHAR
:
1672 *pmsg16
= (UINT16
)msg32
+ (EM_GETSEL16
- EM_GETSEL
);
1677 case LB_DELETESTRING
:
1678 case LB_GETANCHORINDEX
:
1679 case LB_GETCARETINDEX
:
1682 case LB_GETHORIZONTALEXTENT
:
1683 case LB_GETITEMDATA
:
1684 case LB_GETITEMHEIGHT
:
1686 case LB_GETSELCOUNT
:
1688 case LB_GETTOPINDEX
:
1689 case LB_RESETCONTENT
:
1690 case LB_SELITEMRANGE
:
1691 case LB_SELITEMRANGEEX
:
1692 case LB_SETANCHORINDEX
:
1693 case LB_SETCARETINDEX
:
1694 case LB_SETCOLUMNWIDTH
:
1696 case LB_SETHORIZONTALEXTENT
:
1697 case LB_SETITEMDATA
:
1698 case LB_SETITEMHEIGHT
:
1700 case LB_SETTOPINDEX
:
1701 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1703 case CB_DELETESTRING
:
1705 case CB_GETLBTEXTLEN
:
1707 case CB_RESETCONTENT
:
1711 case CB_SHOWDROPDOWN
:
1712 case CB_SETITEMDATA
:
1713 case CB_SETITEMHEIGHT
:
1714 case CB_GETITEMHEIGHT
:
1715 case CB_SETEXTENDEDUI
:
1716 case CB_GETEXTENDEDUI
:
1717 case CB_GETDROPPEDSTATE
:
1718 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1721 *pmsg16
= CB_GETEDITSEL16
;
1726 case LB_FINDSTRINGEXACT
:
1727 case LB_INSERTSTRING
:
1728 case LB_SELECTSTRING
:
1731 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1732 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
1737 case CB_FINDSTRINGEXACT
:
1738 case CB_INSERTSTRING
:
1739 case CB_SELECTSTRING
:
1741 *plparam
= (LPARAM
)MapLS( (LPSTR
)*plparam
);
1742 *pmsg16
= (UINT16
)msg32
+ (CB_GETEDITSEL16
- CB_GETEDITSEL
);
1745 case LB_GETITEMRECT
:
1747 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1748 if (!rect
) return -1;
1749 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1750 *plparam
= MapLS( rect
);
1752 *pmsg16
= LB_GETITEMRECT16
;
1754 case LB_GETSELITEMS
:
1757 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1758 if (!(items
= HeapAlloc( GetProcessHeap(), 0,
1759 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1760 *((LPARAM
*)items
)++ = *plparam
; /* Store the previous lParam */
1761 *plparam
= MapLS( items
);
1763 *pmsg16
= LB_GETSELITEMS16
;
1765 case LB_SETTABSTOPS
:
1770 *pwparam16
= (WPARAM16
)min( wParam32
, 0x7f80 ); /* Must be < 64K */
1771 if (!(stops
= HeapAlloc( GetProcessHeap(), 0,
1772 *pwparam16
* sizeof(INT16
) + sizeof(LPARAM
)))) return -1;
1773 for (i
= 0; i
< *pwparam16
; i
++) stops
[i
] = *((LPINT
)*plparam
+i
);
1774 *plparam
= MapLS( stops
);
1777 *pmsg16
= LB_SETTABSTOPS16
;
1780 case CB_GETDROPPEDCONTROLRECT
:
1782 RECT16
*rect
= HeapAlloc( GetProcessHeap(), 0, sizeof(RECT16
) + sizeof(LPARAM
) );
1783 if (!rect
) return -1;
1784 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1785 *plparam
= (LPARAM
)MapLS(rect
);
1787 *pmsg16
= CB_GETDROPPEDCONTROLRECT16
;
1791 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1792 *pmsg16
= LB_GETTEXT16
;
1796 *plparam
= (LPARAM
)MapLS( (LPVOID
)(*plparam
) );
1797 *pmsg16
= CB_GETLBTEXT16
;
1802 *plparam
= MAKELONG( (INT16
)(INT
)wParam32
, (INT16
)*plparam
);
1803 *pmsg16
= EM_SETSEL16
;
1810 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
1814 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
1816 case WM_CTLCOLORMSGBOX
:
1817 case WM_CTLCOLOREDIT
:
1818 case WM_CTLCOLORLISTBOX
:
1819 case WM_CTLCOLORBTN
:
1820 case WM_CTLCOLORDLG
:
1821 case WM_CTLCOLORSCROLLBAR
:
1822 case WM_CTLCOLORSTATIC
:
1823 *pmsg16
= WM_CTLCOLOR
;
1824 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
1825 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
1827 case WM_COMPAREITEM
:
1829 COMPAREITEMSTRUCT
*cis32
= (COMPAREITEMSTRUCT
*)*plparam
;
1830 COMPAREITEMSTRUCT16
*cis
= HeapAlloc( GetProcessHeap(), 0, sizeof(COMPAREITEMSTRUCT16
));
1831 if (!cis
) return -1;
1832 cis
->CtlType
= (UINT16
)cis32
->CtlType
;
1833 cis
->CtlID
= (UINT16
)cis32
->CtlID
;
1834 cis
->hwndItem
= WIN_Handle16( cis32
->hwndItem
);
1835 cis
->itemID1
= (UINT16
)cis32
->itemID1
;
1836 cis
->itemData1
= cis32
->itemData1
;
1837 cis
->itemID2
= (UINT16
)cis32
->itemID2
;
1838 cis
->itemData2
= cis32
->itemData2
;
1839 *plparam
= MapLS( cis
);
1844 DELETEITEMSTRUCT
*dis32
= (DELETEITEMSTRUCT
*)*plparam
;
1845 DELETEITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DELETEITEMSTRUCT16
) );
1846 if (!dis
) return -1;
1847 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1848 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1849 dis
->itemID
= (UINT16
)dis32
->itemID
;
1850 dis
->hwndItem
= (dis
->CtlType
== ODT_MENU
) ? (HWND16
)LOWORD(dis32
->hwndItem
)
1851 : WIN_Handle16( dis32
->hwndItem
);
1852 dis
->itemData
= dis32
->itemData
;
1853 *plparam
= MapLS( dis
);
1858 DRAWITEMSTRUCT
*dis32
= (DRAWITEMSTRUCT
*)*plparam
;
1859 DRAWITEMSTRUCT16
*dis
= HeapAlloc( GetProcessHeap(), 0, sizeof(DRAWITEMSTRUCT16
) );
1860 if (!dis
) return -1;
1861 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1862 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1863 dis
->itemID
= (UINT16
)dis32
->itemID
;
1864 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
1865 dis
->itemState
= (UINT16
)dis32
->itemState
;
1866 dis
->hwndItem
= WIN_Handle16( dis32
->hwndItem
);
1867 dis
->hDC
= (HDC16
)dis32
->hDC
;
1868 dis
->itemData
= dis32
->itemData
;
1869 CONV_RECT32TO16( &dis32
->rcItem
, &dis
->rcItem
);
1870 *plparam
= MapLS( dis
);
1873 case WM_MEASUREITEM
:
1875 MEASUREITEMSTRUCT
*mis32
= (MEASUREITEMSTRUCT
*)*plparam
;
1876 MEASUREITEMSTRUCT16
*mis
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mis
)+sizeof(LPARAM
));
1877 if (!mis
) return -1;
1878 mis
->CtlType
= (UINT16
)mis32
->CtlType
;
1879 mis
->CtlID
= (UINT16
)mis32
->CtlID
;
1880 mis
->itemID
= (UINT16
)mis32
->itemID
;
1881 mis
->itemWidth
= (UINT16
)mis32
->itemWidth
;
1882 mis
->itemHeight
= (UINT16
)mis32
->itemHeight
;
1883 mis
->itemData
= mis32
->itemData
;
1884 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1885 *plparam
= MapLS( mis
);
1888 case WM_GETMINMAXINFO
:
1890 MINMAXINFO16
*mmi
= HeapAlloc( GetProcessHeap(), 0, sizeof(*mmi
) + sizeof(LPARAM
) );
1891 if (!mmi
) return -1;
1892 STRUCT32_MINMAXINFO32to16( (MINMAXINFO
*)*plparam
, mmi
);
1893 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1894 *plparam
= MapLS( mmi
);
1898 case WM_ASKCBFORMATNAME
:
1901 *pwparam16
= (WPARAM16
)min( wParam32
, 0xff80 ); /* Must be < 64K */
1902 if (!(str
= HeapAlloc( GetProcessHeap(), 0, *pwparam16
+ sizeof(LPARAM
)))) return -1;
1903 *((LPARAM
*)str
)++ = *plparam
; /* Store the previous lParam */
1904 *plparam
= MapLS( str
);
1909 MDICREATESTRUCT16
*cs
;
1910 MDICREATESTRUCTA
*cs32
= (MDICREATESTRUCTA
*)*plparam
;
1912 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
1913 STRUCT32_MDICREATESTRUCT32Ato16( cs32
, cs
);
1914 cs
->szTitle
= MapLS( cs32
->szTitle
);
1915 cs
->szClass
= MapLS( cs32
->szClass
);
1916 *plparam
= MapLS( cs
);
1919 case WM_MDIGETACTIVE
:
1922 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
1923 (HMENU16
)LOWORD(*plparam
) );
1924 *pwparam16
= (*plparam
== 0);
1927 if(HIWORD(wParam32
) & MF_POPUP
)
1930 if (((UINT
)HIWORD(wParam32
) != 0xFFFF) || (*plparam
))
1932 if((hmenu
= GetSubMenu((HMENU16
)*plparam
, *pwparam16
)))
1938 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
1940 case WM_MDIACTIVATE
:
1941 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
1943 *pwparam16
= ((HWND
)*plparam
== hwnd
);
1944 *plparam
= MAKELPARAM( (HWND16
)LOWORD(*plparam
),
1945 (HWND16
)LOWORD(wParam32
) );
1949 *pwparam16
= WIN_Handle16( (HWND
)wParam32
);
1955 NCCALCSIZE_PARAMS
*nc32
= (NCCALCSIZE_PARAMS
*)*plparam
;
1956 NCCALCSIZE_PARAMS16
*nc
= HeapAlloc( GetProcessHeap(), 0, sizeof(*nc
) + sizeof(LPARAM
));
1959 CONV_RECT32TO16( &nc32
->rgrc
[0], &nc
->rgrc
[0] );
1963 CONV_RECT32TO16( &nc32
->rgrc
[1], &nc
->rgrc
[1] );
1964 CONV_RECT32TO16( &nc32
->rgrc
[2], &nc
->rgrc
[2] );
1965 if (!(wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(WINDOWPOS16
) )))
1967 HeapFree( GetProcessHeap(), 0, nc
);
1970 STRUCT32_WINDOWPOS32to16( nc32
->lppos
, wp
);
1971 nc
->lppos
= MapLS( wp
);
1973 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1974 *plparam
= MapLS( nc
);
1981 CREATESTRUCTA
*cs32
= (CREATESTRUCTA
*)*plparam
;
1983 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
1984 STRUCT32_CREATESTRUCT32Ato16( cs32
, cs
);
1985 cs
->lpszName
= MapLS( cs32
->lpszName
);
1986 cs
->lpszClass
= MapLS( cs32
->lpszClass
);
1987 *plparam
= MapLS( cs
);
1990 case WM_PARENTNOTIFY
:
1991 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
1992 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
1993 /* else nothing to do */
1996 *plparam
= MapLS( (NMHDR
*)*plparam
); /* NMHDR is already 32-bit */
1999 case WM_WININICHANGE
:
2000 case WM_DEVMODECHANGE
:
2001 *plparam
= MapLS( (LPSTR
)*plparam
);
2003 case WM_WINDOWPOSCHANGING
:
2004 case WM_WINDOWPOSCHANGED
:
2006 WINDOWPOS16
*wp
= HeapAlloc( GetProcessHeap(), 0, sizeof(*wp
) + sizeof(LPARAM
) );
2008 STRUCT32_WINDOWPOS32to16( (WINDOWPOS
*)*plparam
, wp
);
2009 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
2010 *plparam
= MapLS( wp
);
2015 LPMSG msg32
= (LPMSG
) *plparam
;
2016 LPMSG16 msg16
= HeapAlloc( GetProcessHeap(), 0, sizeof(MSG16
) );
2018 if (!msg16
) return -1;
2019 msg16
->hwnd
= WIN_Handle16( msg32
->hwnd
);
2020 msg16
->lParam
= msg32
->lParam
;
2021 msg16
->time
= msg32
->time
;
2022 CONV_POINT32TO16(&msg32
->pt
,&msg16
->pt
);
2023 /* this is right, right? */
2024 if (WINPROC_MapMsg32ATo16(msg32
->hwnd
,msg32
->message
,msg32
->wParam
,
2025 &msg16
->message
,&msg16
->wParam
, &msg16
->lParam
)<0)
2027 HeapFree( GetProcessHeap(), 0, msg16
);
2030 *plparam
= MapLS( msg16
);
2035 case WM_ACTIVATEAPP
:
2036 if (*plparam
) *plparam
= (LPARAM
)THREAD_IdToTEB((DWORD
) *plparam
)->htask16
;
2040 MDINEXTMENU
*next
= (MDINEXTMENU
*)*plparam
;
2041 *plparam
= next
->hmenuIn
;
2044 case WM_PAINTCLIPBOARD
:
2045 case WM_SIZECLIPBOARD
:
2046 FIXME_(msg
)("message %04x needs translation\n", msg32
);
2048 /* following messages should not be sent to 16-bit apps */
2051 case WM_CAPTURECHANGED
:
2052 case WM_STYLECHANGING
:
2053 case WM_STYLECHANGED
:
2055 default: /* No translation needed */
2061 /**********************************************************************
2062 * WINPROC_UnmapMsg32ATo16
2064 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2066 void WINPROC_UnmapMsg32ATo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2075 case LB_FINDSTRINGEXACT
:
2076 case LB_INSERTSTRING
:
2077 case LB_SELECTSTRING
:
2081 case CB_FINDSTRINGEXACT
:
2082 case CB_INSERTSTRING
:
2083 case CB_SELECTSTRING
:
2087 case WM_WININICHANGE
:
2088 case WM_DEVMODECHANGE
:
2089 UnMapLS( (SEGPTR
)p16
->lParam
);
2091 case LB_SETTABSTOPS
:
2092 case WM_COMPAREITEM
:
2096 void *ptr
= MapSL( p16
->lParam
);
2097 UnMapLS( p16
->lParam
);
2098 HeapFree( GetProcessHeap(), 0, ptr
);
2101 case CB_GETDROPPEDCONTROLRECT
:
2102 case LB_GETITEMRECT
:
2104 RECT16
*rect
= MapSL(p16
->lParam
);
2105 UnMapLS( p16
->lParam
);
2106 p16
->lParam
= *(LPARAM
*)(rect
+ 1);
2107 CONV_RECT16TO32( rect
, (RECT
*)(p16
->lParam
));
2108 HeapFree( GetProcessHeap(), 0, rect
);
2111 case LB_GETSELITEMS
:
2114 LPINT16 items
= MapSL(p16
->lParam
);
2115 UnMapLS( p16
->lParam
);
2116 p16
->lParam
= *((LPARAM
*)items
- 1);
2117 for (i
= 0; i
< p16
->wParam
; i
++) *((LPINT
)(p16
->lParam
) + i
) = items
[i
];
2118 HeapFree( GetProcessHeap(), 0, (LPARAM
*)items
- 1 );
2124 *((LPUINT
)(wParam
)) = LOWORD(p16
->lResult
);
2126 *((LPUINT
)(lParam
)) = HIWORD(p16
->lResult
); /* FIXME: substract 1? */
2129 case WM_MEASUREITEM
:
2131 MEASUREITEMSTRUCT16
*mis
= MapSL(p16
->lParam
);
2132 MEASUREITEMSTRUCT
*mis32
= *(MEASUREITEMSTRUCT
**)(mis
+ 1);
2133 mis32
->itemWidth
= mis
->itemWidth
;
2134 mis32
->itemHeight
= mis
->itemHeight
;
2135 UnMapLS( p16
->lParam
);
2136 HeapFree( GetProcessHeap(), 0, mis
);
2139 case WM_GETMINMAXINFO
:
2141 MINMAXINFO16
*mmi
= MapSL(p16
->lParam
);
2142 UnMapLS( p16
->lParam
);
2143 p16
->lParam
= *(LPARAM
*)(mmi
+ 1);
2144 STRUCT32_MINMAXINFO16to32( mmi
, (MINMAXINFO
*)(p16
->lParam
) );
2145 HeapFree( GetProcessHeap(), 0, mmi
);
2149 case WM_ASKCBFORMATNAME
:
2151 LPSTR str
= MapSL(p16
->lParam
);
2152 UnMapLS( p16
->lParam
);
2153 p16
->lParam
= *((LPARAM
*)str
- 1);
2154 lstrcpynA( (LPSTR
)(p16
->lParam
), str
, p16
->wParam
);
2155 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2160 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2161 UnMapLS( cs
->szTitle
);
2162 UnMapLS( cs
->szClass
);
2163 UnMapLS( p16
->lParam
);
2164 HeapFree( GetProcessHeap(), 0, cs
);
2167 case WM_MDIGETACTIVE
:
2168 if (lParam
) *(BOOL
*)lParam
= (BOOL16
)HIWORD(p16
->lResult
);
2169 p16
->lResult
= (LRESULT
)WIN_Handle32( LOWORD(p16
->lResult
) );
2173 NCCALCSIZE_PARAMS
*nc32
;
2174 NCCALCSIZE_PARAMS16
*nc
= MapSL(p16
->lParam
);
2175 UnMapLS( p16
->lParam
);
2176 p16
->lParam
= *(LPARAM
*)(nc
+ 1);
2177 nc32
= (NCCALCSIZE_PARAMS
*)(p16
->lParam
);
2178 CONV_RECT16TO32( &nc
->rgrc
[0], &nc32
->rgrc
[0] );
2181 WINDOWPOS16
*pos
= MapSL(nc
->lppos
);
2182 UnMapLS( nc
->lppos
);
2183 CONV_RECT16TO32( &nc
->rgrc
[1], &nc32
->rgrc
[1] );
2184 CONV_RECT16TO32( &nc
->rgrc
[2], &nc32
->rgrc
[2] );
2185 STRUCT32_WINDOWPOS16to32( pos
, nc32
->lppos
);
2186 HeapFree( GetProcessHeap(), 0, pos
);
2188 HeapFree( GetProcessHeap(), 0, nc
);
2194 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2195 UnMapLS( p16
->lParam
);
2196 UnMapLS( cs
->lpszName
);
2197 UnMapLS( cs
->lpszClass
);
2198 HeapFree( GetProcessHeap(), 0, cs
);
2201 case WM_WINDOWPOSCHANGING
:
2202 case WM_WINDOWPOSCHANGED
:
2204 WINDOWPOS16
*wp
= MapSL(p16
->lParam
);
2205 UnMapLS( p16
->lParam
);
2206 p16
->lParam
= *(LPARAM
*)(wp
+ 1);
2207 STRUCT32_WINDOWPOS16to32( wp
, (WINDOWPOS
*)p16
->lParam
);
2208 HeapFree( GetProcessHeap(), 0, wp
);
2212 UnMapLS(p16
->lParam
);
2217 LPMSG16 msg16
= MapSL(p16
->lParam
);
2219 UnMapLS( p16
->lParam
);
2220 msgp16
.wParam
=msg16
->wParam
;
2221 msgp16
.lParam
=msg16
->lParam
;
2222 WINPROC_UnmapMsg32ATo16(((LPMSG
)lParam
)->hwnd
, ((LPMSG
)lParam
)->message
,
2223 ((LPMSG
)lParam
)->wParam
, ((LPMSG
)lParam
)->lParam
,
2225 HeapFree( GetProcessHeap(), 0, msg16
);
2230 MDINEXTMENU
*next
= (MDINEXTMENU
*)lParam
;
2231 next
->hmenuNext
= LOWORD(p16
->lResult
);
2232 next
->hwndNext
= WIN_Handle32( HIWORD(p16
->lResult
) );
2240 /**********************************************************************
2241 * WINPROC_MapMsg32WTo16
2243 * Map a message from 32-bit Unicode to 16-bit.
2244 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2246 INT
WINPROC_MapMsg32WTo16( HWND hwnd
, UINT msg32
, WPARAM wParam32
,
2247 UINT16
*pmsg16
, WPARAM16
*pwparam16
,
2253 *pmsg16
= LOWORD(msg32
);
2254 *pwparam16
= LOWORD(wParam32
);
2259 case LB_FINDSTRINGEXACT
:
2260 case LB_INSERTSTRING
:
2261 case LB_SELECTSTRING
:
2264 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2265 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING
);
2270 case CB_FINDSTRINGEXACT
:
2271 case CB_INSERTSTRING
:
2272 case CB_SELECTSTRING
:
2274 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2275 *pmsg16
= (UINT16
)msg32
+ (CB_ADDSTRING16
- CB_ADDSTRING
);
2282 CREATESTRUCTW
*cs32
= (CREATESTRUCTW
*)*plparam
;
2284 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(CREATESTRUCT16
) ))) return -1;
2285 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA
*)cs32
, cs
);
2286 cs
->lpszName
= map_str_32W_to_16( cs32
->lpszName
);
2287 cs
->lpszClass
= map_str_32W_to_16( cs32
->lpszClass
);
2288 *plparam
= MapLS(cs
);
2293 MDICREATESTRUCT16
*cs
;
2294 MDICREATESTRUCTW
*cs32
= (MDICREATESTRUCTW
*)*plparam
;
2296 if (!(cs
= HeapAlloc( GetProcessHeap(), 0, sizeof(MDICREATESTRUCT16
) ))) return -1;
2297 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA
*)cs32
, cs
);
2298 cs
->szTitle
= map_str_32W_to_16( cs32
->szTitle
);
2299 cs
->szClass
= map_str_32W_to_16( cs32
->szClass
);
2300 *plparam
= MapLS(cs
);
2304 case WM_WININICHANGE
:
2305 case WM_DEVMODECHANGE
:
2306 *plparam
= map_str_32W_to_16( (LPWSTR
)*plparam
);
2310 if ( WINPROC_TestLBForStr( hwnd
))
2312 LPSTR str
= HeapAlloc( GetProcessHeap(), 0, 256 ); /* FIXME: fixed sized buffer */
2313 if (!str
) return -1;
2314 *pmsg16
= (msg32
== LB_GETTEXT
)? LB_GETTEXT16
: CB_GETLBTEXT16
;
2315 *plparam
= (LPARAM
)MapLS(str
);
2320 wch
= LOWORD(wParam32
);
2321 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2323 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
2326 wch
= LOWORD(wParam32
);
2327 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2329 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
2334 case WM_SYSDEADCHAR
:
2336 WideCharToMultiByte( CP_ACP
, 0, &wch
, 1, &ch
, 1, NULL
, NULL
);
2340 default: /* No Unicode translation needed (?) */
2341 return WINPROC_MapMsg32ATo16( hwnd
, msg32
, wParam32
, pmsg16
,
2342 pwparam16
, plparam
);
2347 /**********************************************************************
2348 * WINPROC_UnmapMsg32WTo16
2350 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2352 void WINPROC_UnmapMsg32WTo16( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
2359 case LB_FINDSTRINGEXACT
:
2360 case LB_INSERTSTRING
:
2361 case LB_SELECTSTRING
:
2366 case CB_FINDSTRINGEXACT
:
2367 case CB_INSERTSTRING
:
2368 case CB_SELECTSTRING
:
2371 case WM_WININICHANGE
:
2372 case WM_DEVMODECHANGE
:
2373 unmap_str_32W_to_16( p16
->lParam
);
2378 CREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2379 UnMapLS( p16
->lParam
);
2380 unmap_str_32W_to_16( cs
->lpszName
);
2381 unmap_str_32W_to_16( cs
->lpszClass
);
2382 HeapFree( GetProcessHeap(), 0, cs
);
2387 MDICREATESTRUCT16
*cs
= MapSL(p16
->lParam
);
2388 UnMapLS( p16
->lParam
);
2389 unmap_str_32W_to_16( cs
->szTitle
);
2390 unmap_str_32W_to_16( cs
->szClass
);
2391 HeapFree( GetProcessHeap(), 0, cs
);
2395 case WM_ASKCBFORMATNAME
:
2397 LPSTR str
= MapSL(p16
->lParam
);
2398 UnMapLS( p16
->lParam
);
2399 p16
->lParam
= *((LPARAM
*)str
- 1);
2400 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)p16
->lParam
, 0x7fffffff );
2401 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
- 1 );
2406 if ( WINPROC_TestLBForStr( hwnd
))
2408 LPSTR str
= MapSL(p16
->lParam
);
2409 UnMapLS( p16
->lParam
);
2410 MultiByteToWideChar( CP_ACP
, 0, str
, -1, (LPWSTR
)lParam
, 0x7fffffff );
2411 HeapFree( GetProcessHeap(), 0, (LPARAM
*)str
);
2415 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, p16
);
2421 /**********************************************************************
2422 * WINPROC_CallProc32ATo32W
2424 * Call a window procedure, translating args from Ansi to Unicode.
2426 static LRESULT
WINPROC_CallProc32ATo32W( WNDPROC func
, HWND hwnd
,
2427 UINT msg
, WPARAM wParam
,
2433 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2434 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2436 if( (unmap
= WINPROC_MapMsg32ATo32W( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
2437 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2438 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2441 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2442 if (unmap
) result
= WINPROC_UnmapMsg32ATo32W( hwnd
, msg
, wParam
, lParam
, result
);
2447 /**********************************************************************
2448 * WINPROC_CallProc32WTo32A
2450 * Call a window procedure, translating args from Unicode to Ansi.
2452 static LRESULT
WINPROC_CallProc32WTo32A( WNDPROC func
, HWND hwnd
,
2453 UINT msg
, WPARAM wParam
,
2459 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2460 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2462 if ((unmap
= WINPROC_MapMsg32WTo32A( hwnd
, msg
, &wParam
, &lParam
)) == -1) {
2463 ERR_(msg
)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2464 SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2467 result
= WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2468 if( unmap
) WINPROC_UnmapMsg32WTo32A( hwnd
, msg
, wParam
, lParam
);
2473 /**********************************************************************
2474 * __wine_call_wndproc_32A (USER.1010)
2476 LRESULT WINAPI
__wine_call_wndproc_32A( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
2482 HWND hwnd32
= WIN_Handle32( hwnd
);
2484 if (WINPROC_MapMsg16To32A( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2486 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
2487 return WINPROC_UnmapMsg16To32A( hwnd32
, msg32
, wParam32
, lParam
, result
);
2491 /**********************************************************************
2492 * __wine_call_wndproc_32W (USER.1011)
2494 LRESULT WINAPI
__wine_call_wndproc_32W( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
,
2500 HWND hwnd32
= WIN_Handle32( hwnd
);
2502 if (WINPROC_MapMsg16To32W( hwnd32
, msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
2504 result
= WINPROC_CallWndProc( func
, hwnd32
, msg32
, wParam32
, lParam
);
2505 return WINPROC_UnmapMsg16To32W( hwnd32
, msg32
, wParam32
, lParam
, result
);
2509 /**********************************************************************
2510 * WINPROC_CallProc32ATo16
2512 * Call a 16-bit window procedure, translating the 32-bit args.
2514 static LRESULT WINAPI
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND hwnd
,
2515 UINT msg
, WPARAM wParam
,
2521 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2522 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2524 mp16
.lParam
= lParam
;
2525 if (WINPROC_MapMsg32ATo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
, &mp16
.lParam
) == -1)
2527 mp16
.lResult
= WINPROC_CallWndProc16( func
, WIN_Handle16(hwnd
), msg16
,
2528 mp16
.wParam
, mp16
.lParam
);
2529 WINPROC_UnmapMsg32ATo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2530 return mp16
.lResult
;
2534 /**********************************************************************
2535 * WINPROC_CallProc32WTo16
2537 * Call a 16-bit window procedure, translating the 32-bit args.
2539 static LRESULT WINAPI
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND hwnd
,
2540 UINT msg
, WPARAM wParam
,
2546 TRACE_(msg
)("func %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
2547 func
, hwnd
, SPY_GetMsgName(msg
, hwnd
), wParam
, lParam
);
2549 mp16
.lParam
= lParam
;
2550 if (WINPROC_MapMsg32WTo16( hwnd
, msg
, wParam
, &msg16
, &mp16
.wParam
,
2551 &mp16
.lParam
) == -1)
2553 mp16
.lResult
= WINPROC_CallWndProc16( func
, WIN_Handle16(hwnd
), msg16
,
2554 mp16
.wParam
, mp16
.lParam
);
2555 WINPROC_UnmapMsg32WTo16( hwnd
, msg
, wParam
, lParam
, &mp16
);
2556 return mp16
.lResult
;
2560 /**********************************************************************
2561 * CallWindowProc (USER.122)
2562 * CallWindowProc16 (USER32.@)
2564 LRESULT WINAPI
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
2565 WPARAM16 wParam
, LPARAM lParam
)
2567 WINDOWPROC
*proc
= WINPROC_GetPtr( func
);
2570 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2573 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_16
);
2574 return WINPROC_CallWndProc16( func
, hwnd
, msg
, wParam
, lParam
);
2580 if (!proc
->thunk
.t_from32
.proc
) return 0;
2581 return WINPROC_CallWndProc16( proc
->thunk
.t_from32
.proc
,
2582 hwnd
, msg
, wParam
, lParam
);
2584 if (!proc
->thunk
.t_from16
.proc
) return 0;
2585 return __wine_call_wndproc_32A( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
2587 if (!proc
->thunk
.t_from16
.proc
) return 0;
2588 return __wine_call_wndproc_32W( hwnd
, msg
, wParam
, lParam
, proc
->thunk
.t_from16
.proc
);
2590 WARN_(relay
)("Invalid proc %p\n", proc
);
2596 /**********************************************************************
2597 * CallWindowProcA (USER32.@)
2599 * The CallWindowProc() function invokes the windows procedure _func_,
2600 * with _hwnd_ as the target window, the message specified by _msg_, and
2601 * the message parameters _wParam_ and _lParam_.
2603 * Some kinds of argument conversion may be done, I'm not sure what.
2605 * CallWindowProc() may be used for windows subclassing. Use
2606 * SetWindowLong() to set a new windows procedure for windows of the
2607 * subclass, and handle subclassed messages in the new windows
2608 * procedure. The new windows procedure may then use CallWindowProc()
2609 * with _func_ set to the parent class's windows procedure to dispatch
2610 * the message to the superclass.
2614 * The return value is message dependent.
2620 LRESULT WINAPI
CallWindowProcA(
2621 WNDPROC func
, /* [in] window procedure */
2622 HWND hwnd
, /* [in] target window */
2623 UINT msg
, /* [in] message */
2624 WPARAM wParam
, /* [in] message dependent parameter */
2625 LPARAM lParam
/* [in] message dependent parameter */
2627 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2629 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2632 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32A
);
2633 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2639 if (!proc
->thunk
.t_from32
.proc
) return 0;
2640 return WINPROC_CallProc32ATo16( proc
->thunk
.t_from32
.proc
,
2641 hwnd
, msg
, wParam
, lParam
);
2643 if (!proc
->thunk
.t_from16
.proc
) return 0;
2644 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2645 hwnd
, msg
, wParam
, lParam
);
2647 if (!proc
->thunk
.t_from16
.proc
) return 0;
2648 return WINPROC_CallProc32ATo32W( proc
->thunk
.t_from16
.proc
,
2649 hwnd
, msg
, wParam
, lParam
);
2651 WARN_(relay
)("Invalid proc %p\n", proc
);
2657 /**********************************************************************
2658 * CallWindowProcW (USER32.@)
2660 LRESULT WINAPI
CallWindowProcW( WNDPROC func
, HWND hwnd
, UINT msg
,
2661 WPARAM wParam
, LPARAM lParam
)
2663 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
2665 if (!proc
) return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2668 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32W
);
2669 return WINPROC_CallWndProc( func
, hwnd
, msg
, wParam
, lParam
);
2675 if (!proc
->thunk
.t_from32
.proc
) return 0;
2676 return WINPROC_CallProc32WTo16( proc
->thunk
.t_from32
.proc
,
2677 hwnd
, msg
, wParam
, lParam
);
2679 if (!proc
->thunk
.t_from16
.proc
) return 0;
2680 return WINPROC_CallProc32WTo32A( proc
->thunk
.t_from16
.proc
,
2681 hwnd
, msg
, wParam
, lParam
);
2683 if (!proc
->thunk
.t_from16
.proc
) return 0;
2684 return WINPROC_CallWndProc( proc
->thunk
.t_from16
.proc
,
2685 hwnd
, msg
, wParam
, lParam
);
2687 WARN_(relay
)("Invalid proc %p\n", proc
);