Fixes crash when running without external shell32.dll.
[wine/multimedia.git] / windows / winproc.c
blob8ab0f546fc748242d4ec7ba2543db3a928f9b911
1 /*
2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
6 */
8 #include "windows.h"
9 #include "callback.h"
10 #include "heap.h"
11 #include "selectors.h"
12 #include "struct32.h"
13 #include "win.h"
14 #include "winproc.h"
15 #include "debug.h"
16 #include "spy.h"
17 #include "commctrl.h"
19 /* Window procedure 16-to-32-bit thunk,
20 * see BuildSpec16Files() in tools/build.c */
22 typedef struct
24 BYTE popl_eax; /* popl %eax (return address) */
25 BYTE pushl_func; /* pushl $proc */
26 WNDPROC32 proc WINE_PACKED;
27 BYTE pushl_eax; /* pushl %eax */
28 WORD pushw_bp WINE_PACKED; /* pushw %bp */
29 BYTE pushl_thunk; /* pushl $thunkfrom16 */
30 void (*thunk32)() WINE_PACKED;
31 BYTE lcall; /* lcall cs:relay */
32 void (*relay)() WINE_PACKED; /* WINPROC_CallProc16To32A/W() */
33 WORD cs WINE_PACKED;
34 } WINPROC_THUNK_FROM16;
36 /* Window procedure 32-to-16-bit thunk,
37 * see BuildSpec32Files() in tools/build.c */
39 typedef struct
41 BYTE popl_eax; /* popl %eax (return address) */
42 BYTE pushl_func; /* pushl $proc */
43 WNDPROC16 proc WINE_PACKED;
44 BYTE pushl_eax; /* pushl %eax */
45 BYTE jmp; /* jmp relay (relative jump)*/
46 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
47 } WINPROC_THUNK_FROM32;
49 /* Simple jmp to call 32-bit procedure directly */
50 typedef struct
52 BYTE jmp; /* jmp proc (relative jump) */
53 WNDPROC32 proc WINE_PACKED;
54 } WINPROC_JUMP;
56 typedef union
58 WINPROC_THUNK_FROM16 t_from16;
59 WINPROC_THUNK_FROM32 t_from32;
60 } WINPROC_THUNK;
62 typedef struct tagWINDOWPROC
64 WINPROC_THUNK thunk; /* Thunk */
65 WINPROC_JUMP jmp; /* Jump */
66 struct tagWINDOWPROC *next; /* Next window proc */
67 UINT32 magic; /* Magic number */
68 WINDOWPROCTYPE type; /* Function type */
69 WINDOWPROCUSER user; /* Function user */
70 } WINDOWPROC;
72 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
74 #define WINPROC_THUNKPROC(pproc) \
75 (((pproc)->type == WIN_PROC_16) ? \
76 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
77 (WNDPROC16)((pproc)->thunk.t_from16.proc))
79 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
80 UINT32 msg, WPARAM32 wParam,
81 LPARAM lParam );
82 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
83 UINT32 msg, WPARAM32 wParam,
84 LPARAM lParam );
85 static LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
86 WPARAM16 wParam, LPARAM lParam,
87 WNDPROC32 func );
88 static LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
89 WPARAM16 wParam, LPARAM lParam,
90 WNDPROC32 func );
92 static HANDLE32 WinProcHeap;
95 /**********************************************************************
96 * WINPROC_Init
98 BOOL32 WINPROC_Init(void)
100 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
101 if (!WinProcHeap)
103 WARN(relay, "Unable to create winproc heap\n" );
104 return FALSE;
106 return TRUE;
110 /**********************************************************************
111 * WINPROC_CallWndProc32
113 * Call a 32-bit WndProc.
115 static LRESULT WINPROC_CallWndProc32( WNDPROC32 proc, HWND32 hwnd, UINT32 msg,
116 WPARAM32 wParam, LPARAM lParam )
118 TRACE(relay, "(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
119 proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
120 return proc( hwnd, msg, wParam, lParam );
124 /**********************************************************************
125 * WINPROC_GetPtr
127 * Return a pointer to the win proc.
129 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
131 BYTE *ptr;
132 WINDOWPROC *proc;
134 /* Check for a linear pointer */
136 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
138 ptr = (BYTE *)handle;
139 /* First check if it is the jmp address */
140 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
141 (int)&((WINDOWPROC *)0)->thunk;
142 /* Now it must be the thunk address */
143 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
144 /* Now we have a pointer to the WINDOWPROC struct */
145 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
146 return (WINDOWPROC *)ptr;
149 /* Check for a segmented pointer */
151 if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
153 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
154 if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
155 /* It must be the thunk address */
156 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
157 /* Now we have a pointer to the WINDOWPROC struct */
158 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
159 return (WINDOWPROC *)ptr;
162 return NULL;
166 /**********************************************************************
167 * WINPROC_AllocWinProc
169 * Allocate a new window procedure.
171 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
172 WINDOWPROCUSER user )
174 WINDOWPROC *proc, *oldproc;
176 /* Allocate a window procedure */
178 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
180 /* Check if the function is already a win proc */
182 if ((oldproc = WINPROC_GetPtr( func )))
184 *proc = *oldproc;
186 else
188 switch(type)
190 case WIN_PROC_16:
191 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
192 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
193 proc->thunk.t_from32.proc = func;
194 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
195 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
196 proc->thunk.t_from32.relay = /* relative jump */
197 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
198 (DWORD)(&proc->thunk.t_from32.relay + 1));
199 break;
200 case WIN_PROC_32A:
201 case WIN_PROC_32W:
202 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
203 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
204 proc->thunk.t_from16.proc = (FARPROC32)func;
205 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
206 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
207 proc->thunk.t_from16.pushl_thunk = 0x68; /* pushl $thunkfrom16 */
208 proc->thunk.t_from16.thunk32 = (type == WIN_PROC_32A) ?
209 (void(*)())WINPROC_CallProc16To32A :
210 (void(*)())WINPROC_CallProc16To32W;
211 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:relay */
212 proc->thunk.t_from16.relay = Callbacks->CallFrom16WndProc;
213 GET_CS(proc->thunk.t_from16.cs);
214 proc->jmp.jmp = 0xe9;
215 /* Fixup relative jump */
216 proc->jmp.proc = (WNDPROC32)((DWORD)func -
217 (DWORD)(&proc->jmp.proc + 1));
218 break;
219 default:
220 /* Should not happen */
221 break;
223 proc->magic = WINPROC_MAGIC;
224 proc->type = type;
225 proc->user = user;
227 proc->next = NULL;
228 TRACE(win, "(%08x,%d): returning %08x\n",
229 (UINT32)func, type, (UINT32)proc );
230 return proc;
234 /**********************************************************************
235 * WINPROC_GetProc
237 * Get a window procedure pointer that can be passed to the Windows program.
239 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
241 if (!proc) return NULL;
242 if (type == WIN_PROC_16) /* We want a 16:16 address */
244 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
245 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
246 else
247 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
248 &((WINDOWPROC *)proc)->thunk );
250 else /* We want a 32-bit address */
252 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
253 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
254 else if (type != ((WINDOWPROC *)proc)->type)
255 /* Have to return the jmp address if types don't match */
256 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
257 else
258 /* Some Win16 programs want to get back the proc they set */
259 return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc;
264 /**********************************************************************
265 * WINPROC_SetProc
267 * Set the window procedure for a window or class. There are
268 * three tree classes of winproc callbacks:
270 * 1) class -> wp - not subclassed
271 * class -> wp -> wp -> wp -> wp - SetClassLong()
272 * / /
273 * 2) window -' / - not subclassed
274 * window -> wp -> wp ' - SetWindowLong()
276 * 3) timer -> wp - SetTimer()
278 * Initially, winproc of the window points to the current winproc
279 * thunk of its class. Subclassing prepends a new thunk to the
280 * window winproc chain at the head of the list. Thus, window thunk
281 * list includes class thunks and the latter are preserved when the
282 * window is destroyed.
285 BOOL32 WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
286 WINDOWPROCTYPE type, WINDOWPROCUSER user )
288 BOOL32 bRecycle = FALSE;
289 WINDOWPROC *proc, **ppPrev;
291 /* Check if function is already in the list */
293 ppPrev = (WINDOWPROC **)pFirst;
294 proc = WINPROC_GetPtr( func );
295 while (*ppPrev)
297 if (proc)
299 if (*ppPrev == proc)
301 if ((*ppPrev)->user != user)
303 /* terminal thunk is being restored */
305 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
306 *(WINDOWPROC **)pFirst = *ppPrev;
307 return TRUE;
309 bRecycle = TRUE;
310 break;
313 else
315 if (((*ppPrev)->type == type) &&
316 (func == WINPROC_THUNKPROC(*ppPrev)))
318 bRecycle = TRUE;
319 break;
323 /* WPF_CLASS thunk terminates window thunk list */
324 if ((*ppPrev)->user != user) break;
325 ppPrev = &(*ppPrev)->next;
328 if (bRecycle)
330 /* Extract this thunk from the list */
331 proc = *ppPrev;
332 *ppPrev = proc->next;
334 else /* Allocate a new one */
336 if (proc) /* Was already a win proc */
338 type = proc->type;
339 func = WINPROC_THUNKPROC(proc);
341 proc = WINPROC_AllocWinProc( func, type, user );
342 if (!proc) return FALSE;
345 /* Add the win proc at the head of the list */
347 TRACE(win, "(%08x,%08x,%d): res=%08x\n",
348 (UINT32)*pFirst, (UINT32)func, type, (UINT32)proc );
349 proc->next = *(WINDOWPROC **)pFirst;
350 *(WINDOWPROC **)pFirst = proc;
351 return TRUE;
355 /**********************************************************************
356 * WINPROC_FreeProc
358 * Free a list of win procs.
360 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
362 while (proc)
364 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
365 if (((WINDOWPROC *)proc)->user != user) break;
366 TRACE(win, "freeing %08x\n", (UINT32)proc);
367 HeapFree( WinProcHeap, 0, proc );
368 proc = next;
373 /**********************************************************************
374 * WINPROC_GetProcType
376 * Return the window procedure type.
378 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
380 if (!proc ||
381 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
382 return WIN_PROC_INVALID;
383 return ((WINDOWPROC *)proc)->type;
385 /**********************************************************************
386 * WINPROC_TestCBForStr
388 * Return TRUE if the lparam is a string
390 BOOL32 WINPROC_TestCBForStr ( HWND32 hwnd )
391 { WND * wnd = WIN_FindWndPtr(hwnd);
392 return ( !(LOWORD(wnd->dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
393 (LOWORD(wnd->dwStyle) & CBS_HASSTRINGS) );
395 /**********************************************************************
396 * WINPROC_TestLBForStr
398 * Return TRUE if the lparam is a string
400 BOOL32 WINPROC_TestLBForStr ( HWND32 hwnd )
401 { WND * wnd = WIN_FindWndPtr(hwnd);
402 return ( !(LOWORD(wnd->dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) ||
403 (LOWORD(wnd->dwStyle) & LBS_HASSTRINGS) );
405 /**********************************************************************
406 * WINPROC_MapMsg32ATo32W
408 * Map a message from Ansi to Unicode.
409 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
411 * FIXME:
412 * WM_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR, WM_SYSDEADCHAR
414 * FIXME:
415 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
416 * the first four bytes are the handle of the icon
417 * when the WM_SETTEXT message has been used to set the icon
419 INT32 WINPROC_MapMsg32ATo32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
421 switch(msg)
423 case WM_GETTEXT:
425 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
426 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
427 if (!ptr) return -1;
428 *ptr++ = *plparam; /* Store previous lParam */
429 *plparam = (LPARAM)ptr;
431 return 1;
433 case WM_SETTEXT:
434 case CB_DIR32:
435 case CB_FINDSTRING32:
436 case CB_FINDSTRINGEXACT32:
437 case CB_SELECTSTRING32:
438 case LB_DIR32:
439 case LB_ADDFILE32:
440 case LB_FINDSTRING32:
441 case LB_SELECTSTRING32:
442 case EM_REPLACESEL32:
443 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
444 return (*plparam ? 1 : -1);
446 case WM_NCCREATE:
447 case WM_CREATE:
449 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
450 sizeof(*cs) );
451 if (!cs) return -1;
452 *cs = *(CREATESTRUCT32W *)*plparam;
453 if (HIWORD(cs->lpszName))
454 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
455 (LPCSTR)cs->lpszName );
456 if (HIWORD(cs->lpszClass))
457 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
458 (LPCSTR)cs->lpszClass );
459 *plparam = (LPARAM)cs;
461 return 1;
462 case WM_MDICREATE:
464 MDICREATESTRUCT32W *cs =
465 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
466 if (!cs) return -1;
467 *cs = *(MDICREATESTRUCT32W *)*plparam;
468 if (HIWORD(cs->szClass))
469 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
470 (LPCSTR)cs->szClass );
471 if (HIWORD(cs->szTitle))
472 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
473 (LPCSTR)cs->szTitle );
474 *plparam = (LPARAM)cs;
476 return 1;
478 /* Listbox */
479 case LB_ADDSTRING32:
480 case LB_INSERTSTRING32:
481 if ( WINPROC_TestLBForStr( hwnd ))
482 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
483 return (*plparam ? 1 : -1);
485 case LB_GETTEXT32: /* fixme: fixed sized buffer */
486 { if ( WINPROC_TestLBForStr( hwnd ))
487 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
488 if (!ptr) return -1;
489 *ptr++ = *plparam; /* Store previous lParam */
490 *plparam = (LPARAM)ptr;
493 return 1;
495 /* Combobox */
496 case CB_ADDSTRING32:
497 case CB_INSERTSTRING32:
498 if ( WINPROC_TestCBForStr( hwnd ))
499 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
500 return (*plparam ? 1 : -1);
502 case CB_GETLBTEXT32: /* fixme: fixed sized buffer */
503 { if ( WINPROC_TestCBForStr( hwnd ))
504 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
505 if (!ptr) return -1;
506 *ptr++ = *plparam; /* Store previous lParam */
507 *plparam = (LPARAM)ptr;
510 return 1;
512 /* Multiline edit */
513 case EM_GETLINE32:
514 { WORD len = (WORD)*plparam;
515 LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
516 if (!ptr) return -1;
517 *ptr++ = *plparam; /* Store previous lParam */
518 (WORD)*ptr = len; /* Store the lenght */
519 *plparam = (LPARAM)ptr;
521 return 1;
523 case WM_ASKCBFORMATNAME:
524 case WM_DEVMODECHANGE:
525 case WM_PAINTCLIPBOARD:
526 case WM_SIZECLIPBOARD:
527 case WM_WININICHANGE:
528 case EM_SETPASSWORDCHAR32:
529 FIXME(msg, "message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg), msg );
530 return -1;
531 default: /* No translation needed */
532 return 0;
537 /**********************************************************************
538 * WINPROC_UnmapMsg32ATo32W
540 * Unmap a message that was mapped from Ansi to Unicode.
542 void WINPROC_UnmapMsg32ATo32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam )
544 switch(msg)
546 case WM_GETTEXT:
548 LPARAM *ptr = (LPARAM *)lParam - 1;
549 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)lParam, wParam );
550 HeapFree( SystemHeap, 0, ptr );
552 break;
554 case WM_NCCREATE:
555 case WM_CREATE:
557 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
558 if (HIWORD(cs->lpszName))
559 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
560 if (HIWORD(cs->lpszClass))
561 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
562 HeapFree( SystemHeap, 0, cs );
564 break;
566 case WM_MDICREATE:
568 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
569 if (HIWORD(cs->szTitle))
570 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
571 if (HIWORD(cs->szClass))
572 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
573 HeapFree( SystemHeap, 0, cs );
575 break;
577 case WM_SETTEXT:
578 case CB_DIR32:
579 case CB_FINDSTRING32:
580 case CB_FINDSTRINGEXACT32:
581 case CB_SELECTSTRING32:
582 case LB_DIR32:
583 case LB_ADDFILE32:
584 case LB_FINDSTRING32:
585 case LB_SELECTSTRING32:
586 case EM_REPLACESEL32:
587 HeapFree( SystemHeap, 0, (void *)lParam );
588 break;
590 /* Listbox */
591 case LB_ADDSTRING32:
592 case LB_INSERTSTRING32:
593 if ( WINPROC_TestLBForStr( hwnd ))
594 HeapFree( SystemHeap, 0, (void *)lParam );
595 break;
597 case LB_GETTEXT32:
598 { if ( WINPROC_TestLBForStr( hwnd ))
599 { LPARAM *ptr = (LPARAM *)lParam - 1;
600 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
601 HeapFree( SystemHeap, 0, ptr );
604 break;
606 /* Combobox */
607 case CB_ADDSTRING32:
608 case CB_INSERTSTRING32:
609 if ( WINPROC_TestCBForStr( hwnd ))
610 HeapFree( SystemHeap, 0, (void *)lParam );
611 break;
613 case CB_GETLBTEXT32:
614 { if ( WINPROC_TestCBForStr( hwnd ))
615 { LPARAM *ptr = (LPARAM *)lParam - 1;
616 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
617 HeapFree( SystemHeap, 0, ptr );
620 break;
622 /* Multiline edit */
623 case EM_GETLINE32:
624 { LPARAM *ptr = (LPARAM *)lParam - 1; /* get the old lParam */
625 WORD len = *(WORD *)ptr;
626 lstrcpynWtoA( ((LPSTR)*ptr)+2, ((LPWSTR)(lParam + 1))+1, len );
627 HeapFree( SystemHeap, 0, ptr );
629 break;
634 /**********************************************************************
635 * WINPROC_MapMsg32WTo32A
637 * Map a message from Unicode to Ansi.
638 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
640 INT32 WINPROC_MapMsg32WTo32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
641 { switch(msg)
643 case WM_GETTEXT:
645 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
646 wParam + sizeof(LPARAM) );
647 if (!ptr) return -1;
648 *ptr++ = *plparam; /* Store previous lParam */
649 *plparam = (LPARAM)ptr;
651 return 1;
653 case WM_SETTEXT:
654 case CB_DIR32:
655 case CB_FINDSTRING32:
656 case CB_FINDSTRINGEXACT32:
657 case CB_SELECTSTRING32:
658 case LB_DIR32:
659 case LB_ADDFILE32:
660 case LB_FINDSTRING32:
661 case LB_SELECTSTRING32:
662 case EM_REPLACESEL32:
663 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
664 return (*plparam ? 1 : -1);
666 case WM_NCCREATE:
667 case WM_CREATE:
669 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
670 sizeof(*cs) );
671 if (!cs) return -1;
672 *cs = *(CREATESTRUCT32A *)*plparam;
673 if (HIWORD(cs->lpszName))
674 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
675 (LPCWSTR)cs->lpszName );
676 if (HIWORD(cs->lpszClass))
677 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
678 (LPCWSTR)cs->lpszClass);
679 *plparam = (LPARAM)cs;
681 return 1;
682 case WM_MDICREATE:
684 MDICREATESTRUCT32A *cs =
685 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
686 if (!cs) return -1;
687 *cs = *(MDICREATESTRUCT32A *)*plparam;
688 if (HIWORD(cs->szTitle))
689 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
690 (LPCWSTR)cs->szTitle );
691 if (HIWORD(cs->szClass))
692 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
693 (LPCWSTR)cs->szClass );
694 *plparam = (LPARAM)cs;
696 return 1;
698 /* Listbox */
699 case LB_ADDSTRING32:
700 case LB_INSERTSTRING32:
701 if ( WINPROC_TestLBForStr( hwnd ))
702 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
703 return (*plparam ? 1 : -1);
705 case LB_GETTEXT32: /* fixme: fixed sized buffer */
706 { if ( WINPROC_TestLBForStr( hwnd ))
707 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
708 if (!ptr) return -1;
709 *ptr++ = *plparam; /* Store previous lParam */
710 *plparam = (LPARAM)ptr;
713 return 1;
715 /* Combobox */
716 case CB_ADDSTRING32:
717 case CB_INSERTSTRING32:
718 if ( WINPROC_TestCBForStr( hwnd ))
719 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
720 return (*plparam ? 1 : -1);
722 case CB_GETLBTEXT32: /* fixme: fixed sized buffer */
723 { if ( WINPROC_TestCBForStr( hwnd ))
724 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
725 if (!ptr) return -1;
726 *ptr++ = *plparam; /* Store previous lParam */
727 *plparam = (LPARAM)ptr;
730 return 1;
732 /* Multiline edit */
733 case EM_GETLINE32:
734 { WORD len = (WORD)*plparam;
735 LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
736 if (!ptr) return -1;
737 *ptr++ = *plparam; /* Store previous lParam */
738 (WORD)*ptr = len; /* Store the lenght */
739 *plparam = (LPARAM)ptr;
741 return 1;
743 case WM_ASKCBFORMATNAME:
744 case WM_DEVMODECHANGE:
745 case WM_PAINTCLIPBOARD:
746 case WM_SIZECLIPBOARD:
747 case WM_WININICHANGE:
748 case EM_SETPASSWORDCHAR32:
749 FIXME(msg, "message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg),msg );
750 return -1;
751 default: /* No translation needed */
752 return 0;
757 /**********************************************************************
758 * WINPROC_UnmapMsg32WTo32A
760 * Unmap a message that was mapped from Unicode to Ansi.
762 void WINPROC_UnmapMsg32WTo32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam )
764 switch(msg)
766 case WM_GETTEXT:
768 LPARAM *ptr = (LPARAM *)lParam - 1;
769 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)lParam, wParam );
770 HeapFree( SystemHeap, 0, ptr );
772 break;
774 case WM_SETTEXT:
775 case CB_DIR32:
776 case CB_FINDSTRING32:
777 case CB_FINDSTRINGEXACT32:
778 case CB_SELECTSTRING32:
779 case LB_DIR32:
780 case LB_ADDFILE32:
781 case LB_FINDSTRING32:
782 case LB_SELECTSTRING32:
783 case EM_REPLACESEL32:
784 HeapFree( SystemHeap, 0, (void *)lParam );
785 break;
787 case WM_NCCREATE:
788 case WM_CREATE:
790 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
791 if (HIWORD(cs->lpszName))
792 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
793 if (HIWORD(cs->lpszClass))
794 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
795 HeapFree( SystemHeap, 0, cs );
797 break;
799 case WM_MDICREATE:
801 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
802 if (HIWORD(cs->szTitle))
803 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
804 if (HIWORD(cs->szClass))
805 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
806 HeapFree( SystemHeap, 0, cs );
808 break;
810 /* Listbox */
811 case LB_ADDSTRING32:
812 case LB_INSERTSTRING32:
813 if ( WINPROC_TestLBForStr( hwnd ))
814 HeapFree( SystemHeap, 0, (void *)lParam );
815 break;
817 case LB_GETTEXT32:
818 { if ( WINPROC_TestLBForStr( hwnd ))
819 { LPARAM *ptr = (LPARAM *)lParam - 1;
820 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
821 HeapFree( SystemHeap, 0, ptr );
824 break;
826 /* Combobox */
827 case CB_ADDSTRING32:
828 case CB_INSERTSTRING32:
829 if ( WINPROC_TestCBForStr( hwnd ))
830 HeapFree( SystemHeap, 0, (void *)lParam );
831 break;
833 case CB_GETLBTEXT32:
834 { if ( WINPROC_TestCBForStr( hwnd ))
835 { LPARAM *ptr = (LPARAM *)lParam - 1;
836 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
837 HeapFree( SystemHeap, 0, ptr );
840 break;
842 /* Multiline edit */
843 case EM_GETLINE32:
844 { LPARAM *ptr = (LPARAM *)lParam - 1; /* get the old lParam */
845 WORD len = *(WORD *)ptr;
846 lstrcpynAtoW( ((LPWSTR)*ptr)+1, ((LPSTR)(lParam + 1))+2, len );
847 HeapFree( SystemHeap, 0, ptr );
849 break;
854 /**********************************************************************
855 * WINPROC_MapMsg16To32A
857 * Map a message from 16- to 32-bit Ansi.
858 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
860 INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
861 WPARAM32 *pwparam32, LPARAM *plparam )
863 *pmsg32 = (UINT32)msg16;
864 *pwparam32 = (WPARAM32)wParam16;
865 switch(msg16)
867 case WM_ACTIVATE:
868 case WM_CHARTOITEM:
869 case WM_COMMAND:
870 case WM_VKEYTOITEM:
871 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
872 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
873 return 0;
874 case WM_HSCROLL:
875 case WM_VSCROLL:
876 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
877 *plparam = (LPARAM)(HWND32)HIWORD(*plparam);
878 return 0;
879 case WM_CTLCOLOR:
880 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
881 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
882 *pwparam32 = (WPARAM32)(HDC32)wParam16;
883 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
884 return 0;
885 case WM_COMPAREITEM:
887 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
888 COMPAREITEMSTRUCT32 *cis = (COMPAREITEMSTRUCT32 *)
889 HeapAlloc(SystemHeap, 0, sizeof(*cis));
890 if (!cis) return -1;
891 cis->CtlType = cis16->CtlType;
892 cis->CtlID = cis16->CtlID;
893 cis->hwndItem = cis16->hwndItem;
894 cis->itemID1 = cis16->itemID1;
895 cis->itemData1 = cis16->itemData1;
896 cis->itemID2 = cis16->itemID2;
897 cis->itemData2 = cis16->itemData2;
898 cis->dwLocaleId = 0; /* FIXME */
899 *plparam = (LPARAM)cis;
901 return 1;
902 case WM_DELETEITEM:
904 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
905 DELETEITEMSTRUCT32 *dis = (DELETEITEMSTRUCT32 *)
906 HeapAlloc(SystemHeap, 0, sizeof(*dis));
907 if (!dis) return -1;
908 dis->CtlType = dis16->CtlType;
909 dis->CtlID = dis16->CtlID;
910 dis->hwndItem = dis16->hwndItem;
911 dis->itemData = dis16->itemData;
912 *plparam = (LPARAM)dis;
914 return 1;
915 case WM_MEASUREITEM:
917 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
918 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)
919 HeapAlloc(SystemHeap, 0,
920 sizeof(*mis) + sizeof(LPARAM));
921 if (!mis) return -1;
922 mis->CtlType = mis16->CtlType;
923 mis->CtlID = mis16->CtlID;
924 mis->itemID = mis16->itemID;
925 mis->itemWidth = mis16->itemWidth;
926 mis->itemHeight = mis16->itemHeight;
927 mis->itemData = mis16->itemData;
928 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
929 *plparam = (LPARAM)mis;
931 return 1;
932 case WM_DRAWITEM:
934 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
935 DRAWITEMSTRUCT32 *dis = (DRAWITEMSTRUCT32*)HeapAlloc(SystemHeap, 0,
936 sizeof(*dis));
937 if (!dis) return -1;
938 dis->CtlType = dis16->CtlType;
939 dis->CtlID = dis16->CtlID;
940 dis->itemID = dis16->itemID;
941 dis->itemAction = dis16->itemAction;
942 dis->itemState = dis16->itemState;
943 dis->hwndItem = dis16->hwndItem;
944 dis->hDC = dis16->hDC;
945 dis->itemData = dis16->itemData;
946 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
947 *plparam = (LPARAM)dis;
949 return 1;
950 case WM_GETMINMAXINFO:
952 MINMAXINFO32 *mmi = (MINMAXINFO32 *)HeapAlloc( SystemHeap, 0,
953 sizeof(*mmi) + sizeof(LPARAM));
954 if (!mmi) return -1;
955 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
956 mmi );
957 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
958 *plparam = (LPARAM)mmi;
960 return 1;
961 case WM_GETTEXT:
962 case WM_SETTEXT:
963 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
964 return 0;
965 case WM_MDICREATE:
967 MDICREATESTRUCT16 *cs16 =
968 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
969 MDICREATESTRUCT32A *cs =
970 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
971 sizeof(*cs) + sizeof(LPARAM) );
972 if (!cs) return -1;
973 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
974 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
975 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
976 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
977 *plparam = (LPARAM)cs;
979 return 1;
980 case WM_MDIGETACTIVE:
981 *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL32) );
982 return 1;
983 case WM_MDISETMENU:
984 if(wParam16==TRUE)
985 *pmsg32=WM_MDIREFRESHMENU;
986 *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
987 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
988 return 0;
989 case WM_MENUCHAR:
990 case WM_MENUSELECT:
991 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
992 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
993 return 0;
994 case WM_MDIACTIVATE:
995 if( *plparam )
997 *pwparam32 = (WPARAM32)(HWND32)HIWORD(*plparam);
998 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
1000 else /* message sent to MDI client */
1001 *pwparam32 = wParam16;
1002 return 0;
1003 case WM_NCCALCSIZE:
1005 NCCALCSIZE_PARAMS16 *nc16;
1006 NCCALCSIZE_PARAMS32 *nc;
1008 nc = (NCCALCSIZE_PARAMS32 *)HeapAlloc( SystemHeap, 0,
1009 sizeof(*nc) + sizeof(LPARAM) );
1010 if (!nc) return -1;
1011 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
1012 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
1013 if (wParam16)
1015 nc->lppos = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
1016 sizeof(*nc->lppos) );
1017 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
1018 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
1019 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
1021 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1022 *plparam = (LPARAM)nc;
1024 return 1;
1025 case WM_NCCREATE:
1026 case WM_CREATE:
1028 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1029 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
1030 sizeof(*cs) + sizeof(LPARAM) );
1031 if (!cs) return -1;
1032 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
1033 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1034 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1035 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1036 *plparam = (LPARAM)cs;
1038 return 1;
1039 case WM_PARENTNOTIFY:
1040 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1042 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1043 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
1045 return 0;
1046 case WM_WINDOWPOSCHANGING:
1047 case WM_WINDOWPOSCHANGED:
1049 WINDOWPOS32 *wp = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
1050 sizeof(*wp) + sizeof(LPARAM) );
1051 if (!wp) return -1;
1052 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
1053 wp );
1054 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1055 *plparam = (LPARAM)wp;
1057 return 1;
1058 case WM_GETDLGCODE:
1059 if (*plparam)
1061 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1062 LPMSG32 msg32 = (LPMSG32)HeapAlloc( SystemHeap, 0, sizeof(MSG32) );
1064 if (!msg32) return -1;
1065 msg32->hwnd = msg16->hwnd;
1066 msg32->lParam = msg16->lParam;
1067 msg32->time = msg16->time;
1068 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1069 /* this is right, right? */
1070 if (WINPROC_MapMsg16To32A(msg16->message,msg16->wParam,
1071 &msg32->message,&msg32->wParam,
1072 &msg32->lParam)<0) {
1073 HeapFree( SystemHeap, 0, msg32 );
1074 return -1;
1076 *plparam = (LPARAM)msg32;
1077 return 1;
1079 else return 0;
1080 case WM_NOTIFY:
1081 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1082 return 1;
1083 case WM_ASKCBFORMATNAME:
1084 case WM_DEVMODECHANGE:
1085 case WM_PAINTCLIPBOARD:
1086 case WM_SIZECLIPBOARD:
1087 case WM_WININICHANGE:
1088 FIXME( msg, "message %04x needs translation\n",msg16 );
1089 return -1;
1091 default: /* No translation needed */
1092 return 0;
1097 /**********************************************************************
1098 * WINPROC_UnmapMsg16To32A
1100 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1102 LRESULT WINPROC_UnmapMsg16To32A( HWND16 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1103 LRESULT result )
1105 switch(msg)
1107 case WM_COMPAREITEM:
1108 case WM_DELETEITEM:
1109 case WM_DRAWITEM:
1110 HeapFree( SystemHeap, 0, (LPVOID)lParam );
1111 break;
1112 case WM_MEASUREITEM:
1114 MEASUREITEMSTRUCT16 *mis16;
1115 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)lParam;
1116 lParam = *(LPARAM *)(mis + 1);
1117 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
1118 mis16->itemWidth = (UINT16)mis->itemWidth;
1119 mis16->itemHeight = (UINT16)mis->itemHeight;
1120 HeapFree( SystemHeap, 0, mis );
1122 break;
1123 case WM_GETMINMAXINFO:
1125 MINMAXINFO32 *mmi = (MINMAXINFO32 *)lParam;
1126 lParam = *(LPARAM *)(mmi + 1);
1127 STRUCT32_MINMAXINFO32to16( mmi,
1128 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
1129 HeapFree( SystemHeap, 0, mmi );
1131 break;
1132 case WM_MDICREATE:
1134 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
1135 lParam = *(LPARAM *)(cs + 1);
1136 STRUCT32_MDICREATESTRUCT32Ato16( cs,
1137 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1138 HeapFree( SystemHeap, 0, cs );
1140 break;
1141 case WM_MDIGETACTIVE:
1142 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL32 *)lParam) );
1143 HeapFree( SystemHeap, 0, (BOOL32 *)lParam );
1144 break;
1145 case WM_NCCALCSIZE:
1147 NCCALCSIZE_PARAMS16 *nc16;
1148 NCCALCSIZE_PARAMS32 *nc = (NCCALCSIZE_PARAMS32 *)lParam;
1149 lParam = *(LPARAM *)(nc + 1);
1150 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
1151 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
1152 if (wParam)
1154 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
1155 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
1156 if (nc->lppos)
1158 STRUCT32_WINDOWPOS32to16( nc->lppos,
1159 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
1160 HeapFree( SystemHeap, 0, nc->lppos );
1163 HeapFree( SystemHeap, 0, nc );
1165 break;
1166 case WM_NCCREATE:
1167 case WM_CREATE:
1169 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
1170 lParam = *(LPARAM *)(cs + 1);
1171 STRUCT32_CREATESTRUCT32Ato16( cs,
1172 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1173 HeapFree( SystemHeap, 0, cs );
1175 break;
1176 case WM_WINDOWPOSCHANGING:
1177 case WM_WINDOWPOSCHANGED:
1179 WINDOWPOS32 *wp = (WINDOWPOS32 *)lParam;
1180 lParam = *(LPARAM *)(wp + 1);
1181 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
1182 HeapFree( SystemHeap, 0, wp );
1184 break;
1185 case WM_GETDLGCODE:
1186 if (lParam)
1188 LPMSG32 msg32 = (LPMSG32)lParam;
1190 WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1191 result);
1192 HeapFree( SystemHeap, 0, msg32 );
1194 break;
1196 return result;
1200 /**********************************************************************
1201 * WINPROC_MapMsg16To32W
1203 * Map a message from 16- to 32-bit Unicode.
1204 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1206 INT32 WINPROC_MapMsg16To32W( HWND16 hwnd, UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
1207 WPARAM32 *pwparam32, LPARAM *plparam )
1209 switch(msg16)
1211 case WM_GETTEXT:
1212 case WM_SETTEXT:
1213 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1214 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, *pwparam32, plparam );
1215 case WM_NCCREATE:
1216 case WM_CREATE:
1218 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1219 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
1220 sizeof(*cs) + sizeof(LPARAM) );
1221 if (!cs) return -1;
1222 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCT32A *)cs );
1223 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1224 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1225 if (HIWORD(cs->lpszName))
1226 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
1227 (LPCSTR)cs->lpszName );
1228 if (HIWORD(cs->lpszClass))
1229 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
1230 (LPCSTR)cs->lpszClass );
1231 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1232 *plparam = (LPARAM)cs;
1234 return 1;
1235 case WM_MDICREATE:
1237 MDICREATESTRUCT16 *cs16 =
1238 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1239 MDICREATESTRUCT32W *cs =
1240 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
1241 sizeof(*cs) + sizeof(LPARAM) );
1242 if (!cs) return -1;
1243 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCT32A *)cs );
1244 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1245 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
1246 if (HIWORD(cs->szTitle))
1247 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
1248 (LPCSTR)cs->szTitle );
1249 if (HIWORD(cs->szClass))
1250 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
1251 (LPCSTR)cs->szClass );
1252 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1253 *plparam = (LPARAM)cs;
1255 return 1;
1256 case WM_GETDLGCODE:
1257 if (*plparam)
1259 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1260 LPMSG32 msg32 = (LPMSG32)HeapAlloc( SystemHeap, 0, sizeof(MSG32) );
1262 if (!msg32) return -1;
1263 msg32->hwnd = msg16->hwnd;
1264 msg32->lParam = msg16->lParam;
1265 msg32->time = msg16->time;
1266 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1267 /* this is right, right? */
1268 if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
1269 &msg32->message,&msg32->wParam,
1270 &msg32->lParam)<0) {
1271 HeapFree( SystemHeap, 0, msg32 );
1272 return -1;
1274 *plparam = (LPARAM)msg32;
1275 return 1;
1277 else return 0;
1278 default: /* No Unicode translation needed */
1279 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1280 pwparam32, plparam );
1285 /**********************************************************************
1286 * WINPROC_UnmapMsg16To32W
1288 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1290 LRESULT WINPROC_UnmapMsg16To32W( HWND16 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1291 LRESULT result )
1293 switch(msg)
1295 case WM_GETTEXT:
1296 case WM_SETTEXT:
1297 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
1298 break;
1299 case WM_NCCREATE:
1300 case WM_CREATE:
1302 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
1303 lParam = *(LPARAM *)(cs + 1);
1304 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
1305 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1306 if (HIWORD(cs->lpszName))
1307 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1308 if (HIWORD(cs->lpszClass))
1309 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1310 HeapFree( SystemHeap, 0, cs );
1312 break;
1313 case WM_MDICREATE:
1315 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
1316 lParam = *(LPARAM *)(cs + 1);
1317 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
1318 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1319 if (HIWORD(cs->szTitle))
1320 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1321 if (HIWORD(cs->szClass))
1322 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1323 HeapFree( SystemHeap, 0, cs );
1325 break;
1326 case WM_GETDLGCODE:
1327 if (lParam)
1329 LPMSG32 msg32 = (LPMSG32)lParam;
1331 WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1332 result);
1333 HeapFree( SystemHeap, 0, msg32 );
1335 break;
1336 default:
1337 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1339 return result;
1343 /**********************************************************************
1344 * WINPROC_MapMsg32ATo16
1346 * Map a message from 32-bit Ansi to 16-bit.
1347 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1349 INT32 WINPROC_MapMsg32ATo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1350 UINT16 *pmsg16, WPARAM16 *pwparam16,
1351 LPARAM *plparam )
1353 *pmsg16 = (UINT16)msg32;
1354 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1355 switch(msg32)
1357 case BM_GETCHECK32:
1358 case BM_SETCHECK32:
1359 case BM_GETSTATE32:
1360 case BM_SETSTATE32:
1361 case BM_SETSTYLE32:
1362 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK32);
1363 return 0;
1365 case EM_GETSEL32:
1366 case EM_GETRECT32:
1367 case EM_SETRECT32:
1368 case EM_SETRECTNP32:
1369 case EM_SCROLL32:
1370 case EM_LINESCROLL32:
1371 case EM_SCROLLCARET32:
1372 case EM_GETMODIFY32:
1373 case EM_SETMODIFY32:
1374 case EM_GETLINECOUNT32:
1375 case EM_LINEINDEX32:
1376 case EM_SETHANDLE32:
1377 case EM_GETHANDLE32:
1378 case EM_GETTHUMB32:
1379 case EM_LINELENGTH32:
1380 case EM_REPLACESEL32:
1381 case EM_GETLINE32:
1382 case EM_LIMITTEXT32:
1383 case EM_CANUNDO32:
1384 case EM_UNDO32:
1385 case EM_FMTLINES32:
1386 case EM_LINEFROMCHAR32:
1387 case EM_SETTABSTOPS32:
1388 case EM_SETPASSWORDCHAR32:
1389 case EM_EMPTYUNDOBUFFER32:
1390 case EM_GETFIRSTVISIBLELINE32:
1391 case EM_SETREADONLY32:
1392 case EM_SETWORDBREAKPROC32:
1393 case EM_GETWORDBREAKPROC32:
1394 case EM_GETPASSWORDCHAR32:
1395 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL32);
1396 return 0;
1398 case LB_CARETOFF32:
1399 case LB_CARETON32:
1400 case LB_DELETESTRING32:
1401 case LB_GETANCHORINDEX32:
1402 case LB_GETCARETINDEX32:
1403 case LB_GETCOUNT32:
1404 case LB_GETCURSEL32:
1405 case LB_GETHORIZONTALEXTENT32:
1406 case LB_GETITEMDATA32:
1407 case LB_GETITEMHEIGHT32:
1408 case LB_GETSEL32:
1409 case LB_GETSELCOUNT32:
1410 case LB_GETTEXTLEN32:
1411 case LB_GETTOPINDEX32:
1412 case LB_RESETCONTENT32:
1413 case LB_SELITEMRANGE32:
1414 case LB_SELITEMRANGEEX32:
1415 case LB_SETANCHORINDEX32:
1416 case LB_SETCARETINDEX32:
1417 case LB_SETCOLUMNWIDTH32:
1418 case LB_SETCURSEL32:
1419 case LB_SETHORIZONTALEXTENT32:
1420 case LB_SETITEMDATA32:
1421 case LB_SETITEMHEIGHT32:
1422 case LB_SETSEL32:
1423 case LB_SETTOPINDEX32:
1424 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1425 return 0;
1426 case CB_DELETESTRING32:
1427 case CB_GETCOUNT32:
1428 case CB_GETLBTEXTLEN32:
1429 case CB_LIMITTEXT32:
1430 case CB_RESETCONTENT32:
1431 case CB_SETEDITSEL32:
1432 case CB_GETCURSEL32:
1433 case CB_SETCURSEL32:
1434 case CB_SHOWDROPDOWN32:
1435 case CB_SETITEMDATA32:
1436 case CB_SETITEMHEIGHT32:
1437 case CB_GETITEMHEIGHT32:
1438 case CB_SETEXTENDEDUI32:
1439 case CB_GETEXTENDEDUI32:
1440 case CB_GETDROPPEDSTATE32:
1441 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1442 return 0;
1443 case CB_GETEDITSEL32:
1444 *pmsg16 = CB_GETEDITSEL16;
1445 return 1;
1447 case LB_ADDSTRING32:
1448 case LB_FINDSTRING32:
1449 case LB_FINDSTRINGEXACT32:
1450 case LB_INSERTSTRING32:
1451 case LB_SELECTSTRING32:
1452 case LB_DIR32:
1453 case LB_ADDFILE32:
1455 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1456 if (!str) return -1;
1457 *plparam = (LPARAM)SEGPTR_GET(str);
1459 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1460 return 1;
1462 case CB_ADDSTRING32:
1463 case CB_FINDSTRING32:
1464 case CB_FINDSTRINGEXACT32:
1465 case CB_INSERTSTRING32:
1466 case CB_SELECTSTRING32:
1467 case CB_DIR32:
1469 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1470 if (!str) return -1;
1471 *plparam = (LPARAM)SEGPTR_GET(str);
1473 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1474 return 1;
1476 case LB_GETITEMRECT32:
1478 RECT16 *rect;
1479 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1480 if (!rect) return -1;
1481 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1482 *plparam = (LPARAM)SEGPTR_GET(rect);
1484 *pmsg16 = LB_GETITEMRECT16;
1485 return 1;
1486 case LB_GETSELITEMS32:
1488 LPINT16 items;
1489 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1490 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1491 + sizeof(LPARAM)))) return -1;
1492 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1493 *plparam = (LPARAM)SEGPTR_GET(items);
1495 *pmsg16 = LB_GETSELITEMS16;
1496 return 1;
1497 case LB_SETTABSTOPS32:
1498 if (wParam32)
1500 INT32 i;
1501 LPINT16 stops;
1502 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1503 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1504 + sizeof(LPARAM)))) return -1;
1505 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT32)*plparam+i);
1506 *plparam = (LPARAM)SEGPTR_GET(stops);
1507 return 1;
1509 *pmsg16 = LB_SETTABSTOPS16;
1510 return 0;
1512 case CB_GETDROPPEDCONTROLRECT32:
1514 RECT16 *rect;
1515 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1516 if (!rect) return -1;
1517 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1518 *plparam = (LPARAM)SEGPTR_GET(rect);
1520 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1521 return 1;
1523 case LB_GETTEXT32:
1524 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1525 *pmsg16 = LB_GETTEXT16;
1526 return 1;
1528 case CB_GETLBTEXT32:
1529 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1530 *pmsg16 = CB_GETLBTEXT16;
1531 return 1;
1533 case EM_SETSEL32:
1534 *pwparam16 = 0;
1535 *plparam = MAKELONG( (INT16)(INT32)wParam32, (INT16)*plparam );
1536 *pmsg16 = EM_SETSEL16;
1537 return 0;
1539 case WM_ACTIVATE:
1540 case WM_CHARTOITEM:
1541 case WM_COMMAND:
1542 case WM_VKEYTOITEM:
1543 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1544 return 0;
1545 case WM_HSCROLL:
1546 case WM_VSCROLL:
1547 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1548 return 0;
1549 case WM_CTLCOLORMSGBOX:
1550 case WM_CTLCOLOREDIT:
1551 case WM_CTLCOLORLISTBOX:
1552 case WM_CTLCOLORBTN:
1553 case WM_CTLCOLORDLG:
1554 case WM_CTLCOLORSCROLLBAR:
1555 case WM_CTLCOLORSTATIC:
1556 *pmsg16 = WM_CTLCOLOR;
1557 *plparam = MAKELPARAM( (HWND16)*plparam,
1558 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1559 return 0;
1560 case WM_COMPAREITEM:
1562 COMPAREITEMSTRUCT32 *cis32 = (COMPAREITEMSTRUCT32 *)*plparam;
1563 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1564 if (!cis) return -1;
1565 cis->CtlType = (UINT16)cis32->CtlType;
1566 cis->CtlID = (UINT16)cis32->CtlID;
1567 cis->hwndItem = (HWND16)cis32->hwndItem;
1568 cis->itemID1 = (UINT16)cis32->itemID1;
1569 cis->itemData1 = cis32->itemData1;
1570 cis->itemID2 = (UINT16)cis32->itemID2;
1571 cis->itemData2 = cis32->itemData2;
1572 *plparam = (LPARAM)SEGPTR_GET(cis);
1574 return 1;
1575 case WM_DELETEITEM:
1577 DELETEITEMSTRUCT32 *dis32 = (DELETEITEMSTRUCT32 *)*plparam;
1578 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1579 if (!dis) return -1;
1580 dis->CtlType = (UINT16)dis32->CtlType;
1581 dis->CtlID = (UINT16)dis32->CtlID;
1582 dis->itemID = (UINT16)dis32->itemID;
1583 dis->hwndItem = (HWND16)dis32->hwndItem;
1584 dis->itemData = dis32->itemData;
1585 *plparam = (LPARAM)SEGPTR_GET(dis);
1587 return 1;
1588 case WM_DRAWITEM:
1590 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)*plparam;
1591 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1592 if (!dis) return -1;
1593 dis->CtlType = (UINT16)dis32->CtlType;
1594 dis->CtlID = (UINT16)dis32->CtlID;
1595 dis->itemID = (UINT16)dis32->itemID;
1596 dis->itemAction = (UINT16)dis32->itemAction;
1597 dis->itemState = (UINT16)dis32->itemState;
1598 dis->hwndItem = (HWND16)dis32->hwndItem;
1599 dis->hDC = (HDC16)dis32->hDC;
1600 dis->itemData = dis32->itemData;
1601 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1602 *plparam = (LPARAM)SEGPTR_GET(dis);
1604 return 1;
1605 case WM_MEASUREITEM:
1607 MEASUREITEMSTRUCT32 *mis32 = (MEASUREITEMSTRUCT32 *)*plparam;
1608 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1609 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1610 if (!mis) return -1;
1611 mis->CtlType = (UINT16)mis32->CtlType;
1612 mis->CtlID = (UINT16)mis32->CtlID;
1613 mis->itemID = (UINT16)mis32->itemID;
1614 mis->itemWidth = (UINT16)mis32->itemWidth;
1615 mis->itemHeight = (UINT16)mis32->itemHeight;
1616 mis->itemData = mis32->itemData;
1617 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1618 *plparam = (LPARAM)SEGPTR_GET(mis);
1620 return 1;
1621 case WM_GETMINMAXINFO:
1623 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1624 sizeof(LPARAM) );
1625 if (!mmi) return -1;
1626 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)*plparam, mmi );
1627 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1628 *plparam = (LPARAM)SEGPTR_GET(mmi);
1630 return 1;
1631 case WM_GETTEXT:
1633 LPSTR str;
1634 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1635 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1636 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1637 *plparam = (LPARAM)SEGPTR_GET(str);
1639 return 1;
1640 case WM_MDICREATE:
1642 MDICREATESTRUCT16 *cs;
1643 MDICREATESTRUCT32A *cs32 = (MDICREATESTRUCT32A *)*plparam;
1644 LPSTR name, cls;
1646 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1647 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1648 name = SEGPTR_STRDUP( cs32->szTitle );
1649 cls = SEGPTR_STRDUP( cs32->szClass );
1650 cs->szTitle = SEGPTR_GET(name);
1651 cs->szClass = SEGPTR_GET(cls);
1652 *plparam = (LPARAM)SEGPTR_GET(cs);
1654 return 1;
1655 case WM_MDIGETACTIVE:
1656 return 1;
1657 case WM_MDISETMENU:
1658 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1659 (HMENU16)LOWORD(*plparam) );
1660 *pwparam16 = (*plparam == 0);
1661 return 0;
1662 case WM_MENUCHAR:
1663 case WM_MENUSELECT:
1664 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1665 return 0;
1666 case WM_MDIACTIVATE:
1667 if( WIDGETS_IsControl32(WIN_FindWndPtr(hwnd), BIC32_MDICLIENT) )
1669 *pwparam16 = (HWND32)wParam32;
1670 *plparam = 0;
1672 else
1674 *pwparam16 = ((HWND32)*plparam == hwnd);
1675 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1676 (HWND16)LOWORD(wParam32) );
1678 return 0;
1679 case WM_NCCALCSIZE:
1681 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
1682 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1683 if (!nc) return -1;
1685 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1686 if (wParam32)
1688 WINDOWPOS16 *wp;
1689 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1690 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1691 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1693 SEGPTR_FREE(nc);
1694 return -1;
1696 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1697 nc->lppos = SEGPTR_GET(wp);
1699 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1700 *plparam = (LPARAM)SEGPTR_GET(nc);
1702 return 1;
1703 case WM_NCCREATE:
1704 case WM_CREATE:
1706 CREATESTRUCT16 *cs;
1707 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)*plparam;
1708 LPSTR name, cls;
1710 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1711 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1712 name = SEGPTR_STRDUP( cs32->lpszName );
1713 cls = SEGPTR_STRDUP( cs32->lpszClass );
1714 cs->lpszName = SEGPTR_GET(name);
1715 cs->lpszClass = SEGPTR_GET(cls);
1716 *plparam = (LPARAM)SEGPTR_GET(cs);
1718 return 1;
1719 case WM_PARENTNOTIFY:
1720 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1721 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1722 /* else nothing to do */
1723 return 0;
1724 case WM_NOTIFY:
1725 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
1726 return 1;
1727 case WM_SETTEXT:
1729 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1730 if (!str) return -1;
1731 *plparam = (LPARAM)SEGPTR_GET(str);
1733 return 1;
1734 case WM_WINDOWPOSCHANGING:
1735 case WM_WINDOWPOSCHANGED:
1737 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1738 sizeof(LPARAM) );
1739 if (!wp) return -1;
1740 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)*plparam, wp );
1741 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1742 *plparam = (LPARAM)SEGPTR_GET(wp);
1744 return 1;
1745 case WM_GETDLGCODE:
1746 if (*plparam) {
1747 LPMSG32 msg32 = (LPMSG32) *plparam;
1748 LPMSG16 msg16 = (LPMSG16) SEGPTR_NEW( MSG16 );
1750 if (!msg16) return -1;
1751 msg16->hwnd = msg32->hwnd;
1752 msg16->lParam = msg32->lParam;
1753 msg16->time = msg32->time;
1754 CONV_POINT32TO16(&msg32->pt,&msg16->pt);
1755 /* this is right, right? */
1756 if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
1757 &msg16->message,&msg16->wParam, &msg16->lParam)<0) {
1758 SEGPTR_FREE( msg16 );
1759 return -1;
1761 *plparam = (LPARAM)SEGPTR_GET(msg16);
1762 return 1;
1764 return 0;
1766 case WM_ASKCBFORMATNAME:
1767 case WM_DEVMODECHANGE:
1768 case WM_PAINTCLIPBOARD:
1769 case WM_SIZECLIPBOARD:
1770 case WM_WININICHANGE:
1771 FIXME( msg, "message %04x needs translation\n", msg32 );
1772 return -1;
1773 default: /* No translation needed */
1774 return 0;
1779 /**********************************************************************
1780 * WINPROC_UnmapMsg32ATo16
1782 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1784 void WINPROC_UnmapMsg32ATo16( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1785 MSGPARAM16* p16 )
1787 switch(msg)
1789 case LB_ADDFILE32:
1790 case LB_ADDSTRING32:
1791 case LB_DIR32:
1792 case LB_FINDSTRING32:
1793 case LB_FINDSTRINGEXACT32:
1794 case LB_INSERTSTRING32:
1795 case LB_SELECTSTRING32:
1796 case LB_SETTABSTOPS32:
1797 case CB_ADDSTRING32:
1798 case CB_FINDSTRING32:
1799 case CB_FINDSTRINGEXACT32:
1800 case CB_INSERTSTRING32:
1801 case CB_SELECTSTRING32:
1802 case CB_DIR32:
1803 case WM_COMPAREITEM:
1804 case WM_DELETEITEM:
1805 case WM_DRAWITEM:
1806 case WM_SETTEXT:
1807 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1808 break;
1810 case CB_GETDROPPEDCONTROLRECT32:
1811 case LB_GETITEMRECT32:
1813 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1814 p16->lParam = *(LPARAM *)(rect + 1);
1815 CONV_RECT16TO32( rect, (RECT32 *)(p16->lParam));
1816 SEGPTR_FREE( rect );
1818 break;
1819 case LB_GETSELITEMS32:
1821 INT32 i;
1822 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1823 p16->lParam = *((LPARAM *)items - 1);
1824 for (i = 0; i < p16->wParam; i++) *((LPINT32)(p16->lParam) + i) = items[i];
1825 SEGPTR_FREE( (LPARAM *)items - 1 );
1827 break;
1829 case CB_GETEDITSEL32:
1830 if( wParam )
1831 *((LPUINT32)(wParam)) = LOWORD(p16->lResult);
1832 if( lParam )
1833 *((LPUINT32)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1834 break;
1836 case LB_GETTEXT32:
1837 case CB_GETLBTEXT32:
1838 UnMapLS( (SEGPTR)(p16->lParam) );
1839 break;
1841 case WM_MEASUREITEM:
1843 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1844 MEASUREITEMSTRUCT32 *mis32 = *(MEASUREITEMSTRUCT32 **)(mis + 1);
1845 mis32->itemWidth = mis->itemWidth;
1846 mis32->itemHeight = mis->itemHeight;
1847 SEGPTR_FREE(mis);
1849 break;
1850 case WM_GETMINMAXINFO:
1852 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1853 p16->lParam = *(LPARAM *)(mmi + 1);
1854 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)(p16->lParam) );
1855 SEGPTR_FREE(mmi);
1857 break;
1858 case WM_GETTEXT:
1860 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1861 p16->lParam = *((LPARAM *)str - 1);
1862 lstrcpyn32A( (LPSTR)(p16->lParam), str, p16->wParam );
1863 SEGPTR_FREE( (LPARAM *)str - 1 );
1865 break;
1866 case WM_MDICREATE:
1868 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1869 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1870 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1871 SEGPTR_FREE( cs );
1873 break;
1874 case WM_MDIGETACTIVE:
1875 if (lParam) *(BOOL32 *)lParam = (BOOL16)HIWORD(p16->lResult);
1876 p16->lResult = (HWND32)LOWORD(p16->lResult);
1877 break;
1878 case WM_NCCALCSIZE:
1880 NCCALCSIZE_PARAMS32 *nc32;
1881 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
1882 p16->lParam = *(LPARAM *)(nc + 1);
1883 nc32 = (NCCALCSIZE_PARAMS32 *)(p16->lParam);
1884 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1885 if (p16->wParam)
1887 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1888 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1889 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1890 nc32->lppos );
1891 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1893 SEGPTR_FREE(nc);
1895 break;
1896 case WM_NCCREATE:
1897 case WM_CREATE:
1899 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1900 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1901 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1902 SEGPTR_FREE( cs );
1904 break;
1905 case WM_WINDOWPOSCHANGING:
1906 case WM_WINDOWPOSCHANGED:
1908 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
1909 p16->lParam = *(LPARAM *)(wp + 1);
1910 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)p16->lParam );
1911 SEGPTR_FREE(wp);
1913 break;
1914 case WM_NOTIFY:
1915 UnMapLS(p16->lParam);
1916 break;
1917 case WM_GETDLGCODE:
1918 if (p16->lParam)
1920 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(p16->lParam);
1921 MSGPARAM16 msgp16;
1922 msgp16.wParam=msg16->wParam;
1923 msgp16.lParam=msg16->lParam;
1924 WINPROC_UnmapMsg32ATo16(((LPMSG32)lParam)->hwnd, ((LPMSG32)lParam)->message,
1925 ((LPMSG32)lParam)->wParam, ((LPMSG32)lParam)->lParam,
1926 &msgp16 );
1927 SEGPTR_FREE(msg16);
1929 break;
1934 /**********************************************************************
1935 * WINPROC_MapMsg32WTo16
1937 * Map a message from 32-bit Unicode to 16-bit.
1938 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1940 INT32 WINPROC_MapMsg32WTo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1941 UINT16 *pmsg16, WPARAM16 *pwparam16,
1942 LPARAM *plparam )
1944 switch(msg32)
1946 case LB_ADDSTRING32:
1947 case LB_FINDSTRING32:
1948 case LB_FINDSTRINGEXACT32:
1949 case LB_INSERTSTRING32:
1950 case LB_SELECTSTRING32:
1951 case LB_DIR32:
1952 case LB_ADDFILE32:
1954 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1955 if (!str) return -1;
1956 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1957 *plparam = (LPARAM)SEGPTR_GET(str);
1959 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1960 return 1;
1962 case CB_ADDSTRING32:
1963 case CB_FINDSTRING32:
1964 case CB_FINDSTRINGEXACT32:
1965 case CB_INSERTSTRING32:
1966 case CB_SELECTSTRING32:
1967 case CB_DIR32:
1969 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1970 if (!str) return -1;
1971 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1972 *plparam = (LPARAM)SEGPTR_GET(str);
1974 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING32);
1975 return 1;
1977 case WM_NCCREATE:
1978 case WM_CREATE:
1980 CREATESTRUCT16 *cs;
1981 CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
1982 LPSTR name, cls;
1984 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1985 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
1986 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
1987 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
1988 cs->lpszName = SEGPTR_GET(name);
1989 cs->lpszClass = SEGPTR_GET(cls);
1990 *pmsg16 = (UINT16)msg32;
1991 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1992 *plparam = (LPARAM)SEGPTR_GET(cs);
1994 return 1;
1995 case WM_MDICREATE:
1997 MDICREATESTRUCT16 *cs;
1998 MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
1999 LPSTR name, cls;
2001 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
2002 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
2003 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
2004 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
2005 cs->szTitle = SEGPTR_GET(name);
2006 cs->szClass = SEGPTR_GET(cls);
2007 *pmsg16 = (UINT16)msg32;
2008 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2009 *plparam = (LPARAM)SEGPTR_GET(cs);
2011 return 1;
2012 case WM_SETTEXT:
2014 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2015 if (!str) return -1;
2016 *pmsg16 = (UINT16)msg32;
2017 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2018 *plparam = (LPARAM)SEGPTR_GET(str);
2020 return 1;
2021 default: /* No Unicode translation needed */
2022 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2023 pwparam16, plparam );
2028 /**********************************************************************
2029 * WINPROC_UnmapMsg32WTo16
2031 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2033 void WINPROC_UnmapMsg32WTo16( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam,
2034 MSGPARAM16* p16 )
2036 switch(msg)
2038 case WM_GETTEXT:
2040 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
2041 p16->lParam = *((LPARAM *)str - 1);
2042 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
2043 SEGPTR_FREE( (LPARAM *)str - 1 );
2045 break;
2046 default:
2047 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2048 break;
2053 /**********************************************************************
2054 * WINPROC_CallProc32ATo32W
2056 * Call a window procedure, translating args from Ansi to Unicode.
2058 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
2059 UINT32 msg, WPARAM32 wParam,
2060 LPARAM lParam )
2062 LRESULT result;
2064 if (WINPROC_MapMsg32ATo32W( hwnd, msg, wParam, &lParam ) == -1) return 0;
2065 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2066 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
2067 return result;
2071 /**********************************************************************
2072 * WINPROC_CallProc32WTo32A
2074 * Call a window procedure, translating args from Unicode to Ansi.
2076 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
2077 UINT32 msg, WPARAM32 wParam,
2078 LPARAM lParam )
2080 LRESULT result;
2082 if (WINPROC_MapMsg32WTo32A( hwnd, msg, wParam, &lParam ) == -1) return 0;
2083 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2084 WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
2085 return result;
2089 /**********************************************************************
2090 * WINPROC_CallProc16To32A
2092 * Call a 32-bit window procedure, translating the 16-bit args.
2094 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
2095 WPARAM16 wParam, LPARAM lParam,
2096 WNDPROC32 func )
2098 LRESULT result;
2099 UINT32 msg32;
2100 WPARAM32 wParam32;
2102 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2103 return 0;
2104 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
2105 return WINPROC_UnmapMsg16To32A( hwnd, msg32, wParam32, lParam, result );
2109 /**********************************************************************
2110 * WINPROC_CallProc16To32W
2112 * Call a 32-bit window procedure, translating the 16-bit args.
2114 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
2115 WPARAM16 wParam, LPARAM lParam,
2116 WNDPROC32 func )
2118 LRESULT result;
2119 UINT32 msg32;
2120 WPARAM32 wParam32;
2122 if (WINPROC_MapMsg16To32W( hwnd, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2123 return 0;
2124 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
2125 return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result );
2129 /**********************************************************************
2130 * WINPROC_CallProc32ATo16
2132 * Call a 16-bit window procedure, translating the 32-bit args.
2134 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
2135 UINT32 msg, WPARAM32 wParam,
2136 LPARAM lParam )
2138 UINT16 msg16;
2139 MSGPARAM16 mp16;
2141 mp16.lParam = lParam;
2142 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
2143 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
2144 return 0;
2145 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
2146 mp16.wParam, mp16.lParam );
2147 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
2148 return mp16.lResult;
2152 /**********************************************************************
2153 * WINPROC_CallProc32WTo16
2155 * Call a 16-bit window procedure, translating the 32-bit args.
2157 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
2158 UINT32 msg, WPARAM32 wParam,
2159 LPARAM lParam )
2161 UINT16 msg16;
2162 MSGPARAM16 mp16;
2164 mp16.lParam = lParam;
2165 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
2166 &mp16.lParam ) == -1)
2167 return 0;
2168 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
2169 mp16.wParam, mp16.lParam );
2170 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
2171 return mp16.lResult;
2175 /**********************************************************************
2176 * CallWindowProc16 (USER.122)
2178 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
2179 WPARAM16 wParam, LPARAM lParam )
2181 WINDOWPROC *proc = WINPROC_GetPtr( func );
2183 if (!proc)
2184 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
2186 #if testing
2187 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
2188 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
2189 #endif
2191 switch(proc->type)
2193 case WIN_PROC_16:
2194 if (!proc->thunk.t_from32.proc) return 0;
2195 return Callbacks->CallWndProc( proc->thunk.t_from32.proc,
2196 hwnd, msg, wParam, lParam );
2197 case WIN_PROC_32A:
2198 if (!proc->thunk.t_from16.proc) return 0;
2199 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
2200 proc->thunk.t_from16.proc );
2201 case WIN_PROC_32W:
2202 if (!proc->thunk.t_from16.proc) return 0;
2203 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
2204 proc->thunk.t_from16.proc );
2205 default:
2206 WARN( relay, "Invalid proc %p\n", proc );
2207 return 0;
2212 /**********************************************************************
2213 * CallWindowProc32A (USER32.18)
2215 * The CallWindowProc() function invokes the windows procedure _func_,
2216 * with _hwnd_ as the target window, the message specified by _msg_, and
2217 * the message parameters _wParam_ and _lParam_.
2219 * Some kinds of argument conversion may be done, I'm not sure what.
2221 * CallWindowProc() may be used for windows subclassing. Use
2222 * SetWindowLong() to set a new windows procedure for windows of the
2223 * subclass, and handle subclassed messages in the new windows
2224 * procedure. The new windows procedure may then use CallWindowProc()
2225 * with _func_ set to the parent class's windows procedure to dispatch
2226 * the message to the superclass.
2228 * RETURNS
2230 * The return value is message dependent.
2232 * CONFORMANCE
2234 * ECMA-234, Win32
2236 LRESULT WINAPI CallWindowProc32A(
2237 WNDPROC32 func, /* window procedure */
2238 HWND32 hwnd, /* target window */
2239 UINT32 msg, /* message */
2240 WPARAM32 wParam, /* message dependent parameter */
2241 LPARAM lParam /* message dependent parameter */
2243 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2245 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2247 #if testing
2248 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2249 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2250 #endif
2252 switch(proc->type)
2254 case WIN_PROC_16:
2255 if (!proc->thunk.t_from32.proc) return 0;
2256 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2257 hwnd, msg, wParam, lParam );
2258 case WIN_PROC_32A:
2259 if (!proc->thunk.t_from16.proc) return 0;
2260 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
2261 hwnd, msg, wParam, lParam );
2262 case WIN_PROC_32W:
2263 if (!proc->thunk.t_from16.proc) return 0;
2264 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2265 hwnd, msg, wParam, lParam );
2266 default:
2267 WARN( relay, "Invalid proc %p\n", proc );
2268 return 0;
2273 /**********************************************************************
2274 * CallWindowProc32W (USER32.19)
2276 LRESULT WINAPI CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
2277 WPARAM32 wParam, LPARAM lParam )
2279 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2281 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2283 #if testing
2284 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2285 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
2286 #endif
2288 switch(proc->type)
2290 case WIN_PROC_16:
2291 if (!proc->thunk.t_from32.proc) return 0;
2292 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2293 hwnd, msg, wParam, lParam );
2294 case WIN_PROC_32A:
2295 if (!proc->thunk.t_from16.proc) return 0;
2296 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2297 hwnd, msg, wParam, lParam );
2298 case WIN_PROC_32W:
2299 if (!proc->thunk.t_from16.proc) return 0;
2300 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
2301 hwnd, msg, wParam, lParam );
2302 default:
2303 WARN( relay, "Invalid proc %p\n", proc );
2304 return 0;