2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
12 #include "selectors.h"
18 /* Window procedure 16-to-32-bit thunk,
19 * see BuildSpec16Files() in tools/build.c */
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() */
33 } WINPROC_THUNK_FROM16;
35 /* Window procedure 32-to-16-bit thunk,
36 * see BuildSpec32Files() in tools/build.c */
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 */
51 BYTE jmp; /* jmp proc (relative jump) */
52 WNDPROC32 proc WINE_PACKED;
57 WINPROC_THUNK_FROM16 t_from16;
58 WINPROC_THUNK_FROM32 t_from32;
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 */
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,
81 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
82 UINT32 msg, WPARAM32 wParam,
84 static LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
85 WPARAM16 wParam, LPARAM lParam,
87 static LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
88 WPARAM16 wParam, LPARAM lParam,
91 static HANDLE32 WinProcHeap;
94 /**********************************************************************
97 BOOL32 WINPROC_Init(void)
99 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
102 fprintf( stderr, "Unable to create winproc heap\n" );
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=%08x,wp=%08x,lp=%08lx)\n",
118 proc, hwnd, msg, wParam, lParam );
119 return proc( hwnd, msg, wParam, lParam );
123 /**********************************************************************
126 * Return a pointer to the win proc.
128 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
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;
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 )))
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));
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));
219 /* Should not happen */
222 proc->magic = WINPROC_MAGIC;
227 TRACE(win, "(%08x,%d): returning %08x\n",
228 (UINT32)func, type, (UINT32)proc );
233 /**********************************************************************
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;
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;
254 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
259 /**********************************************************************
262 * Set the window procedure for a window or class. There are
263 * three tree classes of winproc callbacks:
265 * 1) class -> wp - not subclassed
266 * class -> wp -> wp -> wp -> wp - SetClassLong()
268 * 2) window -' / - not subclassed
269 * window -> wp -> wp ' - SetWindowLong()
271 * 3) timer -> wp - SetTimer()
273 * Initially, winproc of the window points to the current winproc
274 * thunk of its class. Subclassing prepends a new thunk to the
275 * window winproc chain at the head of the list. Thus, window thunk
276 * list includes class thunks and the latter are preserved when the
277 * window is destroyed.
280 BOOL32 WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
281 WINDOWPROCTYPE type, WINDOWPROCUSER user )
283 BOOL32 bRecycle = FALSE;
284 WINDOWPROC *proc, **ppPrev;
286 /* Check if function is already in the list */
288 ppPrev = (WINDOWPROC **)pFirst;
289 proc = WINPROC_GetPtr( func );
296 if ((*ppPrev)->user != user)
298 /* terminal thunk is being restored */
300 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
301 *(WINDOWPROC **)pFirst = *ppPrev;
310 if (((*ppPrev)->type == type) &&
311 (func == WINPROC_THUNKPROC(*ppPrev)))
318 /* WPF_CLASS thunk terminates window thunk list */
319 if ((*ppPrev)->user != user) break;
320 ppPrev = &(*ppPrev)->next;
325 /* Extract this thunk from the list */
327 *ppPrev = proc->next;
329 else /* Allocate a new one */
331 if (proc) /* Was already a win proc */
334 func = WINPROC_THUNKPROC(proc);
336 proc = WINPROC_AllocWinProc( func, type, user );
337 if (!proc) return FALSE;
340 /* Add the win proc at the head of the list */
342 TRACE(win, "(%08x,%08x,%d): res=%08x\n",
343 (UINT32)*pFirst, (UINT32)func, type, (UINT32)proc );
344 proc->next = *(WINDOWPROC **)pFirst;
345 *(WINDOWPROC **)pFirst = proc;
350 /**********************************************************************
353 * Free a list of win procs.
355 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
359 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
360 if (((WINDOWPROC *)proc)->user != user) break;
361 TRACE(win, "freeing %08x\n", (UINT32)proc);
362 HeapFree( WinProcHeap, 0, proc );
368 /**********************************************************************
369 * WINPROC_GetProcType
371 * Return the window procedure type.
373 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
376 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
377 return WIN_PROC_INVALID;
378 return ((WINDOWPROC *)proc)->type;
382 /**********************************************************************
383 * WINPROC_MapMsg32ATo32W
385 * Map a message from Ansi to Unicode.
386 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
388 INT32 WINPROC_MapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
394 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
395 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
397 *ptr++ = *plparam; /* Store previous lParam */
398 *plparam = (LPARAM)ptr;
402 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
403 return (*plparam ? 1 : -1);
407 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
410 *cs = *(CREATESTRUCT32W *)*plparam;
411 if (HIWORD(cs->lpszName))
412 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
413 (LPCSTR)cs->lpszName );
414 if (HIWORD(cs->lpszClass))
415 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
416 (LPCSTR)cs->lpszClass );
417 *plparam = (LPARAM)cs;
422 MDICREATESTRUCT32W *cs =
423 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
425 *cs = *(MDICREATESTRUCT32W *)*plparam;
426 if (HIWORD(cs->szClass))
427 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
428 (LPCSTR)cs->szClass );
429 if (HIWORD(cs->szTitle))
430 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
431 (LPCSTR)cs->szTitle );
432 *plparam = (LPARAM)cs;
435 case WM_ASKCBFORMATNAME:
436 case WM_DEVMODECHANGE:
437 case WM_PAINTCLIPBOARD:
438 case WM_SIZECLIPBOARD:
439 case WM_WININICHANGE:
440 fprintf( stderr, "MapMsg32ATo32W: message %04x needs translation\n",
443 default: /* No translation needed */
449 /**********************************************************************
450 * WINPROC_UnmapMsg32ATo32W
452 * Unmap a message that was mapped from Ansi to Unicode.
454 void WINPROC_UnmapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
460 LPARAM *ptr = (LPARAM *)lParam - 1;
461 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)(ptr + 1), wParam );
462 HeapFree( SystemHeap, 0, ptr );
466 HeapFree( SystemHeap, 0, (void *)lParam );
471 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
472 if (HIWORD(cs->lpszName))
473 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
474 if (HIWORD(cs->lpszClass))
475 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
476 HeapFree( SystemHeap, 0, cs );
481 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
482 if (HIWORD(cs->szTitle))
483 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
484 if (HIWORD(cs->szClass))
485 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
486 HeapFree( SystemHeap, 0, cs );
493 /**********************************************************************
494 * WINPROC_MapMsg32WTo32A
496 * Map a message from Unicode to Ansi.
497 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
499 INT32 WINPROC_MapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
505 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
506 wParam + sizeof(LPARAM) );
508 *ptr++ = *plparam; /* Store previous lParam */
509 *plparam = (LPARAM)ptr;
513 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
514 return (*plparam ? 1 : -1);
518 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
521 *cs = *(CREATESTRUCT32A *)*plparam;
522 if (HIWORD(cs->lpszName))
523 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
524 (LPCWSTR)cs->lpszName );
525 if (HIWORD(cs->lpszClass))
526 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
527 (LPCWSTR)cs->lpszClass);
528 *plparam = (LPARAM)cs;
533 MDICREATESTRUCT32A *cs =
534 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
536 *cs = *(MDICREATESTRUCT32A *)*plparam;
537 if (HIWORD(cs->szTitle))
538 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
539 (LPCWSTR)cs->szTitle );
540 if (HIWORD(cs->szClass))
541 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
542 (LPCWSTR)cs->szClass );
543 *plparam = (LPARAM)cs;
546 case WM_ASKCBFORMATNAME:
547 case WM_DEVMODECHANGE:
548 case WM_PAINTCLIPBOARD:
549 case WM_SIZECLIPBOARD:
550 case WM_WININICHANGE:
551 fprintf( stderr, "MapMsg32WTo32A: message %04x needs translation\n",
554 default: /* No translation needed */
560 /**********************************************************************
561 * WINPROC_UnmapMsg32WTo32A
563 * Unmap a message that was mapped from Unicode to Ansi.
565 void WINPROC_UnmapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
571 LPARAM *ptr = (LPARAM *)lParam - 1;
572 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)(ptr + 1), wParam );
573 HeapFree( SystemHeap, 0, ptr );
577 HeapFree( SystemHeap, 0, (void *)lParam );
582 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
583 if (HIWORD(cs->lpszName))
584 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
585 if (HIWORD(cs->lpszClass))
586 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
587 HeapFree( SystemHeap, 0, cs );
592 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
593 if (HIWORD(cs->szTitle))
594 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
595 if (HIWORD(cs->szClass))
596 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
597 HeapFree( SystemHeap, 0, cs );
604 /**********************************************************************
605 * WINPROC_MapMsg16To32A
607 * Map a message from 16- to 32-bit Ansi.
608 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
610 INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
611 WPARAM32 *pwparam32, LPARAM *plparam )
613 *pmsg32 = (UINT32)msg16;
614 *pwparam32 = (WPARAM32)wParam16;
621 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
622 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
626 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
627 *plparam = (LPARAM)(HWND32)HIWORD(*plparam);
630 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
631 *pwparam32 = (WPARAM32)(HDC32)wParam16;
632 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
636 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
637 COMPAREITEMSTRUCT32 *cis = (COMPAREITEMSTRUCT32 *)
638 HeapAlloc(SystemHeap, 0, sizeof(*cis));
640 cis->CtlType = cis16->CtlType;
641 cis->CtlID = cis16->CtlID;
642 cis->hwndItem = cis16->hwndItem;
643 cis->itemID1 = cis16->itemID1;
644 cis->itemData1 = cis16->itemData1;
645 cis->itemID2 = cis16->itemID2;
646 cis->itemData2 = cis16->itemData2;
647 cis->dwLocaleId = 0; /* FIXME */
648 *plparam = (LPARAM)cis;
653 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
654 DELETEITEMSTRUCT32 *dis = (DELETEITEMSTRUCT32 *)
655 HeapAlloc(SystemHeap, 0, sizeof(*dis));
657 dis->CtlType = dis16->CtlType;
658 dis->CtlID = dis16->CtlID;
659 dis->hwndItem = dis16->hwndItem;
660 dis->itemData = dis16->itemData;
661 *plparam = (LPARAM)dis;
666 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
667 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)
668 HeapAlloc(SystemHeap, 0,
669 sizeof(*mis) + sizeof(LPARAM));
671 mis->CtlType = mis16->CtlType;
672 mis->CtlID = mis16->CtlID;
673 mis->itemID = mis16->itemID;
674 mis->itemWidth = mis16->itemWidth;
675 mis->itemHeight = mis16->itemHeight;
676 mis->itemData = mis16->itemData;
677 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
678 *plparam = (LPARAM)mis;
683 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
684 DRAWITEMSTRUCT32 *dis = (DRAWITEMSTRUCT32*)HeapAlloc(SystemHeap, 0,
687 dis->CtlType = dis16->CtlType;
688 dis->CtlID = dis16->CtlID;
689 dis->itemID = dis16->itemID;
690 dis->itemAction = dis16->itemAction;
691 dis->itemState = dis16->itemState;
692 dis->hwndItem = dis16->hwndItem;
693 dis->hDC = dis16->hDC;
694 dis->itemData = dis16->itemData;
695 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
696 *plparam = (LPARAM)dis;
699 case WM_GETMINMAXINFO:
701 MINMAXINFO32 *mmi = (MINMAXINFO32 *)HeapAlloc( SystemHeap, 0,
702 sizeof(*mmi) + sizeof(LPARAM));
704 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
706 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
707 *plparam = (LPARAM)mmi;
711 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
715 MDICREATESTRUCT16 *cs16 =
716 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
717 MDICREATESTRUCT32A *cs =
718 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
719 sizeof(*cs) + sizeof(LPARAM) );
721 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
722 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
723 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
724 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
725 *plparam = (LPARAM)cs;
728 case WM_MDIGETACTIVE:
729 *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL32) );
732 *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
733 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
737 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
738 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
743 *pwparam32 = (WPARAM32)(HWND32)HIWORD(*plparam);
744 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
746 else /* message sent to MDI client */
747 *pwparam32 = wParam16;
751 NCCALCSIZE_PARAMS16 *nc16;
752 NCCALCSIZE_PARAMS32 *nc;
754 nc = (NCCALCSIZE_PARAMS32 *)HeapAlloc( SystemHeap, 0,
755 sizeof(*nc) + sizeof(LPARAM) );
757 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
758 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
761 nc->lppos = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
762 sizeof(*nc->lppos) );
763 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
764 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
765 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
767 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
768 *plparam = (LPARAM)nc;
774 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
775 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
776 sizeof(*cs) + sizeof(LPARAM) );
778 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
779 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
780 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
781 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
782 *plparam = (LPARAM)cs;
785 case WM_PARENTNOTIFY:
786 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
788 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
789 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
793 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
795 case WM_WINDOWPOSCHANGING:
796 case WM_WINDOWPOSCHANGED:
798 WINDOWPOS32 *wp = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
799 sizeof(*wp) + sizeof(LPARAM) );
801 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
803 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
804 *plparam = (LPARAM)wp;
807 case WM_ASKCBFORMATNAME:
808 case WM_DEVMODECHANGE:
809 case WM_PAINTCLIPBOARD:
810 case WM_SIZECLIPBOARD:
811 case WM_WININICHANGE:
812 fprintf( stderr, "MapMsg16To32A: message %04x needs translation\n",
816 default: /* No translation needed */
822 /**********************************************************************
823 * WINPROC_UnmapMsg16To32A
825 * Unmap a message that was mapped from 16- to 32-bit Ansi.
827 LRESULT WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
835 HeapFree( SystemHeap, 0, (LPVOID)lParam );
839 MEASUREITEMSTRUCT16 *mis16;
840 MEASUREITEMSTRUCT32 *mis = (MEASUREITEMSTRUCT32 *)lParam;
841 lParam = *(LPARAM *)(mis + 1);
842 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
843 mis16->itemWidth = (UINT16)mis->itemWidth;
844 mis16->itemHeight = (UINT16)mis->itemHeight;
845 HeapFree( SystemHeap, 0, mis );
848 case WM_GETMINMAXINFO:
850 MINMAXINFO32 *mmi = (MINMAXINFO32 *)lParam;
851 lParam = *(LPARAM *)(mmi + 1);
852 STRUCT32_MINMAXINFO32to16( mmi,
853 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
854 HeapFree( SystemHeap, 0, mmi );
859 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
860 lParam = *(LPARAM *)(cs + 1);
861 STRUCT32_MDICREATESTRUCT32Ato16( cs,
862 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
863 HeapFree( SystemHeap, 0, cs );
866 case WM_MDIGETACTIVE:
867 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL32 *)lParam) );
868 HeapFree( SystemHeap, 0, (BOOL32 *)lParam );
872 NCCALCSIZE_PARAMS16 *nc16;
873 NCCALCSIZE_PARAMS32 *nc = (NCCALCSIZE_PARAMS32 *)lParam;
874 lParam = *(LPARAM *)(nc + 1);
875 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
876 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
879 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
880 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
883 STRUCT32_WINDOWPOS32to16( nc->lppos,
884 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
885 HeapFree( SystemHeap, 0, nc->lppos );
888 HeapFree( SystemHeap, 0, nc );
894 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
895 lParam = *(LPARAM *)(cs + 1);
896 STRUCT32_CREATESTRUCT32Ato16( cs,
897 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
898 HeapFree( SystemHeap, 0, cs );
901 case WM_WINDOWPOSCHANGING:
902 case WM_WINDOWPOSCHANGED:
904 WINDOWPOS32 *wp = (WINDOWPOS32 *)lParam;
905 lParam = *(LPARAM *)(wp + 1);
906 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
907 HeapFree( SystemHeap, 0, wp );
915 /**********************************************************************
916 * WINPROC_MapMsg16To32W
918 * Map a message from 16- to 32-bit Unicode.
919 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
921 INT32 WINPROC_MapMsg16To32W( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
922 WPARAM32 *pwparam32, LPARAM *plparam )
928 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
929 return WINPROC_MapMsg32ATo32W( *pmsg32, *pwparam32, plparam );
933 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
934 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
935 sizeof(*cs) + sizeof(LPARAM) );
937 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCT32A *)cs );
938 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
939 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
940 if (HIWORD(cs->lpszName))
941 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
942 (LPCSTR)cs->lpszName );
943 if (HIWORD(cs->lpszClass))
944 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
945 (LPCSTR)cs->lpszClass );
946 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
947 *plparam = (LPARAM)cs;
952 MDICREATESTRUCT16 *cs16 =
953 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
954 MDICREATESTRUCT32W *cs =
955 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
956 sizeof(*cs) + sizeof(LPARAM) );
958 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCT32A *)cs );
959 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
960 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
961 if (HIWORD(cs->szTitle))
962 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
963 (LPCSTR)cs->szTitle );
964 if (HIWORD(cs->szClass))
965 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
966 (LPCSTR)cs->szClass );
967 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
968 *plparam = (LPARAM)cs;
971 default: /* No Unicode translation needed */
972 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
973 pwparam32, plparam );
978 /**********************************************************************
979 * WINPROC_UnmapMsg16To32W
981 * Unmap a message that was mapped from 16- to 32-bit Unicode.
983 LRESULT WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
990 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
995 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
996 lParam = *(LPARAM *)(cs + 1);
997 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
998 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
999 if (HIWORD(cs->lpszName))
1000 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1001 if (HIWORD(cs->lpszClass))
1002 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1003 HeapFree( SystemHeap, 0, cs );
1008 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
1009 lParam = *(LPARAM *)(cs + 1);
1010 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
1011 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1012 if (HIWORD(cs->szTitle))
1013 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1014 if (HIWORD(cs->szClass))
1015 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1016 HeapFree( SystemHeap, 0, cs );
1020 return WINPROC_UnmapMsg16To32A( msg, wParam, lParam, result );
1026 /**********************************************************************
1027 * WINPROC_MapMsg32ATo16
1029 * Map a message from 32-bit Ansi to 16-bit.
1030 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1032 INT32 WINPROC_MapMsg32ATo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1033 UINT16 *pmsg16, WPARAM16 *pwparam16,
1036 *pmsg16 = (UINT16)msg32;
1037 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1045 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK32);
1051 case EM_SETRECTNP32:
1053 case EM_LINESCROLL32:
1054 case EM_SCROLLCARET32:
1055 case EM_GETMODIFY32:
1056 case EM_SETMODIFY32:
1057 case EM_GETLINECOUNT32:
1058 case EM_LINEINDEX32:
1059 case EM_SETHANDLE32:
1060 case EM_GETHANDLE32:
1062 case EM_LINELENGTH32:
1063 case EM_REPLACESEL32:
1065 case EM_LIMITTEXT32:
1069 case EM_LINEFROMCHAR32:
1070 case EM_SETTABSTOPS32:
1071 case EM_SETPASSWORDCHAR32:
1072 case EM_EMPTYUNDOBUFFER32:
1073 case EM_GETFIRSTVISIBLELINE32:
1074 case EM_SETREADONLY32:
1075 case EM_SETWORDBREAKPROC32:
1076 case EM_GETWORDBREAKPROC32:
1077 case EM_GETPASSWORDCHAR32:
1078 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL32);
1083 case LB_DELETESTRING32:
1084 case LB_GETANCHORINDEX32:
1085 case LB_GETCARETINDEX32:
1087 case LB_GETCURSEL32:
1088 case LB_GETHORIZONTALEXTENT32:
1089 case LB_GETITEMDATA32:
1090 case LB_GETITEMHEIGHT32:
1092 case LB_GETSELCOUNT32:
1093 case LB_GETTEXTLEN32:
1094 case LB_GETTOPINDEX32:
1095 case LB_RESETCONTENT32:
1096 case LB_SELITEMRANGE32:
1097 case LB_SELITEMRANGEEX32:
1098 case LB_SETANCHORINDEX32:
1099 case LB_SETCARETINDEX32:
1100 case LB_SETCOLUMNWIDTH32:
1101 case LB_SETCURSEL32:
1102 case LB_SETHORIZONTALEXTENT32:
1103 case LB_SETITEMDATA32:
1104 case LB_SETITEMHEIGHT32:
1106 case LB_SETTOPINDEX32:
1107 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1109 case CB_DELETESTRING32:
1111 case CB_GETLBTEXTLEN32:
1112 case CB_LIMITTEXT32:
1113 case CB_RESETCONTENT32:
1114 case CB_SETEDITSEL32:
1115 case CB_GETCURSEL32:
1116 case CB_SETCURSEL32:
1117 case CB_SHOWDROPDOWN32:
1118 case CB_SETITEMDATA32:
1119 case CB_SETITEMHEIGHT32:
1120 case CB_GETITEMHEIGHT32:
1121 case CB_SETEXTENDEDUI32:
1122 case CB_GETEXTENDEDUI32:
1123 case CB_GETDROPPEDSTATE32:
1124 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1126 case CB_GETEDITSEL32:
1127 *pmsg16 = CB_GETEDITSEL16;
1130 case LB_ADDSTRING32:
1131 case LB_FINDSTRING32:
1132 case LB_FINDSTRINGEXACT32:
1133 case LB_INSERTSTRING32:
1134 case LB_SELECTSTRING32:
1138 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1139 if (!str) return -1;
1140 *plparam = (LPARAM)SEGPTR_GET(str);
1142 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1145 case CB_ADDSTRING32:
1146 case CB_FINDSTRING32:
1147 case CB_FINDSTRINGEXACT32:
1148 case CB_INSERTSTRING32:
1149 case CB_SELECTSTRING32:
1152 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1153 if (!str) return -1;
1154 *plparam = (LPARAM)SEGPTR_GET(str);
1156 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL32);
1159 case LB_GETITEMRECT32:
1162 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1163 if (!rect) return -1;
1164 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1165 *plparam = (LPARAM)SEGPTR_GET(rect);
1167 *pmsg16 = LB_GETITEMRECT16;
1169 case LB_GETSELITEMS32:
1172 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1173 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1174 + sizeof(LPARAM)))) return -1;
1175 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1176 *plparam = (LPARAM)SEGPTR_GET(items);
1178 *pmsg16 = LB_GETSELITEMS16;
1180 case LB_SETTABSTOPS32:
1185 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1186 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1187 + sizeof(LPARAM)))) return -1;
1188 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT32)*plparam+i);
1189 *plparam = (LPARAM)SEGPTR_GET(stops);
1192 *pmsg16 = LB_SETTABSTOPS16;
1195 case CB_GETDROPPEDCONTROLRECT32:
1198 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1199 if (!rect) return -1;
1200 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1201 *plparam = (LPARAM)SEGPTR_GET(rect);
1203 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1207 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1208 *pmsg16 = LB_GETTEXT16;
1211 case CB_GETLBTEXT32:
1212 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1213 *pmsg16 = CB_GETLBTEXT16;
1218 *plparam = MAKELONG( (INT16)(INT32)wParam32, (INT16)*plparam );
1219 *pmsg16 = EM_SETSEL16;
1226 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1230 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1232 case WM_CTLCOLORMSGBOX:
1233 case WM_CTLCOLOREDIT:
1234 case WM_CTLCOLORLISTBOX:
1235 case WM_CTLCOLORBTN:
1236 case WM_CTLCOLORDLG:
1237 case WM_CTLCOLORSCROLLBAR:
1238 case WM_CTLCOLORSTATIC:
1239 *pmsg16 = WM_CTLCOLOR;
1240 *plparam = MAKELPARAM( (HWND16)*plparam,
1241 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1243 case WM_COMPAREITEM:
1245 COMPAREITEMSTRUCT32 *cis32 = (COMPAREITEMSTRUCT32 *)*plparam;
1246 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1247 if (!cis) return -1;
1248 cis->CtlType = (UINT16)cis32->CtlType;
1249 cis->CtlID = (UINT16)cis32->CtlID;
1250 cis->hwndItem = (HWND16)cis32->hwndItem;
1251 cis->itemID1 = (UINT16)cis32->itemID1;
1252 cis->itemData1 = cis32->itemData1;
1253 cis->itemID2 = (UINT16)cis32->itemID2;
1254 cis->itemData2 = cis32->itemData2;
1255 *plparam = (LPARAM)SEGPTR_GET(cis);
1260 DELETEITEMSTRUCT32 *dis32 = (DELETEITEMSTRUCT32 *)*plparam;
1261 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1262 if (!dis) return -1;
1263 dis->CtlType = (UINT16)dis32->CtlType;
1264 dis->CtlID = (UINT16)dis32->CtlID;
1265 dis->itemID = (UINT16)dis32->itemID;
1266 dis->hwndItem = (HWND16)dis32->hwndItem;
1267 dis->itemData = dis32->itemData;
1268 *plparam = (LPARAM)SEGPTR_GET(dis);
1273 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)*plparam;
1274 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1275 if (!dis) return -1;
1276 dis->CtlType = (UINT16)dis32->CtlType;
1277 dis->CtlID = (UINT16)dis32->CtlID;
1278 dis->itemID = (UINT16)dis32->itemID;
1279 dis->itemAction = (UINT16)dis32->itemAction;
1280 dis->itemState = (UINT16)dis32->itemState;
1281 dis->hwndItem = (HWND16)dis32->hwndItem;
1282 dis->hDC = (HDC16)dis32->hDC;
1283 dis->itemData = dis32->itemData;
1284 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1285 *plparam = (LPARAM)SEGPTR_GET(dis);
1288 case WM_MEASUREITEM:
1290 MEASUREITEMSTRUCT32 *mis32 = (MEASUREITEMSTRUCT32 *)*plparam;
1291 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1292 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1293 if (!mis) return -1;
1294 mis->CtlType = (UINT16)mis32->CtlType;
1295 mis->CtlID = (UINT16)mis32->CtlID;
1296 mis->itemID = (UINT16)mis32->itemID;
1297 mis->itemWidth = (UINT16)mis32->itemWidth;
1298 mis->itemHeight = (UINT16)mis32->itemHeight;
1299 mis->itemData = mis32->itemData;
1300 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1301 *plparam = (LPARAM)SEGPTR_GET(mis);
1304 case WM_GETMINMAXINFO:
1306 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1308 if (!mmi) return -1;
1309 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)*plparam, mmi );
1310 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1311 *plparam = (LPARAM)SEGPTR_GET(mmi);
1317 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1318 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1319 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1320 *plparam = (LPARAM)SEGPTR_GET(str);
1325 MDICREATESTRUCT16 *cs;
1326 MDICREATESTRUCT32A *cs32 = (MDICREATESTRUCT32A *)*plparam;
1329 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1330 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1331 name = SEGPTR_STRDUP( cs32->szTitle );
1332 cls = SEGPTR_STRDUP( cs32->szClass );
1333 cs->szTitle = SEGPTR_GET(name);
1334 cs->szClass = SEGPTR_GET(cls);
1335 *plparam = (LPARAM)SEGPTR_GET(cs);
1338 case WM_MDIGETACTIVE:
1341 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1342 (HMENU16)LOWORD(*plparam) );
1343 *pwparam16 = (*plparam == 0);
1347 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1349 case WM_MDIACTIVATE:
1350 if( WIDGETS_IsControl32(WIN_FindWndPtr(hwnd), BIC32_MDICLIENT) )
1352 *pwparam16 = (HWND32)wParam32;
1357 *pwparam16 = ((HWND32)*plparam == hwnd);
1358 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1359 (HWND16)LOWORD(wParam32) );
1364 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
1365 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1368 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1372 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1373 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1374 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1379 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1380 nc->lppos = SEGPTR_GET(wp);
1382 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1383 *plparam = (LPARAM)SEGPTR_GET(nc);
1390 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)*plparam;
1393 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1394 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1395 name = SEGPTR_STRDUP( cs32->lpszName );
1396 cls = SEGPTR_STRDUP( cs32->lpszClass );
1397 cs->lpszName = SEGPTR_GET(name);
1398 cs->lpszClass = SEGPTR_GET(cls);
1399 *plparam = (LPARAM)SEGPTR_GET(cs);
1402 case WM_PARENTNOTIFY:
1403 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1404 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1405 /* else nothing to do */
1409 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1410 if (!str) return -1;
1411 *plparam = (LPARAM)SEGPTR_GET(str);
1414 case WM_WINDOWPOSCHANGING:
1415 case WM_WINDOWPOSCHANGED:
1417 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1420 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)*plparam, wp );
1421 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1422 *plparam = (LPARAM)SEGPTR_GET(wp);
1425 case WM_ASKCBFORMATNAME:
1426 case WM_DEVMODECHANGE:
1427 case WM_PAINTCLIPBOARD:
1428 case WM_SIZECLIPBOARD:
1429 case WM_WININICHANGE:
1430 fprintf( stderr, "MapMsg32ATo16: message %04x needs translation\n",
1434 default: /* No translation needed */
1440 /**********************************************************************
1441 * WINPROC_UnmapMsg32ATo16
1443 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1445 void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1451 case LB_ADDSTRING32:
1453 case LB_FINDSTRING32:
1454 case LB_FINDSTRINGEXACT32:
1455 case LB_INSERTSTRING32:
1456 case LB_SELECTSTRING32:
1457 case LB_SETTABSTOPS32:
1458 case CB_ADDSTRING32:
1459 case CB_FINDSTRING32:
1460 case CB_FINDSTRINGEXACT32:
1461 case CB_INSERTSTRING32:
1462 case CB_SELECTSTRING32:
1464 case WM_COMPAREITEM:
1468 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1471 case CB_GETDROPPEDCONTROLRECT32:
1472 case LB_GETITEMRECT32:
1474 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1475 p16->lParam = *(LPARAM *)(rect + 1);
1476 CONV_RECT16TO32( rect, (RECT32 *)(p16->lParam));
1477 SEGPTR_FREE( rect );
1480 case LB_GETSELITEMS32:
1483 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1484 p16->lParam = *((LPARAM *)items - 1);
1485 for (i = 0; i < p16->wParam; i++) *((LPINT32)(p16->lParam) + i) = items[i];
1486 SEGPTR_FREE( (LPARAM *)items - 1 );
1490 case CB_GETEDITSEL32:
1492 *((LPUINT32)(wParam)) = LOWORD(p16->lResult);
1494 *((LPUINT32)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1498 case CB_GETLBTEXT32:
1499 UnMapLS( (SEGPTR)(p16->lParam) );
1502 case WM_MEASUREITEM:
1504 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1505 MEASUREITEMSTRUCT32 *mis32 = *(MEASUREITEMSTRUCT32 **)(mis + 1);
1506 mis32->itemWidth = mis->itemWidth;
1507 mis32->itemHeight = mis->itemHeight;
1511 case WM_GETMINMAXINFO:
1513 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1514 p16->lParam = *(LPARAM *)(mmi + 1);
1515 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)(p16->lParam) );
1521 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1522 p16->lParam = *((LPARAM *)str - 1);
1523 lstrcpyn32A( (LPSTR)(p16->lParam), str, p16->wParam );
1524 SEGPTR_FREE( (LPARAM *)str - 1 );
1529 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1530 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1531 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1535 case WM_MDIGETACTIVE:
1536 if (lParam) *(BOOL32 *)lParam = (BOOL16)HIWORD(p16->lResult);
1537 p16->lResult = (HWND32)LOWORD(p16->lResult);
1541 NCCALCSIZE_PARAMS32 *nc32;
1542 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
1543 p16->lParam = *(LPARAM *)(nc + 1);
1544 nc32 = (NCCALCSIZE_PARAMS32 *)(p16->lParam);
1545 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1548 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1549 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1550 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1552 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1560 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1561 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1562 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1566 case WM_WINDOWPOSCHANGING:
1567 case WM_WINDOWPOSCHANGED:
1569 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
1570 p16->lParam = *(LPARAM *)(wp + 1);
1571 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)p16->lParam );
1579 /**********************************************************************
1580 * WINPROC_MapMsg32WTo16
1582 * Map a message from 32-bit Unicode to 16-bit.
1583 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1585 INT32 WINPROC_MapMsg32WTo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
1586 UINT16 *pmsg16, WPARAM16 *pwparam16,
1591 case LB_ADDSTRING32:
1592 case LB_FINDSTRING32:
1593 case LB_FINDSTRINGEXACT32:
1594 case LB_INSERTSTRING32:
1595 case LB_SELECTSTRING32:
1599 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1600 if (!str) return -1;
1601 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1602 *plparam = (LPARAM)SEGPTR_GET(str);
1604 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
1607 case CB_ADDSTRING32:
1608 case CB_FINDSTRING32:
1609 case CB_FINDSTRINGEXACT32:
1610 case CB_INSERTSTRING32:
1611 case CB_SELECTSTRING32:
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 + (CB_ADDSTRING16 - CB_ADDSTRING32);
1626 CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
1629 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1630 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
1631 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
1632 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
1633 cs->lpszName = SEGPTR_GET(name);
1634 cs->lpszClass = SEGPTR_GET(cls);
1635 *pmsg16 = (UINT16)msg32;
1636 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1637 *plparam = (LPARAM)SEGPTR_GET(cs);
1642 MDICREATESTRUCT16 *cs;
1643 MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
1646 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1647 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
1648 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
1649 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
1650 cs->szTitle = SEGPTR_GET(name);
1651 cs->szClass = SEGPTR_GET(cls);
1652 *pmsg16 = (UINT16)msg32;
1653 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1654 *plparam = (LPARAM)SEGPTR_GET(cs);
1659 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
1660 if (!str) return -1;
1661 *pmsg16 = (UINT16)msg32;
1662 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1663 *plparam = (LPARAM)SEGPTR_GET(str);
1666 default: /* No Unicode translation needed */
1667 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
1668 pwparam16, plparam );
1673 /**********************************************************************
1674 * WINPROC_UnmapMsg32WTo16
1676 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1678 void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
1685 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1686 p16->lParam = *((LPARAM *)str - 1);
1687 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
1688 SEGPTR_FREE( (LPARAM *)str - 1 );
1692 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, p16 );
1698 /**********************************************************************
1699 * WINPROC_CallProc32ATo32W
1701 * Call a window procedure, translating args from Ansi to Unicode.
1703 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
1704 UINT32 msg, WPARAM32 wParam,
1709 if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
1710 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1711 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1716 /**********************************************************************
1717 * WINPROC_CallProc32WTo32A
1719 * Call a window procedure, translating args from Unicode to Ansi.
1721 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
1722 UINT32 msg, WPARAM32 wParam,
1727 if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
1728 result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1729 WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
1734 /**********************************************************************
1735 * WINPROC_CallProc16To32A
1737 * Call a 32-bit window procedure, translating the 16-bit args.
1739 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
1740 WPARAM16 wParam, LPARAM lParam,
1747 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1749 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1750 return WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam, result );
1754 /**********************************************************************
1755 * WINPROC_CallProc16To32W
1757 * Call a 32-bit window procedure, translating the 16-bit args.
1759 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
1760 WPARAM16 wParam, LPARAM lParam,
1767 if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1769 result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1770 return WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam, result );
1774 /**********************************************************************
1775 * WINPROC_CallProc32ATo16
1777 * Call a 16-bit window procedure, translating the 32-bit args.
1779 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
1780 UINT32 msg, WPARAM32 wParam,
1786 mp16.lParam = lParam;
1787 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
1788 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
1790 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1791 mp16.wParam, mp16.lParam );
1792 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, &mp16 );
1793 return mp16.lResult;
1797 /**********************************************************************
1798 * WINPROC_CallProc32WTo16
1800 * Call a 16-bit window procedure, translating the 32-bit args.
1802 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
1803 UINT32 msg, WPARAM32 wParam,
1809 mp16.lParam = lParam;
1810 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
1811 &mp16.lParam ) == -1)
1813 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
1814 mp16.wParam, mp16.lParam );
1815 WINPROC_UnmapMsg32WTo16( msg, wParam, lParam, &mp16 );
1816 return mp16.lResult;
1820 /**********************************************************************
1821 * CallWindowProc16 (USER.122)
1823 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
1824 WPARAM16 wParam, LPARAM lParam )
1826 WINDOWPROC *proc = WINPROC_GetPtr( func );
1829 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1832 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
1833 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
1839 if (!proc->thunk.t_from32.proc) return 0;
1840 return Callbacks->CallWndProc( proc->thunk.t_from32.proc,
1841 hwnd, msg, wParam, lParam );
1843 if (!proc->thunk.t_from16.proc) return 0;
1844 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
1845 proc->thunk.t_from16.proc );
1847 if (!proc->thunk.t_from16.proc) return 0;
1848 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
1849 proc->thunk.t_from16.proc );
1851 fprintf( stderr, "CallWindowProc16: invalid proc %p\n", proc );
1857 /**********************************************************************
1858 * CallWindowProc32A (USER32.17)
1860 LRESULT WINAPI CallWindowProc32A( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1861 WPARAM32 wParam, LPARAM lParam )
1863 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1865 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1868 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
1869 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1875 if (!proc->thunk.t_from32.proc) return 0;
1876 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
1877 hwnd, msg, wParam, lParam );
1879 if (!proc->thunk.t_from16.proc) return 0;
1880 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
1881 hwnd, msg, wParam, lParam );
1883 if (!proc->thunk.t_from16.proc) return 0;
1884 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
1885 hwnd, msg, wParam, lParam );
1887 fprintf( stderr, "CallWindowProc32A: invalid proc %p\n", proc );
1893 /**********************************************************************
1894 * CallWindowProc32W (USER32.18)
1896 LRESULT WINAPI CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1897 WPARAM32 wParam, LPARAM lParam )
1899 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1901 if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1904 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
1905 return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
1911 if (!proc->thunk.t_from32.proc) return 0;
1912 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
1913 hwnd, msg, wParam, lParam );
1915 if (!proc->thunk.t_from16.proc) return 0;
1916 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
1917 hwnd, msg, wParam, lParam );
1919 if (!proc->thunk.t_from16.proc) return 0;
1920 return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
1921 hwnd, msg, wParam, lParam );
1923 fprintf( stderr, "CallWindowProc32W: invalid proc %p\n", proc );