2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
8 #include "wine/winbase16.h"
12 #include "selectors.h"
16 #include "debugtools.h"
22 DECLARE_DEBUG_CHANNEL(msg)
23 DECLARE_DEBUG_CHANNEL(relay)
24 DECLARE_DEBUG_CHANNEL(win)
26 /* Window procedure 16-to-32-bit thunk,
27 * see BuildSpec16Files() in tools/build.c */
31 BYTE popl_eax; /* popl %eax (return address) */
32 BYTE pushl_func; /* pushl $proc */
33 WNDPROC proc WINE_PACKED;
34 BYTE pushl_eax; /* pushl %eax */
35 WORD pushw_bp WINE_PACKED; /* pushw %bp */
36 BYTE pushl_thunk; /* pushl $thunkfrom16 */
37 void (*thunk32)() WINE_PACKED;
38 BYTE lcall; /* lcall cs:relay */
39 void (*relay)() WINE_PACKED; /* WINPROC_CallProc16To32A/W() */
41 } WINPROC_THUNK_FROM16;
43 /* Window procedure 32-to-16-bit thunk,
44 * see BuildSpec32Files() in tools/build.c */
48 BYTE popl_eax; /* popl %eax (return address) */
49 BYTE pushl_func; /* pushl $proc */
50 WNDPROC16 proc WINE_PACKED;
51 BYTE pushl_eax; /* pushl %eax */
52 BYTE jmp; /* jmp relay (relative jump)*/
53 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
54 } WINPROC_THUNK_FROM32;
56 /* Simple jmp to call 32-bit procedure directly */
59 BYTE jmp; /* jmp proc (relative jump) */
60 WNDPROC proc WINE_PACKED;
65 WINPROC_THUNK_FROM16 t_from16;
66 WINPROC_THUNK_FROM32 t_from32;
69 typedef struct tagWINDOWPROC
71 WINPROC_THUNK thunk; /* Thunk */
72 WINPROC_JUMP jmp; /* Jump */
73 struct tagWINDOWPROC *next; /* Next window proc */
74 UINT magic; /* Magic number */
75 WINDOWPROCTYPE type; /* Function type */
76 WINDOWPROCUSER user; /* Function user */
79 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
81 #define WINPROC_THUNKPROC(pproc) \
82 (((pproc)->type == WIN_PROC_16) ? \
83 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
84 (WNDPROC16)((pproc)->thunk.t_from16.proc))
86 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
87 UINT msg, WPARAM wParam,
89 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
90 UINT msg, WPARAM wParam,
92 static LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
93 WPARAM16 wParam, LPARAM lParam,
95 static LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
96 WPARAM16 wParam, LPARAM lParam,
99 static HANDLE WinProcHeap;
102 /**********************************************************************
105 BOOL WINPROC_Init(void)
107 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
110 WARN_(relay)("Unable to create winproc heap\n" );
117 /**********************************************************************
118 * WINPROC_CallWndProc32
120 * Call a 32-bit WndProc.
122 static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
123 WPARAM wParam, LPARAM lParam )
128 TRACE_(relay)("(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
129 proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
130 /* To avoid any deadlocks, all the locks on the windows structures
131 must be suspended before the control is passed to the application */
132 iWndsLocks = WIN_SuspendWndsLock();
133 retvalue = proc( hwnd, msg, wParam, lParam );
134 WIN_RestoreWndsLock(iWndsLocks);
139 /**********************************************************************
142 * Return a pointer to the win proc.
144 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
149 /* Check for a linear pointer */
151 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
153 ptr = (BYTE *)handle;
154 /* First check if it is the jmp address */
155 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
156 (int)&((WINDOWPROC *)0)->thunk;
157 /* Now it must be the thunk address */
158 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
159 /* Now we have a pointer to the WINDOWPROC struct */
160 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
161 return (WINDOWPROC *)ptr;
164 /* Check for a segmented pointer */
166 if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
168 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
169 if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
170 /* It must be the thunk address */
171 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
172 /* Now we have a pointer to the WINDOWPROC struct */
173 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
174 return (WINDOWPROC *)ptr;
181 /**********************************************************************
182 * WINPROC_AllocWinProc
184 * Allocate a new window procedure.
186 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
187 WINDOWPROCUSER user )
189 WINDOWPROC *proc, *oldproc;
191 /* Allocate a window procedure */
193 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
195 /* Check if the function is already a win proc */
197 if ((oldproc = WINPROC_GetPtr( func )))
206 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
207 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
208 proc->thunk.t_from32.proc = func;
209 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
210 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
211 proc->thunk.t_from32.relay = /* relative jump */
212 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
213 (DWORD)(&proc->thunk.t_from32.relay + 1));
217 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
218 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
219 proc->thunk.t_from16.proc = (FARPROC)func;
220 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
221 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
222 proc->thunk.t_from16.pushl_thunk = 0x68; /* pushl $thunkfrom16 */
223 proc->thunk.t_from16.thunk32 = (type == WIN_PROC_32A) ?
224 (void(*)())WINPROC_CallProc16To32A :
225 (void(*)())WINPROC_CallProc16To32W;
226 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:relay */
227 proc->thunk.t_from16.relay = (void*)Callbacks->CallFrom16WndProc;
228 GET_CS(proc->thunk.t_from16.cs);
229 proc->jmp.jmp = 0xe9;
230 /* Fixup relative jump */
231 proc->jmp.proc = (WNDPROC)((DWORD)func -
232 (DWORD)(&proc->jmp.proc + 1));
235 /* Should not happen */
238 proc->magic = WINPROC_MAGIC;
243 TRACE_(win)("(%08x,%d): returning %08x\n",
244 (UINT)func, type, (UINT)proc );
249 /**********************************************************************
252 * Get a window procedure pointer that can be passed to the Windows program.
254 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
256 if (!proc) return NULL;
257 if (type == WIN_PROC_16) /* We want a 16:16 address */
259 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
260 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
262 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
263 &((WINDOWPROC *)proc)->thunk );
265 else /* We want a 32-bit address */
267 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
268 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
269 else if (type != ((WINDOWPROC *)proc)->type)
270 /* Have to return the jmp address if types don't match */
271 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
273 /* Some Win16 programs want to get back the proc they set */
274 return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc;
279 /**********************************************************************
282 * Set the window procedure for a window or class. There are
283 * three tree classes of winproc callbacks:
285 * 1) class -> wp - not subclassed
286 * class -> wp -> wp -> wp -> wp - SetClassLong()
288 * 2) window -' / - not subclassed
289 * window -> wp -> wp ' - SetWindowLong()
291 * 3) timer -> wp - SetTimer()
293 * Initially, winproc of the window points to the current winproc
294 * thunk of its class. Subclassing prepends a new thunk to the
295 * window winproc chain at the head of the list. Thus, window thunk
296 * list includes class thunks and the latter are preserved when the
297 * window is destroyed.
300 BOOL WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
301 WINDOWPROCTYPE type, WINDOWPROCUSER user )
303 BOOL bRecycle = FALSE;
304 WINDOWPROC *proc, **ppPrev;
306 /* Check if function is already in the list */
308 ppPrev = (WINDOWPROC **)pFirst;
309 proc = WINPROC_GetPtr( func );
316 if ((*ppPrev)->user != user)
318 /* terminal thunk is being restored */
320 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
321 *(WINDOWPROC **)pFirst = *ppPrev;
330 if (((*ppPrev)->type == type) &&
331 (func == WINPROC_THUNKPROC(*ppPrev)))
338 /* WPF_CLASS thunk terminates window thunk list */
339 if ((*ppPrev)->user != user) break;
340 ppPrev = &(*ppPrev)->next;
345 /* Extract this thunk from the list */
347 *ppPrev = proc->next;
349 else /* Allocate a new one */
351 if (proc) /* Was already a win proc */
354 func = WINPROC_THUNKPROC(proc);
356 proc = WINPROC_AllocWinProc( func, type, user );
357 if (!proc) return FALSE;
360 /* Add the win proc at the head of the list */
362 TRACE_(win)("(%08x,%08x,%d): res=%08x\n",
363 (UINT)*pFirst, (UINT)func, type, (UINT)proc );
364 proc->next = *(WINDOWPROC **)pFirst;
365 *(WINDOWPROC **)pFirst = proc;
370 /**********************************************************************
373 * Free a list of win procs.
375 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
379 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
380 if (((WINDOWPROC *)proc)->user != user) break;
381 TRACE_(win)("freeing %08x\n", (UINT)proc);
382 HeapFree( WinProcHeap, 0, proc );
388 /**********************************************************************
389 * WINPROC_GetProcType
391 * Return the window procedure type.
393 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
396 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
397 return WIN_PROC_INVALID;
398 return ((WINDOWPROC *)proc)->type;
400 /**********************************************************************
401 * WINPROC_TestCBForStr
403 * Return TRUE if the lparam is a string
405 BOOL WINPROC_TestCBForStr ( HWND hwnd )
408 WND * wnd = WIN_FindWndPtr(hwnd);
409 retvalue = ( !(LOWORD(wnd->dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
410 (LOWORD(wnd->dwStyle) & CBS_HASSTRINGS) );
411 WIN_ReleaseWndPtr(wnd);
414 /**********************************************************************
415 * WINPROC_TestLBForStr
417 * Return TRUE if the lparam is a string
419 BOOL WINPROC_TestLBForStr ( HWND hwnd )
422 WND * wnd = WIN_FindWndPtr(hwnd);
423 retvalue = ( !(LOWORD(wnd->dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) ||
424 (LOWORD(wnd->dwStyle) & LBS_HASSTRINGS) );
425 WIN_ReleaseWndPtr(wnd);
429 /**********************************************************************
430 * WINPROC_MapMsg32ATo32W
432 * Map a message from Ansi to Unicode.
433 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
436 * WM_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR, WM_SYSDEADCHAR
439 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
440 * the first four bytes are the handle of the icon
441 * when the WM_SETTEXT message has been used to set the icon
443 INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
449 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
450 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
452 *ptr++ = *plparam; /* Store previous lParam */
453 *plparam = (LPARAM)ptr;
456 /* lparam is string (0-terminated) */
458 case WM_WININICHANGE:
461 case CB_FINDSTRINGEXACT:
462 case CB_SELECTSTRING:
466 case LB_SELECTSTRING:
468 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
469 return (*plparam ? 1 : -1);
474 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
477 *cs = *(CREATESTRUCTW *)*plparam;
478 if (HIWORD(cs->lpszName))
479 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
480 (LPCSTR)cs->lpszName );
481 if (HIWORD(cs->lpszClass))
482 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
483 (LPCSTR)cs->lpszClass );
484 *plparam = (LPARAM)cs;
489 MDICREATESTRUCTW *cs =
490 (MDICREATESTRUCTW *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
492 *cs = *(MDICREATESTRUCTW *)*plparam;
493 if (HIWORD(cs->szClass))
494 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
495 (LPCSTR)cs->szClass );
496 if (HIWORD(cs->szTitle))
497 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
498 (LPCSTR)cs->szTitle );
499 *plparam = (LPARAM)cs;
505 case LB_INSERTSTRING:
506 if ( WINPROC_TestLBForStr( hwnd ))
507 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
508 return (*plparam ? 1 : -1);
510 case LB_GETTEXT: /* fixme: fixed sized buffer */
511 { if ( WINPROC_TestLBForStr( hwnd ))
512 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
514 *ptr++ = *plparam; /* Store previous lParam */
515 *plparam = (LPARAM)ptr;
522 case CB_INSERTSTRING:
523 if ( WINPROC_TestCBForStr( hwnd ))
524 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
525 return (*plparam ? 1 : -1);
527 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
528 { if ( WINPROC_TestCBForStr( hwnd ))
529 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
531 *ptr++ = *plparam; /* Store previous lParam */
532 *plparam = (LPARAM)ptr;
539 { WORD len = (WORD)*plparam;
540 LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
542 *ptr++ = *plparam; /* Store previous lParam */
543 *((WORD *) ptr) = len; /* Store the length */
544 *plparam = (LPARAM)ptr;
548 case WM_ASKCBFORMATNAME:
549 case WM_DEVMODECHANGE:
550 case WM_PAINTCLIPBOARD:
551 case WM_SIZECLIPBOARD:
552 case EM_SETPASSWORDCHAR:
553 FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg), msg );
555 default: /* No translation needed */
561 /**********************************************************************
562 * WINPROC_UnmapMsg32ATo32W
564 * Unmap a message that was mapped from Ansi to Unicode.
566 void WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
572 LPARAM *ptr = (LPARAM *)lParam - 1;
573 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)lParam, wParam );
574 HeapFree( SystemHeap, 0, ptr );
581 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
582 if (HIWORD(cs->lpszName))
583 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
584 if (HIWORD(cs->lpszClass))
585 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
586 HeapFree( SystemHeap, 0, cs );
592 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
593 if (HIWORD(cs->szTitle))
594 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
595 if (HIWORD(cs->szClass))
596 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
597 HeapFree( SystemHeap, 0, cs );
602 case WM_WININICHANGE:
605 case CB_FINDSTRINGEXACT:
606 case CB_SELECTSTRING:
610 case LB_SELECTSTRING:
612 HeapFree( SystemHeap, 0, (void *)lParam );
617 case LB_INSERTSTRING:
618 if ( WINPROC_TestLBForStr( hwnd ))
619 HeapFree( SystemHeap, 0, (void *)lParam );
623 { if ( WINPROC_TestLBForStr( hwnd ))
624 { LPARAM *ptr = (LPARAM *)lParam - 1;
625 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
626 HeapFree( SystemHeap, 0, ptr );
633 case CB_INSERTSTRING:
634 if ( WINPROC_TestCBForStr( hwnd ))
635 HeapFree( SystemHeap, 0, (void *)lParam );
639 { if ( WINPROC_TestCBForStr( hwnd ))
640 { LPARAM *ptr = (LPARAM *)lParam - 1;
641 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
642 HeapFree( SystemHeap, 0, ptr );
649 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
650 WORD len = *(WORD *) lParam;
651 lstrcpynWtoA( (LPSTR)*ptr , (LPWSTR)lParam, len );
652 HeapFree( SystemHeap, 0, ptr );
659 /**********************************************************************
660 * WINPROC_MapMsg32WTo32A
662 * Map a message from Unicode to Ansi.
663 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
665 INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
670 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
671 wParam + sizeof(LPARAM) );
673 *ptr++ = *plparam; /* Store previous lParam */
674 *plparam = (LPARAM)ptr;
679 case WM_WININICHANGE:
682 case CB_FINDSTRINGEXACT:
683 case CB_SELECTSTRING:
687 case LB_SELECTSTRING:
689 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
690 return (*plparam ? 1 : -1);
695 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
698 *cs = *(CREATESTRUCTA *)*plparam;
699 if (HIWORD(cs->lpszName))
700 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
701 (LPCWSTR)cs->lpszName );
702 if (HIWORD(cs->lpszClass))
703 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
704 (LPCWSTR)cs->lpszClass);
705 *plparam = (LPARAM)cs;
710 MDICREATESTRUCTA *cs =
711 (MDICREATESTRUCTA *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
713 *cs = *(MDICREATESTRUCTA *)*plparam;
714 if (HIWORD(cs->szTitle))
715 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
716 (LPCWSTR)cs->szTitle );
717 if (HIWORD(cs->szClass))
718 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
719 (LPCWSTR)cs->szClass );
720 *plparam = (LPARAM)cs;
726 case LB_INSERTSTRING:
727 if ( WINPROC_TestLBForStr( hwnd ))
728 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
729 return (*plparam ? 1 : -1);
731 case LB_GETTEXT: /* fixme: fixed sized buffer */
732 { if ( WINPROC_TestLBForStr( hwnd ))
733 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
735 *ptr++ = *plparam; /* Store previous lParam */
736 *plparam = (LPARAM)ptr;
743 case CB_INSERTSTRING:
744 if ( WINPROC_TestCBForStr( hwnd ))
745 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
746 return (*plparam ? 1 : -1);
748 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
749 { if ( WINPROC_TestCBForStr( hwnd ))
750 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
752 *ptr++ = *plparam; /* Store previous lParam */
753 *plparam = (LPARAM)ptr;
760 { WORD len = (WORD)*plparam;
761 LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
763 *ptr++ = *plparam; /* Store previous lParam */
764 *((WORD *) ptr) = len; /* Store the length */
765 *plparam = (LPARAM)ptr;
769 case WM_ASKCBFORMATNAME:
770 case WM_DEVMODECHANGE:
771 case WM_PAINTCLIPBOARD:
772 case WM_SIZECLIPBOARD:
773 case EM_SETPASSWORDCHAR:
774 FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg),msg );
776 default: /* No translation needed */
782 /**********************************************************************
783 * WINPROC_UnmapMsg32WTo32A
785 * Unmap a message that was mapped from Unicode to Ansi.
787 void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
793 LPARAM *ptr = (LPARAM *)lParam - 1;
794 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)lParam, wParam );
795 HeapFree( SystemHeap, 0, ptr );
800 case WM_WININICHANGE:
803 case CB_FINDSTRINGEXACT:
804 case CB_SELECTSTRING:
808 case LB_SELECTSTRING:
810 HeapFree( SystemHeap, 0, (void *)lParam );
816 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
817 if (HIWORD(cs->lpszName))
818 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
819 if (HIWORD(cs->lpszClass))
820 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
821 HeapFree( SystemHeap, 0, cs );
827 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
828 if (HIWORD(cs->szTitle))
829 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
830 if (HIWORD(cs->szClass))
831 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
832 HeapFree( SystemHeap, 0, cs );
838 case LB_INSERTSTRING:
839 if ( WINPROC_TestLBForStr( hwnd ))
840 HeapFree( SystemHeap, 0, (void *)lParam );
844 { if ( WINPROC_TestLBForStr( hwnd ))
845 { LPARAM *ptr = (LPARAM *)lParam - 1;
846 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
847 HeapFree( SystemHeap, 0, ptr );
854 case CB_INSERTSTRING:
855 if ( WINPROC_TestCBForStr( hwnd ))
856 HeapFree( SystemHeap, 0, (void *)lParam );
860 { if ( WINPROC_TestCBForStr( hwnd ))
861 { LPARAM *ptr = (LPARAM *)lParam - 1;
862 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
863 HeapFree( SystemHeap, 0, ptr );
870 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lparam */
871 WORD len = *(WORD *)ptr;
872 lstrcpynAtoW( (LPWSTR) *ptr, (LPSTR)lParam, len );
873 HeapFree( SystemHeap, 0, ptr );
880 /**********************************************************************
881 * WINPROC_MapMsg16To32A
883 * Map a message from 16- to 32-bit Ansi.
884 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
886 INT WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
887 WPARAM *pwparam32, LPARAM *plparam )
889 *pmsg32 = (UINT)msg16;
890 *pwparam32 = (WPARAM)wParam16;
897 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
898 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
902 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
903 *plparam = (LPARAM)(HWND)HIWORD(*plparam);
906 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
907 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
908 *pwparam32 = (WPARAM)(HDC)wParam16;
909 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
913 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
914 COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)
915 HeapAlloc(SystemHeap, 0, sizeof(*cis));
917 cis->CtlType = cis16->CtlType;
918 cis->CtlID = cis16->CtlID;
919 cis->hwndItem = cis16->hwndItem;
920 cis->itemID1 = cis16->itemID1;
921 cis->itemData1 = cis16->itemData1;
922 cis->itemID2 = cis16->itemID2;
923 cis->itemData2 = cis16->itemData2;
924 cis->dwLocaleId = 0; /* FIXME */
925 *plparam = (LPARAM)cis;
930 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
931 DELETEITEMSTRUCT *dis = (DELETEITEMSTRUCT *)
932 HeapAlloc(SystemHeap, 0, sizeof(*dis));
934 dis->CtlType = dis16->CtlType;
935 dis->CtlID = dis16->CtlID;
936 dis->hwndItem = dis16->hwndItem;
937 dis->itemData = dis16->itemData;
938 *plparam = (LPARAM)dis;
943 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
944 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)
945 HeapAlloc(SystemHeap, 0,
946 sizeof(*mis) + sizeof(LPARAM));
948 mis->CtlType = mis16->CtlType;
949 mis->CtlID = mis16->CtlID;
950 mis->itemID = mis16->itemID;
951 mis->itemWidth = mis16->itemWidth;
952 mis->itemHeight = mis16->itemHeight;
953 mis->itemData = mis16->itemData;
954 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
955 *plparam = (LPARAM)mis;
960 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
961 DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)HeapAlloc(SystemHeap, 0,
964 dis->CtlType = dis16->CtlType;
965 dis->CtlID = dis16->CtlID;
966 dis->itemID = dis16->itemID;
967 dis->itemAction = dis16->itemAction;
968 dis->itemState = dis16->itemState;
969 dis->hwndItem = dis16->hwndItem;
970 dis->hDC = dis16->hDC;
971 dis->itemData = dis16->itemData;
972 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
973 *plparam = (LPARAM)dis;
976 case WM_GETMINMAXINFO:
978 MINMAXINFO *mmi = (MINMAXINFO *)HeapAlloc( SystemHeap, 0,
979 sizeof(*mmi) + sizeof(LPARAM));
981 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
983 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
984 *plparam = (LPARAM)mmi;
989 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
993 MDICREATESTRUCT16 *cs16 =
994 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
995 MDICREATESTRUCTA *cs =
996 (MDICREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
997 sizeof(*cs) + sizeof(LPARAM) );
999 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
1000 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1001 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
1002 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1003 *plparam = (LPARAM)cs;
1006 case WM_MDIGETACTIVE:
1007 *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL) );
1008 *(BOOL*)(*plparam) = 0;
1012 *pmsg32=WM_MDIREFRESHMENU;
1013 *pwparam32 = (WPARAM)(HMENU)LOWORD(*plparam);
1014 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1018 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1019 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1021 case WM_MDIACTIVATE:
1024 *pwparam32 = (WPARAM)(HWND)HIWORD(*plparam);
1025 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1027 else /* message sent to MDI client */
1028 *pwparam32 = wParam16;
1032 NCCALCSIZE_PARAMS16 *nc16;
1033 NCCALCSIZE_PARAMS *nc;
1035 nc = (NCCALCSIZE_PARAMS *)HeapAlloc( SystemHeap, 0,
1036 sizeof(*nc) + sizeof(LPARAM) );
1038 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
1039 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
1042 nc->lppos = (WINDOWPOS *)HeapAlloc( SystemHeap, 0,
1043 sizeof(*nc->lppos) );
1044 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
1045 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
1046 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
1048 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1049 *plparam = (LPARAM)nc;
1055 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1056 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
1057 sizeof(*cs) + sizeof(LPARAM) );
1059 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
1060 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1061 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1062 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1063 *plparam = (LPARAM)cs;
1066 case WM_PARENTNOTIFY:
1067 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1069 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1070 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1073 case WM_WINDOWPOSCHANGING:
1074 case WM_WINDOWPOSCHANGED:
1076 WINDOWPOS *wp = (WINDOWPOS *)HeapAlloc( SystemHeap, 0,
1077 sizeof(*wp) + sizeof(LPARAM) );
1079 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
1081 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1082 *plparam = (LPARAM)wp;
1088 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1089 LPMSG msg32 = (LPMSG)HeapAlloc( SystemHeap, 0, sizeof(MSG) );
1091 if (!msg32) return -1;
1092 msg32->hwnd = msg16->hwnd;
1093 msg32->lParam = msg16->lParam;
1094 msg32->time = msg16->time;
1095 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1096 /* this is right, right? */
1097 if (WINPROC_MapMsg16To32A(msg16->message,msg16->wParam,
1098 &msg32->message,&msg32->wParam,
1099 &msg32->lParam)<0) {
1100 HeapFree( SystemHeap, 0, msg32 );
1103 *plparam = (LPARAM)msg32;
1108 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1110 case WM_ACTIVATEAPP:
1112 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1113 a 32bit window. Might be superflous with 32bit interprocess
1116 HTASK16 htask = (HTASK16) *plparam;
1117 DWORD idThread = (DWORD)((TDB*)GlobalLock16(htask))->thdb->teb.tid;
1118 *plparam = (LPARAM) idThread;
1121 case WM_ASKCBFORMATNAME:
1122 case WM_DEVMODECHANGE:
1123 case WM_PAINTCLIPBOARD:
1124 case WM_SIZECLIPBOARD:
1125 case WM_WININICHANGE:
1126 FIXME_(msg)("message %04x needs translation\n",msg16 );
1129 default: /* No translation needed */
1135 /**********************************************************************
1136 * WINPROC_UnmapMsg16To32A
1138 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1140 LRESULT WINPROC_UnmapMsg16To32A( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1145 case WM_COMPAREITEM:
1148 HeapFree( SystemHeap, 0, (LPVOID)lParam );
1150 case WM_MEASUREITEM:
1152 MEASUREITEMSTRUCT16 *mis16;
1153 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1154 lParam = *(LPARAM *)(mis + 1);
1155 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
1156 mis16->itemWidth = (UINT16)mis->itemWidth;
1157 mis16->itemHeight = (UINT16)mis->itemHeight;
1158 HeapFree( SystemHeap, 0, mis );
1161 case WM_GETMINMAXINFO:
1163 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1164 lParam = *(LPARAM *)(mmi + 1);
1165 STRUCT32_MINMAXINFO32to16( mmi,
1166 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
1167 HeapFree( SystemHeap, 0, mmi );
1172 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1173 lParam = *(LPARAM *)(cs + 1);
1174 STRUCT32_MDICREATESTRUCT32Ato16( cs,
1175 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1176 HeapFree( SystemHeap, 0, cs );
1179 case WM_MDIGETACTIVE:
1180 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1181 HeapFree( SystemHeap, 0, (BOOL *)lParam );
1185 NCCALCSIZE_PARAMS16 *nc16;
1186 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1187 lParam = *(LPARAM *)(nc + 1);
1188 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
1189 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
1192 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
1193 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
1196 STRUCT32_WINDOWPOS32to16( nc->lppos,
1197 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
1198 HeapFree( SystemHeap, 0, nc->lppos );
1201 HeapFree( SystemHeap, 0, nc );
1207 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1208 lParam = *(LPARAM *)(cs + 1);
1209 STRUCT32_CREATESTRUCT32Ato16( cs,
1210 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1211 HeapFree( SystemHeap, 0, cs );
1214 case WM_WINDOWPOSCHANGING:
1215 case WM_WINDOWPOSCHANGED:
1217 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1218 lParam = *(LPARAM *)(wp + 1);
1219 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
1220 HeapFree( SystemHeap, 0, wp );
1226 LPMSG msg32 = (LPMSG)lParam;
1228 WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1230 HeapFree( SystemHeap, 0, msg32 );
1238 /**********************************************************************
1239 * WINPROC_MapMsg16To32W
1241 * Map a message from 16- to 32-bit Unicode.
1242 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1244 INT WINPROC_MapMsg16To32W( HWND16 hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1245 WPARAM *pwparam32, LPARAM *plparam )
1251 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1252 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, *pwparam32, plparam );
1256 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1257 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
1258 sizeof(*cs) + sizeof(LPARAM) );
1260 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1261 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1262 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1263 if (HIWORD(cs->lpszName))
1264 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
1265 (LPCSTR)cs->lpszName );
1266 if (HIWORD(cs->lpszClass))
1267 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
1268 (LPCSTR)cs->lpszClass );
1269 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1270 *plparam = (LPARAM)cs;
1275 MDICREATESTRUCT16 *cs16 =
1276 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1277 MDICREATESTRUCTW *cs =
1278 (MDICREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
1279 sizeof(*cs) + sizeof(LPARAM) );
1281 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1282 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1283 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
1284 if (HIWORD(cs->szTitle))
1285 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
1286 (LPCSTR)cs->szTitle );
1287 if (HIWORD(cs->szClass))
1288 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
1289 (LPCSTR)cs->szClass );
1290 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1291 *plparam = (LPARAM)cs;
1297 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1298 LPMSG msg32 = (LPMSG)HeapAlloc( SystemHeap, 0, sizeof(MSG) );
1300 if (!msg32) return -1;
1301 msg32->hwnd = msg16->hwnd;
1302 msg32->lParam = msg16->lParam;
1303 msg32->time = msg16->time;
1304 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1305 /* this is right, right? */
1306 if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
1307 &msg32->message,&msg32->wParam,
1308 &msg32->lParam)<0) {
1309 HeapFree( SystemHeap, 0, msg32 );
1312 *plparam = (LPARAM)msg32;
1316 default: /* No Unicode translation needed */
1317 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1318 pwparam32, plparam );
1323 /**********************************************************************
1324 * WINPROC_UnmapMsg16To32W
1326 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1328 LRESULT WINPROC_UnmapMsg16To32W( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1335 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
1340 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1341 lParam = *(LPARAM *)(cs + 1);
1342 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs,
1343 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1344 if (HIWORD(cs->lpszName))
1345 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1346 if (HIWORD(cs->lpszClass))
1347 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1348 HeapFree( SystemHeap, 0, cs );
1353 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1354 lParam = *(LPARAM *)(cs + 1);
1355 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs,
1356 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1357 if (HIWORD(cs->szTitle))
1358 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1359 if (HIWORD(cs->szClass))
1360 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1361 HeapFree( SystemHeap, 0, cs );
1367 LPMSG msg32 = (LPMSG)lParam;
1369 WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1371 HeapFree( SystemHeap, 0, msg32 );
1375 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1381 /**********************************************************************
1382 * WINPROC_MapMsg32ATo16
1384 * Map a message from 32-bit Ansi to 16-bit.
1385 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1387 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1388 UINT16 *pmsg16, WPARAM16 *pwparam16,
1391 *pmsg16 = (UINT16)msg32;
1392 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1400 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1409 case EM_SCROLLCARET:
1412 case EM_GETLINECOUNT:
1424 case EM_LINEFROMCHAR:
1425 case EM_SETTABSTOPS:
1426 case EM_SETPASSWORDCHAR:
1427 case EM_EMPTYUNDOBUFFER:
1428 case EM_GETFIRSTVISIBLELINE:
1429 case EM_SETREADONLY:
1430 case EM_SETWORDBREAKPROC:
1431 case EM_GETWORDBREAKPROC:
1432 case EM_GETPASSWORDCHAR:
1433 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1438 case LB_DELETESTRING:
1439 case LB_GETANCHORINDEX:
1440 case LB_GETCARETINDEX:
1443 case LB_GETHORIZONTALEXTENT:
1444 case LB_GETITEMDATA:
1445 case LB_GETITEMHEIGHT:
1447 case LB_GETSELCOUNT:
1449 case LB_GETTOPINDEX:
1450 case LB_RESETCONTENT:
1451 case LB_SELITEMRANGE:
1452 case LB_SELITEMRANGEEX:
1453 case LB_SETANCHORINDEX:
1454 case LB_SETCARETINDEX:
1455 case LB_SETCOLUMNWIDTH:
1457 case LB_SETHORIZONTALEXTENT:
1458 case LB_SETITEMDATA:
1459 case LB_SETITEMHEIGHT:
1461 case LB_SETTOPINDEX:
1462 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1464 case CB_DELETESTRING:
1466 case CB_GETLBTEXTLEN:
1468 case CB_RESETCONTENT:
1472 case CB_SHOWDROPDOWN:
1473 case CB_SETITEMDATA:
1474 case CB_SETITEMHEIGHT:
1475 case CB_GETITEMHEIGHT:
1476 case CB_SETEXTENDEDUI:
1477 case CB_GETEXTENDEDUI:
1478 case CB_GETDROPPEDSTATE:
1479 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1482 *pmsg16 = CB_GETEDITSEL16;
1487 case LB_FINDSTRINGEXACT:
1488 case LB_INSERTSTRING:
1489 case LB_SELECTSTRING:
1493 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1494 if (!str) return -1;
1495 *plparam = (LPARAM)SEGPTR_GET(str);
1497 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1502 case CB_FINDSTRINGEXACT:
1503 case CB_INSERTSTRING:
1504 case CB_SELECTSTRING:
1507 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1508 if (!str) return -1;
1509 *plparam = (LPARAM)SEGPTR_GET(str);
1511 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1514 case LB_GETITEMRECT:
1517 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1518 if (!rect) return -1;
1519 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1520 *plparam = (LPARAM)SEGPTR_GET(rect);
1522 *pmsg16 = LB_GETITEMRECT16;
1524 case LB_GETSELITEMS:
1527 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1528 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1529 + sizeof(LPARAM)))) return -1;
1530 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1531 *plparam = (LPARAM)SEGPTR_GET(items);
1533 *pmsg16 = LB_GETSELITEMS16;
1535 case LB_SETTABSTOPS:
1540 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1541 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1542 + sizeof(LPARAM)))) return -1;
1543 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1544 *plparam = (LPARAM)SEGPTR_GET(stops);
1547 *pmsg16 = LB_SETTABSTOPS16;
1550 case CB_GETDROPPEDCONTROLRECT:
1553 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1554 if (!rect) return -1;
1555 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1556 *plparam = (LPARAM)SEGPTR_GET(rect);
1558 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1562 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1563 *pmsg16 = LB_GETTEXT16;
1567 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1568 *pmsg16 = CB_GETLBTEXT16;
1573 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
1574 *pmsg16 = EM_SETSEL16;
1581 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1585 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1587 case WM_CTLCOLORMSGBOX:
1588 case WM_CTLCOLOREDIT:
1589 case WM_CTLCOLORLISTBOX:
1590 case WM_CTLCOLORBTN:
1591 case WM_CTLCOLORDLG:
1592 case WM_CTLCOLORSCROLLBAR:
1593 case WM_CTLCOLORSTATIC:
1594 *pmsg16 = WM_CTLCOLOR;
1595 *plparam = MAKELPARAM( (HWND16)*plparam,
1596 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1598 case WM_COMPAREITEM:
1600 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
1601 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1602 if (!cis) return -1;
1603 cis->CtlType = (UINT16)cis32->CtlType;
1604 cis->CtlID = (UINT16)cis32->CtlID;
1605 cis->hwndItem = (HWND16)cis32->hwndItem;
1606 cis->itemID1 = (UINT16)cis32->itemID1;
1607 cis->itemData1 = cis32->itemData1;
1608 cis->itemID2 = (UINT16)cis32->itemID2;
1609 cis->itemData2 = cis32->itemData2;
1610 *plparam = (LPARAM)SEGPTR_GET(cis);
1615 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
1616 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1617 if (!dis) return -1;
1618 dis->CtlType = (UINT16)dis32->CtlType;
1619 dis->CtlID = (UINT16)dis32->CtlID;
1620 dis->itemID = (UINT16)dis32->itemID;
1621 dis->hwndItem = (HWND16)dis32->hwndItem;
1622 dis->itemData = dis32->itemData;
1623 *plparam = (LPARAM)SEGPTR_GET(dis);
1628 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
1629 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1630 if (!dis) return -1;
1631 dis->CtlType = (UINT16)dis32->CtlType;
1632 dis->CtlID = (UINT16)dis32->CtlID;
1633 dis->itemID = (UINT16)dis32->itemID;
1634 dis->itemAction = (UINT16)dis32->itemAction;
1635 dis->itemState = (UINT16)dis32->itemState;
1636 dis->hwndItem = (HWND16)dis32->hwndItem;
1637 dis->hDC = (HDC16)dis32->hDC;
1638 dis->itemData = dis32->itemData;
1639 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1640 *plparam = (LPARAM)SEGPTR_GET(dis);
1643 case WM_MEASUREITEM:
1645 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
1646 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1647 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1648 if (!mis) return -1;
1649 mis->CtlType = (UINT16)mis32->CtlType;
1650 mis->CtlID = (UINT16)mis32->CtlID;
1651 mis->itemID = (UINT16)mis32->itemID;
1652 mis->itemWidth = (UINT16)mis32->itemWidth;
1653 mis->itemHeight = (UINT16)mis32->itemHeight;
1654 mis->itemData = mis32->itemData;
1655 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1656 *plparam = (LPARAM)SEGPTR_GET(mis);
1659 case WM_GETMINMAXINFO:
1661 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1663 if (!mmi) return -1;
1664 STRUCT32_MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
1665 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1666 *plparam = (LPARAM)SEGPTR_GET(mmi);
1672 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1673 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1674 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1675 *plparam = (LPARAM)SEGPTR_GET(str);
1680 MDICREATESTRUCT16 *cs;
1681 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
1684 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1685 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1686 name = SEGPTR_STRDUP( cs32->szTitle );
1687 cls = SEGPTR_STRDUP( cs32->szClass );
1688 cs->szTitle = SEGPTR_GET(name);
1689 cs->szClass = SEGPTR_GET(cls);
1690 *plparam = (LPARAM)SEGPTR_GET(cs);
1693 case WM_MDIGETACTIVE:
1696 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1697 (HMENU16)LOWORD(*plparam) );
1698 *pwparam16 = (*plparam == 0);
1702 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1704 case WM_MDIACTIVATE:
1706 WND *tempWnd = WIN_FindWndPtr(hwnd);
1707 if( WIDGETS_IsControl(tempWnd, BIC32_MDICLIENT) )
1709 *pwparam16 = (HWND)wParam32;
1714 *pwparam16 = ((HWND)*plparam == hwnd);
1715 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1716 (HWND16)LOWORD(wParam32) );
1718 WIN_ReleaseWndPtr(tempWnd);
1723 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
1724 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1727 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1731 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1732 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1733 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1738 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1739 nc->lppos = SEGPTR_GET(wp);
1741 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1742 *plparam = (LPARAM)SEGPTR_GET(nc);
1749 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
1752 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1753 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1754 name = SEGPTR_STRDUP( cs32->lpszName );
1755 cls = SEGPTR_STRDUP( cs32->lpszClass );
1756 cs->lpszName = SEGPTR_GET(name);
1757 cs->lpszClass = SEGPTR_GET(cls);
1758 *plparam = (LPARAM)SEGPTR_GET(cs);
1761 case WM_PARENTNOTIFY:
1762 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1763 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1764 /* else nothing to do */
1767 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
1771 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1772 if (!str) return -1;
1773 *plparam = (LPARAM)SEGPTR_GET(str);
1776 case WM_WINDOWPOSCHANGING:
1777 case WM_WINDOWPOSCHANGED:
1779 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1782 STRUCT32_WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
1783 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1784 *plparam = (LPARAM)SEGPTR_GET(wp);
1789 LPMSG msg32 = (LPMSG) *plparam;
1790 LPMSG16 msg16 = (LPMSG16) SEGPTR_NEW( MSG16 );
1792 if (!msg16) return -1;
1793 msg16->hwnd = msg32->hwnd;
1794 msg16->lParam = msg32->lParam;
1795 msg16->time = msg32->time;
1796 CONV_POINT32TO16(&msg32->pt,&msg16->pt);
1797 /* this is right, right? */
1798 if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
1799 &msg16->message,&msg16->wParam, &msg16->lParam)<0) {
1800 SEGPTR_FREE( msg16 );
1803 *plparam = (LPARAM)SEGPTR_GET(msg16);
1808 case WM_ACTIVATEAPP:
1810 *plparam = (LPARAM)THREAD_IdToTHDB((DWORD) *plparam)->teb.htask16;
1813 case WM_ASKCBFORMATNAME:
1814 case WM_DEVMODECHANGE:
1815 case WM_PAINTCLIPBOARD:
1816 case WM_SIZECLIPBOARD:
1817 case WM_WININICHANGE:
1818 FIXME_(msg)("message %04x needs translation\n", msg32 );
1820 default: /* No translation needed */
1826 /**********************************************************************
1827 * WINPROC_UnmapMsg32ATo16
1829 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1831 void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1840 case LB_FINDSTRINGEXACT:
1841 case LB_INSERTSTRING:
1842 case LB_SELECTSTRING:
1843 case LB_SETTABSTOPS:
1846 case CB_FINDSTRINGEXACT:
1847 case CB_INSERTSTRING:
1848 case CB_SELECTSTRING:
1850 case WM_COMPAREITEM:
1854 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1857 case CB_GETDROPPEDCONTROLRECT:
1858 case LB_GETITEMRECT:
1860 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1861 p16->lParam = *(LPARAM *)(rect + 1);
1862 CONV_RECT16TO32( rect, (RECT *)(p16->lParam));
1863 SEGPTR_FREE( rect );
1866 case LB_GETSELITEMS:
1869 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1870 p16->lParam = *((LPARAM *)items - 1);
1871 for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
1872 SEGPTR_FREE( (LPARAM *)items - 1 );
1878 *((LPUINT)(wParam)) = LOWORD(p16->lResult);
1880 *((LPUINT)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1885 UnMapLS( (SEGPTR)(p16->lParam) );
1888 case WM_MEASUREITEM:
1890 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1891 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
1892 mis32->itemWidth = mis->itemWidth;
1893 mis32->itemHeight = mis->itemHeight;
1897 case WM_GETMINMAXINFO:
1899 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1900 p16->lParam = *(LPARAM *)(mmi + 1);
1901 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
1907 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1908 p16->lParam = *((LPARAM *)str - 1);
1909 lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
1910 SEGPTR_FREE( (LPARAM *)str - 1 );
1915 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1916 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1917 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1921 case WM_MDIGETACTIVE:
1922 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
1923 p16->lResult = (HWND)LOWORD(p16->lResult);
1927 NCCALCSIZE_PARAMS *nc32;
1928 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
1929 p16->lParam = *(LPARAM *)(nc + 1);
1930 nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
1931 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1934 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1935 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1936 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1938 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1946 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1947 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1948 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1952 case WM_WINDOWPOSCHANGING:
1953 case WM_WINDOWPOSCHANGED:
1955 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
1956 p16->lParam = *(LPARAM *)(wp + 1);
1957 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
1962 UnMapLS(p16->lParam);
1967 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(p16->lParam);
1969 msgp16.wParam=msg16->wParam;
1970 msgp16.lParam=msg16->lParam;
1971 WINPROC_UnmapMsg32ATo16(((LPMSG)lParam)->hwnd, ((LPMSG)lParam)->message,
1972 ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam,
1981 /**********************************************************************
1982 * WINPROC_MapMsg32WTo16
1984 * Map a message from 32-bit Unicode to 16-bit.
1985 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1987 INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1988 UINT16 *pmsg16, WPARAM16 *pwparam16,
1995 case LB_FINDSTRINGEXACT:
1996 case LB_INSERTSTRING:
1997 case LB_SELECTSTRING:
2001 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2002 if (!str) return -1;
2003 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2004 *plparam = (LPARAM)SEGPTR_GET(str);
2006 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2011 case CB_FINDSTRINGEXACT:
2012 case CB_INSERTSTRING:
2013 case CB_SELECTSTRING:
2016 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2017 if (!str) return -1;
2018 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2019 *plparam = (LPARAM)SEGPTR_GET(str);
2021 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2028 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2031 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
2032 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2033 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
2034 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
2035 cs->lpszName = SEGPTR_GET(name);
2036 cs->lpszClass = SEGPTR_GET(cls);
2037 *pmsg16 = (UINT16)msg32;
2038 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2039 *plparam = (LPARAM)SEGPTR_GET(cs);
2044 MDICREATESTRUCT16 *cs;
2045 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2048 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
2049 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2050 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
2051 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
2052 cs->szTitle = SEGPTR_GET(name);
2053 cs->szClass = SEGPTR_GET(cls);
2054 *pmsg16 = (UINT16)msg32;
2055 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2056 *plparam = (LPARAM)SEGPTR_GET(cs);
2061 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2062 if (!str) return -1;
2063 *pmsg16 = (UINT16)msg32;
2064 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2065 *plparam = (LPARAM)SEGPTR_GET(str);
2068 default: /* No Unicode translation needed */
2069 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2070 pwparam16, plparam );
2075 /**********************************************************************
2076 * WINPROC_UnmapMsg32WTo16
2078 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2080 void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2087 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
2088 p16->lParam = *((LPARAM *)str - 1);
2089 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
2090 SEGPTR_FREE( (LPARAM *)str - 1 );
2094 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2100 /**********************************************************************
2101 * WINPROC_CallProc32ATo32W
2103 * Call a window procedure, translating args from Ansi to Unicode.
2105 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
2106 UINT msg, WPARAM wParam,
2111 if (WINPROC_MapMsg32ATo32W( hwnd, msg, wParam, &lParam ) == -1) return 0;
2112 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2113 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
2118 /**********************************************************************
2119 * WINPROC_CallProc32WTo32A
2121 * Call a window procedure, translating args from Unicode to Ansi.
2123 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
2124 UINT msg, WPARAM wParam,
2129 if (WINPROC_MapMsg32WTo32A( hwnd, msg, wParam, &lParam ) == -1) return 0;
2130 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2131 WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
2136 /**********************************************************************
2137 * WINPROC_CallProc16To32A
2139 * Call a 32-bit window procedure, translating the 16-bit args.
2141 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
2142 WPARAM16 wParam, LPARAM lParam,
2149 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2151 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2152 return WINPROC_UnmapMsg16To32A( hwnd, msg32, wParam32, lParam, result );
2156 /**********************************************************************
2157 * WINPROC_CallProc16To32W
2159 * Call a 32-bit window procedure, translating the 16-bit args.
2161 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
2162 WPARAM16 wParam, LPARAM lParam,
2169 if (WINPROC_MapMsg16To32W( hwnd, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2172 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2174 return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result );
2178 /**********************************************************************
2179 * WINPROC_CallProc32ATo16
2181 * Call a 16-bit window procedure, translating the 32-bit args.
2183 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
2184 UINT msg, WPARAM wParam,
2190 mp16.lParam = lParam;
2191 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
2192 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
2194 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
2195 mp16.wParam, mp16.lParam );
2196 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
2197 return mp16.lResult;
2201 /**********************************************************************
2202 * WINPROC_CallProc32WTo16
2204 * Call a 16-bit window procedure, translating the 32-bit args.
2206 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
2207 UINT msg, WPARAM wParam,
2213 mp16.lParam = lParam;
2214 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
2215 &mp16.lParam ) == -1)
2217 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
2218 mp16.wParam, mp16.lParam );
2219 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
2220 return mp16.lResult;
2224 /**********************************************************************
2225 * CallWindowProc16 (USER.122)
2227 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
2228 WPARAM16 wParam, LPARAM lParam )
2230 WINDOWPROC *proc = WINPROC_GetPtr( func );
2233 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
2236 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
2237 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
2243 if (!proc->thunk.t_from32.proc) return 0;
2244 return Callbacks->CallWndProc( proc->thunk.t_from32.proc,
2245 hwnd, msg, wParam, lParam );
2247 if (!proc->thunk.t_from16.proc) return 0;
2248 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
2249 proc->thunk.t_from16.proc );
2251 if (!proc->thunk.t_from16.proc) return 0;
2252 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
2253 proc->thunk.t_from16.proc );
2255 WARN_(relay)("Invalid proc %p\n", proc );
2261 /**********************************************************************
2262 * CallWindowProc32A (USER32.18)
2264 * The CallWindowProc() function invokes the windows procedure _func_,
2265 * with _hwnd_ as the target window, the message specified by _msg_, and
2266 * the message parameters _wParam_ and _lParam_.
2268 * Some kinds of argument conversion may be done, I'm not sure what.
2270 * CallWindowProc() may be used for windows subclassing. Use
2271 * SetWindowLong() to set a new windows procedure for windows of the
2272 * subclass, and handle subclassed messages in the new windows
2273 * procedure. The new windows procedure may then use CallWindowProc()
2274 * with _func_ set to the parent class's windows procedure to dispatch
2275 * the message to the superclass.
2279 * The return value is message dependent.
2285 LRESULT WINAPI CallWindowProcA(
2286 WNDPROC func, /* window procedure */
2287 HWND hwnd, /* target window */
2288 UINT msg, /* message */
2289 WPARAM wParam, /* message dependent parameter */
2290 LPARAM lParam /* message dependent parameter */
2292 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2294 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2297 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2298 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2304 if (!proc->thunk.t_from32.proc) return 0;
2305 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2306 hwnd, msg, wParam, lParam );
2308 if (!proc->thunk.t_from16.proc) return 0;
2309 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2310 hwnd, msg, wParam, lParam );
2312 if (!proc->thunk.t_from16.proc) return 0;
2313 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2314 hwnd, msg, wParam, lParam );
2316 WARN_(relay)("Invalid proc %p\n", proc );
2322 /**********************************************************************
2323 * CallWindowProc32W (USER32.19)
2325 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
2326 WPARAM wParam, LPARAM lParam )
2328 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2330 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2333 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2334 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2340 if (!proc->thunk.t_from32.proc) return 0;
2341 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2342 hwnd, msg, wParam, lParam );
2344 if (!proc->thunk.t_from16.proc) return 0;
2345 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2346 hwnd, msg, wParam, lParam );
2348 if (!proc->thunk.t_from16.proc) return 0;
2349 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2350 hwnd, msg, wParam, lParam );
2352 WARN_(relay)("Invalid proc %p\n", proc );