Added function to build the Windows numeric language ID from language,
[wine.git] / windows / winproc.c
blobcb8e9f117bc269b95cdd763f7086c0edaab2aee3
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"
18 /* Window procedure 16-to-32-bit thunk,
19 * see BuildSpec16Files() in tools/build.c */
21 typedef struct
23 BYTE popl_eax; /* popl %eax (return address) */
24 BYTE pushl_func; /* pushl $proc */
25 WNDPROC32 proc WINE_PACKED;
26 BYTE pushl_eax; /* pushl %eax */
27 WORD pushw_bp WINE_PACKED; /* pushw %bp */
28 BYTE pushl_thunk; /* pushl $thunkfrom16 */
29 void (*thunk32)() WINE_PACKED;
30 BYTE lcall; /* lcall cs:relay */
31 void (*relay)() WINE_PACKED; /* WINPROC_CallProc16To32A/W() */
32 WORD cs WINE_PACKED;
33 } WINPROC_THUNK_FROM16;
35 /* Window procedure 32-to-16-bit thunk,
36 * see BuildSpec32Files() in tools/build.c */
38 typedef struct
40 BYTE popl_eax; /* popl %eax (return address) */
41 BYTE pushl_func; /* pushl $proc */
42 WNDPROC16 proc WINE_PACKED;
43 BYTE pushl_eax; /* pushl %eax */
44 BYTE jmp; /* jmp relay (relative jump)*/
45 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
46 } WINPROC_THUNK_FROM32;
48 /* Simple jmp to call 32-bit procedure directly */
49 typedef struct
51 BYTE jmp; /* jmp proc (relative jump) */
52 WNDPROC32 proc WINE_PACKED;
53 } WINPROC_JUMP;
55 typedef union
57 WINPROC_THUNK_FROM16 t_from16;
58 WINPROC_THUNK_FROM32 t_from32;
59 } WINPROC_THUNK;
61 typedef struct tagWINDOWPROC
63 WINPROC_THUNK thunk; /* Thunk */
64 WINPROC_JUMP jmp; /* Jump */
65 struct tagWINDOWPROC *next; /* Next window proc */
66 UINT32 magic; /* Magic number */
67 WINDOWPROCTYPE type; /* Function type */
68 WINDOWPROCUSER user; /* Function user */
69 } WINDOWPROC;
71 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
73 #define WINPROC_THUNKPROC(pproc) \
74 (((pproc)->type == WIN_PROC_16) ? \
75 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
76 (WNDPROC16)((pproc)->thunk.t_from16.proc))
78 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
79 UINT32 msg, WPARAM32 wParam,
80 LPARAM lParam );
81 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
82 UINT32 msg, WPARAM32 wParam,
83 LPARAM lParam );
84 static LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
85 WPARAM16 wParam, LPARAM lParam,
86 WNDPROC32 func );
87 static LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
88 WPARAM16 wParam, LPARAM lParam,
89 WNDPROC32 func );
91 static HANDLE32 WinProcHeap;
94 /**********************************************************************
95 * WINPROC_Init
97 BOOL32 WINPROC_Init(void)
99 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
100 if (!WinProcHeap)
102 WARN(relay, "Unable to create winproc heap\n" );
103 return FALSE;
105 return TRUE;
109 /**********************************************************************
110 * WINPROC_CallWndProc32
112 * Call a 32-bit WndProc.
114 static LRESULT WINPROC_CallWndProc32( WNDPROC32 proc, HWND32 hwnd, UINT32 msg,
115 WPARAM32 wParam, LPARAM lParam )
117 TRACE(relay, "(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
118 proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
119 return proc( hwnd, msg, wParam, lParam );
123 /**********************************************************************
124 * WINPROC_GetPtr
126 * Return a pointer to the win proc.
128 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
130 BYTE *ptr;
131 WINDOWPROC *proc;
133 /* Check for a linear pointer */
135 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
137 ptr = (BYTE *)handle;
138 /* First check if it is the jmp address */
139 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
140 (int)&((WINDOWPROC *)0)->thunk;
141 /* Now it must be the thunk address */
142 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
143 /* Now we have a pointer to the WINDOWPROC struct */
144 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
145 return (WINDOWPROC *)ptr;
148 /* Check for a segmented pointer */
150 if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
152 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
153 if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
154 /* It must be the thunk address */
155 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
156 /* Now we have a pointer to the WINDOWPROC struct */
157 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
158 return (WINDOWPROC *)ptr;
161 return NULL;
165 /**********************************************************************
166 * WINPROC_AllocWinProc
168 * Allocate a new window procedure.
170 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
171 WINDOWPROCUSER user )
173 WINDOWPROC *proc, *oldproc;
175 /* Allocate a window procedure */
177 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
179 /* Check if the function is already a win proc */
181 if ((oldproc = WINPROC_GetPtr( func )))
183 *proc = *oldproc;
185 else
187 switch(type)
189 case WIN_PROC_16:
190 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
191 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
192 proc->thunk.t_from32.proc = func;
193 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
194 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
195 proc->thunk.t_from32.relay = /* relative jump */
196 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
197 (DWORD)(&proc->thunk.t_from32.relay + 1));
198 break;
199 case WIN_PROC_32A:
200 case WIN_PROC_32W:
201 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
202 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
203 proc->thunk.t_from16.proc = (FARPROC32)func;
204 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
205 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
206 proc->thunk.t_from16.pushl_thunk = 0x68; /* pushl $thunkfrom16 */
207 proc->thunk.t_from16.thunk32 = (type == WIN_PROC_32A) ?
208 (void(*)())WINPROC_CallProc16To32A :
209 (void(*)())WINPROC_CallProc16To32W;
210 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:relay */
211 proc->thunk.t_from16.relay = Callbacks->CallFrom16WndProc;
212 GET_CS(proc->thunk.t_from16.cs);
213 proc->jmp.jmp = 0xe9;
214 /* Fixup relative jump */
215 proc->jmp.proc = (WNDPROC32)((DWORD)func -
216 (DWORD)(&proc->jmp.proc + 1));
217 break;
218 default:
219 /* Should not happen */
220 break;
222 proc->magic = WINPROC_MAGIC;
223 proc->type = type;
224 proc->user = user;
226 proc->next = NULL;
227 TRACE(win, "(%08x,%d): returning %08x\n",
228 (UINT32)func, type, (UINT32)proc );
229 return proc;
233 /**********************************************************************
234 * WINPROC_GetProc
236 * Get a window procedure pointer that can be passed to the Windows program.
238 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
240 if (!proc) return NULL;
241 if (type == WIN_PROC_16) /* We want a 16:16 address */
243 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
244 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
245 else
246 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
247 &((WINDOWPROC *)proc)->thunk );
249 else /* We want a 32-bit address */
251 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
252 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
253 else if (type != ((WINDOWPROC *)proc)->type)
254 /* Have to return the jmp address if types don't match */
255 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
256 else
257 /* Some Win16 programs want to get back the proc they set */
258 return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc;
263 /**********************************************************************
264 * WINPROC_SetProc
266 * Set the window procedure for a window or class. There are
267 * three tree classes of winproc callbacks:
269 * 1) class -> wp - not subclassed
270 * class -> wp -> wp -> wp -> wp - SetClassLong()
271 * / /
272 * 2) window -' / - not subclassed
273 * window -> wp -> wp ' - SetWindowLong()
275 * 3) timer -> wp - SetTimer()
277 * Initially, winproc of the window points to the current winproc
278 * thunk of its class. Subclassing prepends a new thunk to the
279 * window winproc chain at the head of the list. Thus, window thunk
280 * list includes class thunks and the latter are preserved when the
281 * window is destroyed.
284 BOOL32 WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
285 WINDOWPROCTYPE type, WINDOWPROCUSER user )
287 BOOL32 bRecycle = FALSE;
288 WINDOWPROC *proc, **ppPrev;
290 /* Check if function is already in the list */
292 ppPrev = (WINDOWPROC **)pFirst;
293 proc = WINPROC_GetPtr( func );
294 while (*ppPrev)
296 if (proc)
298 if (*ppPrev == proc)
300 if ((*ppPrev)->user != user)
302 /* terminal thunk is being restored */
304 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
305 *(WINDOWPROC **)pFirst = *ppPrev;
306 return TRUE;
308 bRecycle = TRUE;
309 break;
312 else
314 if (((*ppPrev)->type == type) &&
315 (func == WINPROC_THUNKPROC(*ppPrev)))
317 bRecycle = TRUE;
318 break;
322 /* WPF_CLASS thunk terminates window thunk list */
323 if ((*ppPrev)->user != user) break;
324 ppPrev = &(*ppPrev)->next;
327 if (bRecycle)
329 /* Extract this thunk from the list */
330 proc = *ppPrev;
331 *ppPrev = proc->next;
333 else /* Allocate a new one */
335 if (proc) /* Was already a win proc */
337 type = proc->type;
338 func = WINPROC_THUNKPROC(proc);
340 proc = WINPROC_AllocWinProc( func, type, user );
341 if (!proc) return FALSE;
344 /* Add the win proc at the head of the list */
346 TRACE(win, "(%08x,%08x,%d): res=%08x\n",
347 (UINT32)*pFirst, (UINT32)func, type, (UINT32)proc );
348 proc->next = *(WINDOWPROC **)pFirst;
349 *(WINDOWPROC **)pFirst = proc;
350 return TRUE;
354 /**********************************************************************
355 * WINPROC_FreeProc
357 * Free a list of win procs.
359 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
361 while (proc)
363 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
364 if (((WINDOWPROC *)proc)->user != user) break;
365 TRACE(win, "freeing %08x\n", (UINT32)proc);
366 HeapFree( WinProcHeap, 0, proc );
367 proc = next;
372 /**********************************************************************
373 * WINPROC_GetProcType
375 * Return the window procedure type.
377 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
379 if (!proc ||
380 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
381 return WIN_PROC_INVALID;
382 return ((WINDOWPROC *)proc)->type;
386 /**********************************************************************
387 * WINPROC_MapMsg32ATo32W
389 * Map a message from Ansi to Unicode.
390 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
392 INT32 WINPROC_MapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
394 switch(msg)
396 case WM_GETTEXT:
398 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
399 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
400 if (!ptr) return -1;
401 *ptr++ = *plparam; /* Store previous lParam */
402 *plparam = (LPARAM)ptr;
404 return 1;
405 case WM_SETTEXT:
406 case LB_ADDSTRING32:
407 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
408 return (*plparam ? 1 : -1);
409 case WM_NCCREATE:
410 case WM_CREATE:
412 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
413 sizeof(*cs) );
414 if (!cs) return -1;
415 *cs = *(CREATESTRUCT32W *)*plparam;
416 if (HIWORD(cs->lpszName))
417 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
418 (LPCSTR)cs->lpszName );
419 if (HIWORD(cs->lpszClass))
420 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
421 (LPCSTR)cs->lpszClass );
422 *plparam = (LPARAM)cs;
424 return 1;
425 case WM_MDICREATE:
427 MDICREATESTRUCT32W *cs =
428 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
429 if (!cs) return -1;
430 *cs = *(MDICREATESTRUCT32W *)*plparam;
431 if (HIWORD(cs->szClass))
432 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
433 (LPCSTR)cs->szClass );
434 if (HIWORD(cs->szTitle))
435 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
436 (LPCSTR)cs->szTitle );
437 *plparam = (LPARAM)cs;
439 return 1;
440 case WM_ASKCBFORMATNAME:
441 case WM_DEVMODECHANGE:
442 case WM_PAINTCLIPBOARD:
443 case WM_SIZECLIPBOARD:
444 case WM_WININICHANGE:
445 TRACE(msg, "message %s needs translation\n", SPY_GetMsgName(msg) );
446 return -1;
447 default: /* No translation needed */
448 return 0;
453 /**********************************************************************
454 * WINPROC_UnmapMsg32ATo32W
456 * Unmap a message that was mapped from Ansi to Unicode.
458 void WINPROC_UnmapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
460 switch(msg)
462 case WM_GETTEXT:
464 LPARAM *ptr = (LPARAM *)lParam - 1;
465 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)(ptr + 1), wParam );
466 HeapFree( SystemHeap, 0, ptr );
468 break;
469 case LB_ADDSTRING32:
470 case WM_SETTEXT:
471 HeapFree( SystemHeap, 0, (void *)lParam );
472 break;
473 case WM_NCCREATE:
474 case WM_CREATE:
476 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
477 if (HIWORD(cs->lpszName))
478 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
479 if (HIWORD(cs->lpszClass))
480 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
481 HeapFree( SystemHeap, 0, cs );
483 break;
484 case WM_MDICREATE:
486 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
487 if (HIWORD(cs->szTitle))
488 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
489 if (HIWORD(cs->szClass))
490 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
491 HeapFree( SystemHeap, 0, cs );
493 break;
498 /**********************************************************************
499 * WINPROC_MapMsg32WTo32A
501 * Map a message from Unicode to Ansi.
502 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
504 INT32 WINPROC_MapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
506 switch(msg)
508 case WM_GETTEXT:
510 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
511 wParam + sizeof(LPARAM) );
512 if (!ptr) return -1;
513 *ptr++ = *plparam; /* Store previous lParam */
514 *plparam = (LPARAM)ptr;
516 return 1;
517 case WM_SETTEXT:
518 case LB_ADDSTRING32:
519 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
520 return (*plparam ? 1 : -1);
521 case WM_NCCREATE:
522 case WM_CREATE:
524 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
525 sizeof(*cs) );
526 if (!cs) return -1;
527 *cs = *(CREATESTRUCT32A *)*plparam;
528 if (HIWORD(cs->lpszName))
529 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
530 (LPCWSTR)cs->lpszName );
531 if (HIWORD(cs->lpszClass))
532 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
533 (LPCWSTR)cs->lpszClass);
534 *plparam = (LPARAM)cs;
536 return 1;
537 case WM_MDICREATE:
539 MDICREATESTRUCT32A *cs =
540 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
541 if (!cs) return -1;
542 *cs = *(MDICREATESTRUCT32A *)*plparam;
543 if (HIWORD(cs->szTitle))
544 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
545 (LPCWSTR)cs->szTitle );
546 if (HIWORD(cs->szClass))
547 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
548 (LPCWSTR)cs->szClass );
549 *plparam = (LPARAM)cs;
551 return 1;
552 case WM_ASKCBFORMATNAME:
553 case WM_DEVMODECHANGE:
554 case WM_PAINTCLIPBOARD:
555 case WM_SIZECLIPBOARD:
556 case WM_WININICHANGE:
557 WARN(msg, "message %04x needs translation\n",msg );
558 return -1;
559 default: /* No translation needed */
560 return 0;
565 /**********************************************************************
566 * WINPROC_UnmapMsg32WTo32A
568 * Unmap a message that was mapped from Unicode to Ansi.
570 void WINPROC_UnmapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
572 switch(msg)
574 case WM_GETTEXT:
576 LPARAM *ptr = (LPARAM *)lParam - 1;
577 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)(ptr + 1), wParam );
578 HeapFree( SystemHeap, 0, ptr );
580 break;
581 case LB_ADDSTRING32:
582 case WM_SETTEXT:
583 HeapFree( SystemHeap, 0, (void *)lParam );
584 break;
585 case WM_NCCREATE:
586 case WM_CREATE:
588 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
589 if (HIWORD(cs->lpszName))
590 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
591 if (HIWORD(cs->lpszClass))
592 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
593 HeapFree( SystemHeap, 0, cs );
595 break;
596 case WM_MDICREATE:
598 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
599 if (HIWORD(cs->szTitle))
600 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
601 if (HIWORD(cs->szClass))
602 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
603 HeapFree( SystemHeap, 0, cs );
605 break;
610 /**********************************************************************
611 * WINPROC_MapMsg16To32A
613 * Map a message from 16- to 32-bit Ansi.
614 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
616 INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
617 WPARAM32 *pwparam32, LPARAM *plparam )
619 *pmsg32 = (UINT32)msg16;
620 *pwparam32 = (WPARAM32)wParam16;
621 switch(msg16)
623 case WM_ACTIVATE:
624 case WM_CHARTOITEM:
625 case WM_COMMAND:
626 case WM_VKEYTOITEM:
627 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
628 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
629 return 0;
630 case WM_HSCROLL:
631 case WM_VSCROLL:
632 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
633 *plparam = (LPARAM)(HWND32)HIWORD(*plparam);
634 return 0;
635 case WM_CTLCOLOR:
636 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
637 *pwparam32 = (WPARAM32)(HDC32)wParam16;
638 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
639 return 0;
640 case WM_COMPAREITEM:
642 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
643 COMPAREITEMSTRUCT32 *cis = (COMPAREITEMSTRUCT32 *)
644 HeapAlloc(SystemHeap, 0, sizeof(*cis));
645 if (!cis) return -1;
646 cis->CtlType = cis16->CtlType;
647 cis->CtlID = cis16->CtlID;
648 cis->hwndItem = cis16->hwndItem;
649 cis->itemID1 = cis16->itemID1;
650 cis->itemData1 = cis16->itemData1;
651 cis->itemID2 = cis16->itemID2;
652 cis->itemData2 = cis16->itemData2;
653 cis->dwLocaleId = 0; /* FIXME */
654 *plparam = (LPARAM)cis;
656 return 1;
657 case WM_DELETEITEM:
659 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
660 DELETEITEMSTRUCT32 *dis = (DELETEITEMSTRUCT32 *)
661 HeapAlloc(SystemHeap, 0, sizeof(*dis));
662 if (!dis) return -1;
663 dis->CtlType = dis16->CtlType;
664 dis->CtlID = dis16->CtlID;
665 dis->hwndItem = dis16->hwndItem;
666 dis->itemData = dis16->itemData;
667 *plparam = (LPARAM)dis;
669 return 1;
670 case WM_MEASUREITEM:
672 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
673 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)
674 HeapAlloc(SystemHeap, 0,
675 sizeof(*mis) + sizeof(LPARAM));
676 if (!mis) return -1;
677 mis->CtlType = mis16->CtlType;
678 mis->CtlID = mis16->CtlID;
679 mis->itemID = mis16->itemID;
680 mis->itemWidth = mis16->itemWidth;
681 mis->itemHeight = mis16->itemHeight;
682 mis->itemData = mis16->itemData;
683 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
684 *plparam = (LPARAM)mis;
686 return 1;
687 case WM_DRAWITEM:
689 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
690 DRAWITEMSTRUCT32 *dis = (DRAWITEMSTRUCT32*)HeapAlloc(SystemHeap, 0,
691 sizeof(*dis));
692 if (!dis) return -1;
693 dis->CtlType = dis16->CtlType;
694 dis->CtlID = dis16->CtlID;
695 dis->itemID = dis16->itemID;
696 dis->itemAction = dis16->itemAction;
697 dis->itemState = dis16->itemState;
698 dis->hwndItem = dis16->hwndItem;
699 dis->hDC = dis16->hDC;
700 dis->itemData = dis16->itemData;
701 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
702 *plparam = (LPARAM)dis;
704 return 1;
705 case WM_GETMINMAXINFO:
707 MINMAXINFO32 *mmi = (MINMAXINFO32 *)HeapAlloc( SystemHeap, 0,
708 sizeof(*mmi) + sizeof(LPARAM));
709 if (!mmi) return -1;
710 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
711 mmi );
712 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
713 *plparam = (LPARAM)mmi;
715 return 1;
716 case WM_GETTEXT:
717 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
718 return 0;
719 case WM_MDICREATE:
721 MDICREATESTRUCT16 *cs16 =
722 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
723 MDICREATESTRUCT32A *cs =
724 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
725 sizeof(*cs) + sizeof(LPARAM) );
726 if (!cs) return -1;
727 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
728 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
729 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
730 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
731 *plparam = (LPARAM)cs;
733 return 1;
734 case WM_MDIGETACTIVE:
735 *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL32) );
736 return 1;
737 case WM_MDISETMENU:
738 if(wParam16==TRUE)
739 *pmsg32=WM_MDIREFRESHMENU;
740 *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
741 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
742 return 0;
743 case WM_MENUCHAR:
744 case WM_MENUSELECT:
745 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
746 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
747 return 0;
748 case WM_MDIACTIVATE:
749 if( *plparam )
751 *pwparam32 = (WPARAM32)(HWND32)HIWORD(*plparam);
752 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
754 else /* message sent to MDI client */
755 *pwparam32 = wParam16;
756 return 0;
757 case WM_NCCALCSIZE:
759 NCCALCSIZE_PARAMS16 *nc16;
760 NCCALCSIZE_PARAMS32 *nc;
762 nc = (NCCALCSIZE_PARAMS32 *)HeapAlloc( SystemHeap, 0,
763 sizeof(*nc) + sizeof(LPARAM) );
764 if (!nc) return -1;
765 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
766 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
767 if (wParam16)
769 nc->lppos = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
770 sizeof(*nc->lppos) );
771 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
772 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
773 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
775 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
776 *plparam = (LPARAM)nc;
778 return 1;
779 case WM_NCCREATE:
780 case WM_CREATE:
782 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
783 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
784 sizeof(*cs) + sizeof(LPARAM) );
785 if (!cs) return -1;
786 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
787 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
788 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
789 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
790 *plparam = (LPARAM)cs;
792 return 1;
793 case WM_PARENTNOTIFY:
794 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
796 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
797 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
799 return 0;
800 case WM_SETTEXT:
801 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
802 return 0;
803 case WM_WINDOWPOSCHANGING:
804 case WM_WINDOWPOSCHANGED:
806 WINDOWPOS32 *wp = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
807 sizeof(*wp) + sizeof(LPARAM) );
808 if (!wp) return -1;
809 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
810 wp );
811 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
812 *plparam = (LPARAM)wp;
814 return 1;
815 case WM_NOTIFY:
816 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
817 return 1;
818 case WM_ASKCBFORMATNAME:
819 case WM_DEVMODECHANGE:
820 case WM_PAINTCLIPBOARD:
821 case WM_SIZECLIPBOARD:
822 case WM_WININICHANGE:
823 FIXME( msg, "message %04x needs translation\n",msg16 );
824 return -1;
826 default: /* No translation needed */
827 return 0;
832 /**********************************************************************
833 * WINPROC_UnmapMsg16To32A
835 * Unmap a message that was mapped from 16- to 32-bit Ansi.
837 LRESULT WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
838 LRESULT result )
840 switch(msg)
842 case WM_COMPAREITEM:
843 case WM_DELETEITEM:
844 case WM_DRAWITEM:
845 HeapFree( SystemHeap, 0, (LPVOID)lParam );
846 break;
847 case WM_MEASUREITEM:
849 MEASUREITEMSTRUCT16 *mis16;
850 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)lParam;
851 lParam = *(LPARAM *)(mis + 1);
852 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
853 mis16->itemWidth = (UINT16)mis->itemWidth;
854 mis16->itemHeight = (UINT16)mis->itemHeight;
855 HeapFree( SystemHeap, 0, mis );
857 break;
858 case WM_GETMINMAXINFO:
860 MINMAXINFO32 *mmi = (MINMAXINFO32 *)lParam;
861 lParam = *(LPARAM *)(mmi + 1);
862 STRUCT32_MINMAXINFO32to16( mmi,
863 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
864 HeapFree( SystemHeap, 0, mmi );
866 break;
867 case WM_MDICREATE:
869 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
870 lParam = *(LPARAM *)(cs + 1);
871 STRUCT32_MDICREATESTRUCT32Ato16( cs,
872 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
873 HeapFree( SystemHeap, 0, cs );
875 break;
876 case WM_MDIGETACTIVE:
877 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL32 *)lParam) );
878 HeapFree( SystemHeap, 0, (BOOL32 *)lParam );
879 break;
880 case WM_NCCALCSIZE:
882 NCCALCSIZE_PARAMS16 *nc16;
883 NCCALCSIZE_PARAMS32 *nc = (NCCALCSIZE_PARAMS32 *)lParam;
884 lParam = *(LPARAM *)(nc + 1);
885 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
886 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
887 if (wParam)
889 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
890 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
891 if (nc->lppos)
893 STRUCT32_WINDOWPOS32to16( nc->lppos,
894 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
895 HeapFree( SystemHeap, 0, nc->lppos );
898 HeapFree( SystemHeap, 0, nc );
900 break;
901 case WM_NCCREATE:
902 case WM_CREATE:
904 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
905 lParam = *(LPARAM *)(cs + 1);
906 STRUCT32_CREATESTRUCT32Ato16( cs,
907 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
908 HeapFree( SystemHeap, 0, cs );
910 break;
911 case WM_WINDOWPOSCHANGING:
912 case WM_WINDOWPOSCHANGED:
914 WINDOWPOS32 *wp = (WINDOWPOS32 *)lParam;
915 lParam = *(LPARAM *)(wp + 1);
916 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
917 HeapFree( SystemHeap, 0, wp );
919 break;
921 return result;
925 /**********************************************************************
926 * WINPROC_MapMsg16To32W
928 * Map a message from 16- to 32-bit Unicode.
929 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
931 INT32 WINPROC_MapMsg16To32W( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
932 WPARAM32 *pwparam32, LPARAM *plparam )
934 switch(msg16)
936 case WM_GETTEXT:
937 case WM_SETTEXT:
938 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
939 return WINPROC_MapMsg32ATo32W( *pmsg32, *pwparam32, plparam );
940 case WM_NCCREATE:
941 case WM_CREATE:
943 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
944 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
945 sizeof(*cs) + sizeof(LPARAM) );
946 if (!cs) return -1;
947 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCT32A *)cs );
948 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
949 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
950 if (HIWORD(cs->lpszName))
951 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
952 (LPCSTR)cs->lpszName );
953 if (HIWORD(cs->lpszClass))
954 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
955 (LPCSTR)cs->lpszClass );
956 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
957 *plparam = (LPARAM)cs;
959 return 1;
960 case WM_MDICREATE:
962 MDICREATESTRUCT16 *cs16 =
963 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
964 MDICREATESTRUCT32W *cs =
965 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
966 sizeof(*cs) + sizeof(LPARAM) );
967 if (!cs) return -1;
968 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCT32A *)cs );
969 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
970 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
971 if (HIWORD(cs->szTitle))
972 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
973 (LPCSTR)cs->szTitle );
974 if (HIWORD(cs->szClass))
975 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
976 (LPCSTR)cs->szClass );
977 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
978 *plparam = (LPARAM)cs;
980 return 1;
981 default: /* No Unicode translation needed */
982 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
983 pwparam32, plparam );
988 /**********************************************************************
989 * WINPROC_UnmapMsg16To32W
991 * Unmap a message that was mapped from 16- to 32-bit Unicode.
993 LRESULT WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
994 LRESULT result )
996 switch(msg)
998 case WM_GETTEXT:
999 case WM_SETTEXT:
1000 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1001 break;
1002 case WM_NCCREATE:
1003 case WM_CREATE:
1005 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
1006 lParam = *(LPARAM *)(cs + 1);
1007 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
1008 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1009 if (HIWORD(cs->lpszName))
1010 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1011 if (HIWORD(cs->lpszClass))
1012 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1013 HeapFree( SystemHeap, 0, cs );
1015 break;
1016 case WM_MDICREATE:
1018 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
1019 lParam = *(LPARAM *)(cs + 1);
1020 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
1021 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1022 if (HIWORD(cs->szTitle))
1023 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1024 if (HIWORD(cs->szClass))
1025 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1026 HeapFree( SystemHeap, 0, cs );
1028 break;
1029 default:
1030 return WINPROC_UnmapMsg16To32A( msg, wParam, lParam, result );
1032 return result;
1036 /**********************************************************************
1037 * WINPROC_MapMsg32ATo16
1039 * Map a message from 32-bit Ansi to 16-bit.
1040 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1042 INT32 WINPROC_MapMsg32ATo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1043 UINT16 *pmsg16, WPARAM16 *pwparam16,
1044 LPARAM *plparam )
1046 *pmsg16 = (UINT16)msg32;
1047 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1048 switch(msg32)
1050 case BM_GETCHECK32:
1051 case BM_SETCHECK32:
1052 case BM_GETSTATE32:
1053 case BM_SETSTATE32:
1054 case BM_SETSTYLE32:
1055 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK32);
1056 return 0;
1058 case EM_GETSEL32:
1059 case EM_GETRECT32:
1060 case EM_SETRECT32:
1061 case EM_SETRECTNP32:
1062 case EM_SCROLL32:
1063 case EM_LINESCROLL32:
1064 case EM_SCROLLCARET32:
1065 case EM_GETMODIFY32:
1066 case EM_SETMODIFY32:
1067 case EM_GETLINECOUNT32:
1068 case EM_LINEINDEX32:
1069 case EM_SETHANDLE32:
1070 case EM_GETHANDLE32:
1071 case EM_GETTHUMB32:
1072 case EM_LINELENGTH32:
1073 case EM_REPLACESEL32:
1074 case EM_GETLINE32:
1075 case EM_LIMITTEXT32:
1076 case EM_CANUNDO32:
1077 case EM_UNDO32:
1078 case EM_FMTLINES32:
1079 case EM_LINEFROMCHAR32:
1080 case EM_SETTABSTOPS32:
1081 case EM_SETPASSWORDCHAR32:
1082 case EM_EMPTYUNDOBUFFER32:
1083 case EM_GETFIRSTVISIBLELINE32:
1084 case EM_SETREADONLY32:
1085 case EM_SETWORDBREAKPROC32:
1086 case EM_GETWORDBREAKPROC32:
1087 case EM_GETPASSWORDCHAR32:
1088 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL32);
1089 return 0;
1091 case LB_CARETOFF32:
1092 case LB_CARETON32:
1093 case LB_DELETESTRING32:
1094 case LB_GETANCHORINDEX32:
1095 case LB_GETCARETINDEX32:
1096 case LB_GETCOUNT32:
1097 case LB_GETCURSEL32:
1098 case LB_GETHORIZONTALEXTENT32:
1099 case LB_GETITEMDATA32:
1100 case LB_GETITEMHEIGHT32:
1101 case LB_GETSEL32:
1102 case LB_GETSELCOUNT32:
1103 case LB_GETTEXTLEN32:
1104 case LB_GETTOPINDEX32:
1105 case LB_RESETCONTENT32:
1106 case LB_SELITEMRANGE32:
1107 case LB_SELITEMRANGEEX32:
1108 case LB_SETANCHORINDEX32:
1109 case LB_SETCARETINDEX32:
1110 case LB_SETCOLUMNWIDTH32:
1111 case LB_SETCURSEL32:
1112 case LB_SETHORIZONTALEXTENT32:
1113 case LB_SETITEMDATA32:
1114 case LB_SETITEMHEIGHT32:
1115 case LB_SETSEL32:
1116 case LB_SETTOPINDEX32:
1117 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1118 return 0;
1119 case CB_DELETESTRING32:
1120 case CB_GETCOUNT32:
1121 case CB_GETLBTEXTLEN32:
1122 case CB_LIMITTEXT32:
1123 case CB_RESETCONTENT32:
1124 case CB_SETEDITSEL32:
1125 case CB_GETCURSEL32:
1126 case CB_SETCURSEL32:
1127 case CB_SHOWDROPDOWN32:
1128 case CB_SETITEMDATA32:
1129 case CB_SETITEMHEIGHT32:
1130 case CB_GETITEMHEIGHT32:
1131 case CB_SETEXTENDEDUI32:
1132 case CB_GETEXTENDEDUI32:
1133 case CB_GETDROPPEDSTATE32:
1134 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1135 return 0;
1136 case CB_GETEDITSEL32:
1137 *pmsg16 = CB_GETEDITSEL16;
1138 return 1;
1140 case LB_ADDSTRING32:
1141 case LB_FINDSTRING32:
1142 case LB_FINDSTRINGEXACT32:
1143 case LB_INSERTSTRING32:
1144 case LB_SELECTSTRING32:
1145 case LB_DIR32:
1146 case LB_ADDFILE32:
1148 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1149 if (!str) return -1;
1150 *plparam = (LPARAM)SEGPTR_GET(str);
1152 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1153 return 1;
1155 case CB_ADDSTRING32:
1156 case CB_FINDSTRING32:
1157 case CB_FINDSTRINGEXACT32:
1158 case CB_INSERTSTRING32:
1159 case CB_SELECTSTRING32:
1160 case CB_DIR32:
1162 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1163 if (!str) return -1;
1164 *plparam = (LPARAM)SEGPTR_GET(str);
1166 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1167 return 1;
1169 case LB_GETITEMRECT32:
1171 RECT16 *rect;
1172 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1173 if (!rect) return -1;
1174 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1175 *plparam = (LPARAM)SEGPTR_GET(rect);
1177 *pmsg16 = LB_GETITEMRECT16;
1178 return 1;
1179 case LB_GETSELITEMS32:
1181 LPINT16 items;
1182 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1183 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1184 + sizeof(LPARAM)))) return -1;
1185 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1186 *plparam = (LPARAM)SEGPTR_GET(items);
1188 *pmsg16 = LB_GETSELITEMS16;
1189 return 1;
1190 case LB_SETTABSTOPS32:
1191 if (wParam32)
1193 INT32 i;
1194 LPINT16 stops;
1195 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1196 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1197 + sizeof(LPARAM)))) return -1;
1198 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT32)*plparam+i);
1199 *plparam = (LPARAM)SEGPTR_GET(stops);
1200 return 1;
1202 *pmsg16 = LB_SETTABSTOPS16;
1203 return 0;
1205 case CB_GETDROPPEDCONTROLRECT32:
1207 RECT16 *rect;
1208 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1209 if (!rect) return -1;
1210 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1211 *plparam = (LPARAM)SEGPTR_GET(rect);
1213 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1214 return 1;
1216 case LB_GETTEXT32:
1217 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1218 *pmsg16 = LB_GETTEXT16;
1219 return 1;
1221 case CB_GETLBTEXT32:
1222 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1223 *pmsg16 = CB_GETLBTEXT16;
1224 return 1;
1226 case EM_SETSEL32:
1227 *pwparam16 = 0;
1228 *plparam = MAKELONG( (INT16)(INT32)wParam32, (INT16)*plparam );
1229 *pmsg16 = EM_SETSEL16;
1230 return 0;
1232 case WM_ACTIVATE:
1233 case WM_CHARTOITEM:
1234 case WM_COMMAND:
1235 case WM_VKEYTOITEM:
1236 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1237 return 0;
1238 case WM_HSCROLL:
1239 case WM_VSCROLL:
1240 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1241 return 0;
1242 case WM_CTLCOLORMSGBOX:
1243 case WM_CTLCOLOREDIT:
1244 case WM_CTLCOLORLISTBOX:
1245 case WM_CTLCOLORBTN:
1246 case WM_CTLCOLORDLG:
1247 case WM_CTLCOLORSCROLLBAR:
1248 case WM_CTLCOLORSTATIC:
1249 *pmsg16 = WM_CTLCOLOR;
1250 *plparam = MAKELPARAM( (HWND16)*plparam,
1251 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1252 return 0;
1253 case WM_COMPAREITEM:
1255 COMPAREITEMSTRUCT32 *cis32 = (COMPAREITEMSTRUCT32 *)*plparam;
1256 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1257 if (!cis) return -1;
1258 cis->CtlType = (UINT16)cis32->CtlType;
1259 cis->CtlID = (UINT16)cis32->CtlID;
1260 cis->hwndItem = (HWND16)cis32->hwndItem;
1261 cis->itemID1 = (UINT16)cis32->itemID1;
1262 cis->itemData1 = cis32->itemData1;
1263 cis->itemID2 = (UINT16)cis32->itemID2;
1264 cis->itemData2 = cis32->itemData2;
1265 *plparam = (LPARAM)SEGPTR_GET(cis);
1267 return 1;
1268 case WM_DELETEITEM:
1270 DELETEITEMSTRUCT32 *dis32 = (DELETEITEMSTRUCT32 *)*plparam;
1271 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1272 if (!dis) return -1;
1273 dis->CtlType = (UINT16)dis32->CtlType;
1274 dis->CtlID = (UINT16)dis32->CtlID;
1275 dis->itemID = (UINT16)dis32->itemID;
1276 dis->hwndItem = (HWND16)dis32->hwndItem;
1277 dis->itemData = dis32->itemData;
1278 *plparam = (LPARAM)SEGPTR_GET(dis);
1280 return 1;
1281 case WM_DRAWITEM:
1283 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)*plparam;
1284 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1285 if (!dis) return -1;
1286 dis->CtlType = (UINT16)dis32->CtlType;
1287 dis->CtlID = (UINT16)dis32->CtlID;
1288 dis->itemID = (UINT16)dis32->itemID;
1289 dis->itemAction = (UINT16)dis32->itemAction;
1290 dis->itemState = (UINT16)dis32->itemState;
1291 dis->hwndItem = (HWND16)dis32->hwndItem;
1292 dis->hDC = (HDC16)dis32->hDC;
1293 dis->itemData = dis32->itemData;
1294 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1295 *plparam = (LPARAM)SEGPTR_GET(dis);
1297 return 1;
1298 case WM_MEASUREITEM:
1300 MEASUREITEMSTRUCT32 *mis32 = (MEASUREITEMSTRUCT32 *)*plparam;
1301 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1302 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1303 if (!mis) return -1;
1304 mis->CtlType = (UINT16)mis32->CtlType;
1305 mis->CtlID = (UINT16)mis32->CtlID;
1306 mis->itemID = (UINT16)mis32->itemID;
1307 mis->itemWidth = (UINT16)mis32->itemWidth;
1308 mis->itemHeight = (UINT16)mis32->itemHeight;
1309 mis->itemData = mis32->itemData;
1310 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1311 *plparam = (LPARAM)SEGPTR_GET(mis);
1313 return 1;
1314 case WM_GETMINMAXINFO:
1316 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1317 sizeof(LPARAM) );
1318 if (!mmi) return -1;
1319 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)*plparam, mmi );
1320 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1321 *plparam = (LPARAM)SEGPTR_GET(mmi);
1323 return 1;
1324 case WM_GETTEXT:
1326 LPSTR str;
1327 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1328 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1329 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1330 *plparam = (LPARAM)SEGPTR_GET(str);
1332 return 1;
1333 case WM_MDICREATE:
1335 MDICREATESTRUCT16 *cs;
1336 MDICREATESTRUCT32A *cs32 = (MDICREATESTRUCT32A *)*plparam;
1337 LPSTR name, cls;
1339 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1340 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1341 name = SEGPTR_STRDUP( cs32->szTitle );
1342 cls = SEGPTR_STRDUP( cs32->szClass );
1343 cs->szTitle = SEGPTR_GET(name);
1344 cs->szClass = SEGPTR_GET(cls);
1345 *plparam = (LPARAM)SEGPTR_GET(cs);
1347 return 1;
1348 case WM_MDIGETACTIVE:
1349 return 1;
1350 case WM_MDISETMENU:
1351 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1352 (HMENU16)LOWORD(*plparam) );
1353 *pwparam16 = (*plparam == 0);
1354 return 0;
1355 case WM_MENUCHAR:
1356 case WM_MENUSELECT:
1357 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1358 return 0;
1359 case WM_MDIACTIVATE:
1360 if( WIDGETS_IsControl32(WIN_FindWndPtr(hwnd), BIC32_MDICLIENT) )
1362 *pwparam16 = (HWND32)wParam32;
1363 *plparam = 0;
1365 else
1367 *pwparam16 = ((HWND32)*plparam == hwnd);
1368 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1369 (HWND16)LOWORD(wParam32) );
1371 return 0;
1372 case WM_NCCALCSIZE:
1374 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
1375 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1376 if (!nc) return -1;
1378 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1379 if (wParam32)
1381 WINDOWPOS16 *wp;
1382 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1383 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1384 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1386 SEGPTR_FREE(nc);
1387 return -1;
1389 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1390 nc->lppos = SEGPTR_GET(wp);
1392 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1393 *plparam = (LPARAM)SEGPTR_GET(nc);
1395 return 1;
1396 case WM_NCCREATE:
1397 case WM_CREATE:
1399 CREATESTRUCT16 *cs;
1400 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)*plparam;
1401 LPSTR name, cls;
1403 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1404 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1405 name = SEGPTR_STRDUP( cs32->lpszName );
1406 cls = SEGPTR_STRDUP( cs32->lpszClass );
1407 cs->lpszName = SEGPTR_GET(name);
1408 cs->lpszClass = SEGPTR_GET(cls);
1409 *plparam = (LPARAM)SEGPTR_GET(cs);
1411 return 1;
1412 case WM_PARENTNOTIFY:
1413 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1414 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1415 /* else nothing to do */
1416 return 0;
1417 case WM_NOTIFY:
1418 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
1419 return 1;
1420 case WM_SETTEXT:
1422 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1423 if (!str) return -1;
1424 *plparam = (LPARAM)SEGPTR_GET(str);
1426 return 1;
1427 case WM_WINDOWPOSCHANGING:
1428 case WM_WINDOWPOSCHANGED:
1430 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1431 sizeof(LPARAM) );
1432 if (!wp) return -1;
1433 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)*plparam, wp );
1434 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1435 *plparam = (LPARAM)SEGPTR_GET(wp);
1437 return 1;
1438 case WM_ASKCBFORMATNAME:
1439 case WM_DEVMODECHANGE:
1440 case WM_PAINTCLIPBOARD:
1441 case WM_SIZECLIPBOARD:
1442 case WM_WININICHANGE:
1443 WARN( msg, "message %04x needs translation\n", msg32 );
1444 return -1;
1446 default: /* No translation needed */
1447 return 0;
1452 /**********************************************************************
1453 * WINPROC_UnmapMsg32ATo16
1455 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1457 void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1458 MSGPARAM16* p16 )
1460 switch(msg)
1462 case LB_ADDFILE32:
1463 case LB_ADDSTRING32:
1464 case LB_DIR32:
1465 case LB_FINDSTRING32:
1466 case LB_FINDSTRINGEXACT32:
1467 case LB_INSERTSTRING32:
1468 case LB_SELECTSTRING32:
1469 case LB_SETTABSTOPS32:
1470 case CB_ADDSTRING32:
1471 case CB_FINDSTRING32:
1472 case CB_FINDSTRINGEXACT32:
1473 case CB_INSERTSTRING32:
1474 case CB_SELECTSTRING32:
1475 case CB_DIR32:
1476 case WM_COMPAREITEM:
1477 case WM_DELETEITEM:
1478 case WM_DRAWITEM:
1479 case WM_SETTEXT:
1480 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1481 break;
1483 case CB_GETDROPPEDCONTROLRECT32:
1484 case LB_GETITEMRECT32:
1486 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1487 p16->lParam = *(LPARAM *)(rect + 1);
1488 CONV_RECT16TO32( rect, (RECT32 *)(p16->lParam));
1489 SEGPTR_FREE( rect );
1491 break;
1492 case LB_GETSELITEMS32:
1494 INT32 i;
1495 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1496 p16->lParam = *((LPARAM *)items - 1);
1497 for (i = 0; i < p16->wParam; i++) *((LPINT32)(p16->lParam) + i) = items[i];
1498 SEGPTR_FREE( (LPARAM *)items - 1 );
1500 break;
1502 case CB_GETEDITSEL32:
1503 if( wParam )
1504 *((LPUINT32)(wParam)) = LOWORD(p16->lResult);
1505 if( lParam )
1506 *((LPUINT32)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1507 break;
1509 case LB_GETTEXT32:
1510 case CB_GETLBTEXT32:
1511 UnMapLS( (SEGPTR)(p16->lParam) );
1512 break;
1514 case WM_MEASUREITEM:
1516 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1517 MEASUREITEMSTRUCT32 *mis32 = *(MEASUREITEMSTRUCT32 **)(mis + 1);
1518 mis32->itemWidth = mis->itemWidth;
1519 mis32->itemHeight = mis->itemHeight;
1520 SEGPTR_FREE(mis);
1522 break;
1523 case WM_GETMINMAXINFO:
1525 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1526 p16->lParam = *(LPARAM *)(mmi + 1);
1527 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)(p16->lParam) );
1528 SEGPTR_FREE(mmi);
1530 break;
1531 case WM_GETTEXT:
1533 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1534 p16->lParam = *((LPARAM *)str - 1);
1535 lstrcpyn32A( (LPSTR)(p16->lParam), str, p16->wParam );
1536 SEGPTR_FREE( (LPARAM *)str - 1 );
1538 break;
1539 case WM_MDICREATE:
1541 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1542 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1543 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1544 SEGPTR_FREE( cs );
1546 break;
1547 case WM_MDIGETACTIVE:
1548 if (lParam) *(BOOL32 *)lParam = (BOOL16)HIWORD(p16->lResult);
1549 p16->lResult = (HWND32)LOWORD(p16->lResult);
1550 break;
1551 case WM_NCCALCSIZE:
1553 NCCALCSIZE_PARAMS32 *nc32;
1554 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
1555 p16->lParam = *(LPARAM *)(nc + 1);
1556 nc32 = (NCCALCSIZE_PARAMS32 *)(p16->lParam);
1557 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1558 if (p16->wParam)
1560 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1561 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1562 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1563 nc32->lppos );
1564 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1566 SEGPTR_FREE(nc);
1568 break;
1569 case WM_NCCREATE:
1570 case WM_CREATE:
1572 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1573 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1574 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1575 SEGPTR_FREE( cs );
1577 break;
1578 case WM_WINDOWPOSCHANGING:
1579 case WM_WINDOWPOSCHANGED:
1581 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
1582 p16->lParam = *(LPARAM *)(wp + 1);
1583 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)p16->lParam );
1584 SEGPTR_FREE(wp);
1586 break;
1587 case WM_NOTIFY:
1588 UnMapLS(p16->lParam);
1589 break;
1594 /**********************************************************************
1595 * WINPROC_MapMsg32WTo16
1597 * Map a message from 32-bit Unicode to 16-bit.
1598 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1600 INT32 WINPROC_MapMsg32WTo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1601 UINT16 *pmsg16, WPARAM16 *pwparam16,
1602 LPARAM *plparam )
1604 switch(msg32)
1606 case LB_ADDSTRING32:
1607 case LB_FINDSTRING32:
1608 case LB_FINDSTRINGEXACT32:
1609 case LB_INSERTSTRING32:
1610 case LB_SELECTSTRING32:
1611 case LB_DIR32:
1612 case LB_ADDFILE32:
1614 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1615 if (!str) return -1;
1616 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1617 *plparam = (LPARAM)SEGPTR_GET(str);
1619 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1620 return 1;
1622 case CB_ADDSTRING32:
1623 case CB_FINDSTRING32:
1624 case CB_FINDSTRINGEXACT32:
1625 case CB_INSERTSTRING32:
1626 case CB_SELECTSTRING32:
1627 case CB_DIR32:
1629 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1630 if (!str) return -1;
1631 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1632 *plparam = (LPARAM)SEGPTR_GET(str);
1634 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING32);
1635 return 1;
1637 case WM_NCCREATE:
1638 case WM_CREATE:
1640 CREATESTRUCT16 *cs;
1641 CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
1642 LPSTR name, cls;
1644 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1645 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
1646 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
1647 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
1648 cs->lpszName = SEGPTR_GET(name);
1649 cs->lpszClass = SEGPTR_GET(cls);
1650 *pmsg16 = (UINT16)msg32;
1651 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1652 *plparam = (LPARAM)SEGPTR_GET(cs);
1654 return 1;
1655 case WM_MDICREATE:
1657 MDICREATESTRUCT16 *cs;
1658 MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
1659 LPSTR name, cls;
1661 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1662 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
1663 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
1664 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
1665 cs->szTitle = SEGPTR_GET(name);
1666 cs->szClass = SEGPTR_GET(cls);
1667 *pmsg16 = (UINT16)msg32;
1668 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1669 *plparam = (LPARAM)SEGPTR_GET(cs);
1671 return 1;
1672 case WM_SETTEXT:
1674 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1675 if (!str) return -1;
1676 *pmsg16 = (UINT16)msg32;
1677 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1678 *plparam = (LPARAM)SEGPTR_GET(str);
1680 return 1;
1681 default: /* No Unicode translation needed */
1682 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
1683 pwparam16, plparam );
1688 /**********************************************************************
1689 * WINPROC_UnmapMsg32WTo16
1691 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1693 void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1694 MSGPARAM16* p16 )
1696 switch(msg)
1698 case WM_GETTEXT:
1700 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1701 p16->lParam = *((LPARAM *)str - 1);
1702 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
1703 SEGPTR_FREE( (LPARAM *)str - 1 );
1705 break;
1706 default:
1707 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, p16 );
1708 break;
1713 /**********************************************************************
1714 * WINPROC_CallProc32ATo32W
1716 * Call a window procedure, translating args from Ansi to Unicode.
1718 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
1719 UINT32 msg, WPARAM32 wParam,
1720 LPARAM lParam )
1722 LRESULT result;
1724 if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
1725 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1726 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1727 return result;
1731 /**********************************************************************
1732 * WINPROC_CallProc32WTo32A
1734 * Call a window procedure, translating args from Unicode to Ansi.
1736 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
1737 UINT32 msg, WPARAM32 wParam,
1738 LPARAM lParam )
1740 LRESULT result;
1742 if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
1743 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1744 WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
1745 return result;
1749 /**********************************************************************
1750 * WINPROC_CallProc16To32A
1752 * Call a 32-bit window procedure, translating the 16-bit args.
1754 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
1755 WPARAM16 wParam, LPARAM lParam,
1756 WNDPROC32 func )
1758 LRESULT result;
1759 UINT32 msg32;
1760 WPARAM32 wParam32;
1762 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1763 return 0;
1764 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1765 return WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam, result );
1769 /**********************************************************************
1770 * WINPROC_CallProc16To32W
1772 * Call a 32-bit window procedure, translating the 16-bit args.
1774 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
1775 WPARAM16 wParam, LPARAM lParam,
1776 WNDPROC32 func )
1778 LRESULT result;
1779 UINT32 msg32;
1780 WPARAM32 wParam32;
1782 if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1783 return 0;
1784 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1785 return WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam, result );
1789 /**********************************************************************
1790 * WINPROC_CallProc32ATo16
1792 * Call a 16-bit window procedure, translating the 32-bit args.
1794 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
1795 UINT32 msg, WPARAM32 wParam,
1796 LPARAM lParam )
1798 UINT16 msg16;
1799 MSGPARAM16 mp16;
1801 mp16.lParam = lParam;
1802 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
1803 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
1804 return 0;
1805 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1806 mp16.wParam, mp16.lParam );
1807 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, &mp16 );
1808 return mp16.lResult;
1812 /**********************************************************************
1813 * WINPROC_CallProc32WTo16
1815 * Call a 16-bit window procedure, translating the 32-bit args.
1817 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
1818 UINT32 msg, WPARAM32 wParam,
1819 LPARAM lParam )
1821 UINT16 msg16;
1822 MSGPARAM16 mp16;
1824 mp16.lParam = lParam;
1825 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
1826 &mp16.lParam ) == -1)
1827 return 0;
1828 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1829 mp16.wParam, mp16.lParam );
1830 WINPROC_UnmapMsg32WTo16( msg, wParam, lParam, &mp16 );
1831 return mp16.lResult;
1835 /**********************************************************************
1836 * CallWindowProc16 (USER.122)
1838 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
1839 WPARAM16 wParam, LPARAM lParam )
1841 WINDOWPROC *proc = WINPROC_GetPtr( func );
1843 if (!proc)
1844 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1846 #if testing
1847 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
1848 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1849 #endif
1851 switch(proc->type)
1853 case WIN_PROC_16:
1854 if (!proc->thunk.t_from32.proc) return 0;
1855 return Callbacks->CallWndProc( proc->thunk.t_from32.proc,
1856 hwnd, msg, wParam, lParam );
1857 case WIN_PROC_32A:
1858 if (!proc->thunk.t_from16.proc) return 0;
1859 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
1860 proc->thunk.t_from16.proc );
1861 case WIN_PROC_32W:
1862 if (!proc->thunk.t_from16.proc) return 0;
1863 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
1864 proc->thunk.t_from16.proc );
1865 default:
1866 WARN( relay, "Invalid proc %p\n", proc );
1867 return 0;
1872 /**********************************************************************
1873 * CallWindowProc32A (USER32.18)
1875 * The CallWindowProc() function invokes the windows procedure _func_,
1876 * with _hwnd_ as the target window, the message specified by _msg_, and
1877 * the message parameters _wParam_ and _lParam_.
1879 * Some kinds of argument conversion may be done, I'm not sure what.
1881 * CallWindowProc() may be used for windows subclassing. Use
1882 * SetWindowLong() to set a new windows procedure for windows of the
1883 * subclass, and handle subclassed messages in the new windows
1884 * procedure. The new windows procedure may then use CallWindowProc()
1885 * with _func_ set to the parent class's windows procedure to dispatch
1886 * the message to the superclass.
1888 * RETURNS
1890 * The return value is message dependent.
1892 * CONFORMANCE
1894 * ECMA-234, Win32
1896 LRESULT WINAPI CallWindowProc32A(
1897 WNDPROC32 func, /* window procedure */
1898 HWND32 hwnd, /* target window */
1899 UINT32 msg, /* message */
1900 WPARAM32 wParam, /* message dependent parameter */
1901 LPARAM lParam /* message dependent parameter */
1903 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1905 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1907 #if testing
1908 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
1909 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1910 #endif
1912 switch(proc->type)
1914 case WIN_PROC_16:
1915 if (!proc->thunk.t_from32.proc) return 0;
1916 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
1917 hwnd, msg, wParam, lParam );
1918 case WIN_PROC_32A:
1919 if (!proc->thunk.t_from16.proc) return 0;
1920 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
1921 hwnd, msg, wParam, lParam );
1922 case WIN_PROC_32W:
1923 if (!proc->thunk.t_from16.proc) return 0;
1924 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
1925 hwnd, msg, wParam, lParam );
1926 default:
1927 WARN( relay, "Invalid proc %p\n", proc );
1928 return 0;
1933 /**********************************************************************
1934 * CallWindowProc32W (USER32.19)
1936 LRESULT WINAPI CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1937 WPARAM32 wParam, LPARAM lParam )
1939 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1941 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1943 #if testing
1944 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
1945 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1946 #endif
1948 switch(proc->type)
1950 case WIN_PROC_16:
1951 if (!proc->thunk.t_from32.proc) return 0;
1952 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
1953 hwnd, msg, wParam, lParam );
1954 case WIN_PROC_32A:
1955 if (!proc->thunk.t_from16.proc) return 0;
1956 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
1957 hwnd, msg, wParam, lParam );
1958 case WIN_PROC_32W:
1959 if (!proc->thunk.t_from16.proc) return 0;
1960 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
1961 hwnd, msg, wParam, lParam );
1962 default:
1963 WARN( relay, "Invalid proc %p\n", proc );
1964 return 0;