Release 960717
[wine/multimedia.git] / windows / winproc.c
blobf52a6d248a62e33ffe2476bff1ce5459d574e828
1 /*
2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
6 */
8 #include <stdio.h>
9 #include "windows.h"
10 #include "callback.h"
11 #include "heap.h"
12 #include "ldt.h"
13 #include "registers.h"
14 #include "stackframe.h"
15 #include "string32.h"
16 #include "struct32.h"
17 #include "win.h"
18 #include "winproc.h"
19 #include "stddebug.h"
20 #include "debug.h"
22 /* Window procedure 16-bit thunk; see BuildSpec16Files() in tools/build.c */
23 typedef struct
25 BYTE popl_eax; /* popl %eax (return address) */
26 BYTE pushl_func; /* pushl $proc */
27 WNDPROC32 proc WINE_PACKED;
28 BYTE pushl_eax; /* pushl %eax */
29 WORD pushw_bp WINE_PACKED; /* pushw %bp */
30 BYTE pushl_thunk; /* pushl $thunkfrom16 */
31 void (*thunk32)() WINE_PACKED;
32 BYTE lcall; /* lcall cs:relay */
33 void (*relay)() WINE_PACKED;
34 WORD cs WINE_PACKED;
35 } WINPROC_THUNK_FROM16;
37 /* Window procedure 32-bit thunk; 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 pushl_ebp; /* pushl %ebp */
45 BYTE pushl_name; /* pushl $name */
46 LPCSTR name WINE_PACKED;
47 BYTE pushl_thunk; /* pushl $thunkfrom32 */
48 void (*thunk32)() WINE_PACKED;
49 BYTE jmp; /* jmp relay (relative jump)*/
50 void (*relay)() WINE_PACKED;
51 } WINPROC_THUNK_FROM32;
53 /* Simple jmp to call 32-bit procedure directly */
54 typedef struct
56 BYTE jmp; /* jmp proc (relative jump) */
57 WNDPROC32 proc WINE_PACKED;
58 } WINPROC_JUMP;
60 typedef union
62 WINPROC_THUNK_FROM16 t_from16;
63 WINPROC_THUNK_FROM32 t_from32;
64 } WINPROC_THUNK;
66 typedef struct tagWINDOWPROC
68 WINPROC_THUNK thunk; /* Thunk */
69 WINPROC_JUMP jmp; /* Jump */
70 struct tagWINDOWPROC *next; /* Next window proc */
71 UINT32 magic; /* Magic number */
72 WINDOWPROCTYPE type; /* Function type */
73 } WINDOWPROC;
75 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
77 #define WINPROC_THUNKPROC(pproc) \
78 (((pproc)->type == WIN_PROC_16) ? \
79 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
80 (WNDPROC16)((pproc)->thunk.t_from16.proc))
82 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
83 WPARAM16 wParam, LPARAM lParam,
84 WNDPROC32 func );
85 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
86 WPARAM16 wParam, LPARAM lParam,
87 WNDPROC32 func );
88 static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
89 UINT32 msg, WPARAM32 wParam,
90 LPARAM lParam );
91 static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
92 UINT32 msg, WPARAM32 wParam,
93 LPARAM lParam );
95 #ifndef WINELIB
96 extern void CallFrom16_long_wwwll(void);
97 extern void CallFrom32_stdcall_5(void);
98 #else
99 static void CallFrom16_long_wwwll(void) {}
100 static void CallFrom32_stdcall_5(void) {}
101 #endif /* WINELIB */
103 static HANDLE32 WinProcHeap;
105 /**********************************************************************
106 * WINPROC_Init
108 BOOL32 WINPROC_Init(void)
110 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
111 if (!WinProcHeap)
113 fprintf( stderr, "Unable to create winproc heap\n" );
114 return FALSE;
116 return TRUE;
120 /**********************************************************************
121 * WINPROC_GetPtr
123 * Return a pointer to the win proc.
125 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
127 BYTE *ptr;
128 WINDOWPROC *proc;
130 /* Check for a linear pointer */
132 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
134 ptr = (BYTE *)handle;
135 /* First check if it is the jmp address */
136 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
137 (int)&((WINDOWPROC *)0)->thunk;
138 /* Now it must be the thunk address */
139 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
140 /* Now we have a pointer to the WINDOWPROC struct */
141 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
142 return (WINDOWPROC *)ptr;
145 /* Check for a segmented pointer */
147 if (!IsBadReadPtr( (SEGPTR)handle, sizeof(WINDOWPROC)-sizeof(proc->thunk)))
149 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
150 /* It must be the thunk address */
151 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
152 /* Now we have a pointer to the WINDOWPROC struct */
153 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
154 return (WINDOWPROC *)ptr;
157 return NULL;
161 /**********************************************************************
162 * WINPROC_AllocWinProc
164 * Allocate a new window procedure.
166 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type )
168 WINDOWPROC *proc, *oldproc;
170 /* Allocate a window procedure */
172 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
174 /* Check if the function is already a win proc */
176 if ((oldproc = WINPROC_GetPtr( func )))
178 *proc = *oldproc;
180 else
182 switch(type)
184 case WIN_PROC_16:
185 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
186 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
187 proc->thunk.t_from32.proc = func;
188 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
189 proc->thunk.t_from32.pushl_ebp = 0x55; /* pushl %ebp */
190 proc->thunk.t_from32.pushl_name = 0x68; /* pushl $name */
191 proc->thunk.t_from32.name = "WINPROC_CallProc32ATo16";
192 proc->thunk.t_from32.pushl_thunk = 0x68; /* pushl $thunkfrom32 */
193 proc->thunk.t_from32.thunk32 = (void(*)())WINPROC_CallProc32ATo16;
194 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
195 proc->thunk.t_from32.relay = /* relative jump */
196 (void (*)())((DWORD)CallFrom32_stdcall_5 -
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 = CallFrom16_long_wwwll;
212 proc->thunk.t_from16.cs = WINE_CODE_SELECTOR;
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;
225 proc->next = NULL;
226 dprintf_win( stddeb, "WINPROC_AllocWinProc(%08x,%d): returning %08x\n",
227 (UINT32)func, type, (UINT32)proc );
228 return proc;
232 /**********************************************************************
233 * WINPROC_GetProc
235 * Get a window procedure pointer that can be passed to the Windows program.
237 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
239 if (type == WIN_PROC_16) /* We want a 16:16 address */
241 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
242 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
243 else
244 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
245 &((WINDOWPROC *)proc)->thunk );
247 else /* We want a 32-bit address */
249 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
250 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
251 else
252 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
257 /**********************************************************************
258 * WINPROC_SetProc
260 * Set the window procedure for a window or class.
262 BOOL32 WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
263 WINDOWPROCTYPE type )
265 WINDOWPROC *proc, **ppPrev;
267 /* Check if function is already in the list */
269 ppPrev = (WINDOWPROC **)pFirst;
270 proc = WINPROC_GetPtr( func );
271 while (*ppPrev)
273 if (proc)
275 if (*ppPrev == proc) break;
277 else
279 if (((*ppPrev)->type == type) &&
280 (func == WINPROC_THUNKPROC(*ppPrev))) break;
282 ppPrev = &(*ppPrev)->next;
285 if (*ppPrev) /* Remove it from the list */
287 proc = *ppPrev;
288 *ppPrev = proc->next;
290 else /* Allocate a new one */
292 if (proc) /* Was already a win proc */
294 type = proc->type;
295 func = WINPROC_THUNKPROC(proc);
297 proc = WINPROC_AllocWinProc( func, type );
298 if (!proc) return FALSE;
301 /* Add the win proc at the head of the list */
303 dprintf_win( stddeb, "WINPROC_SetProc(%08x,%08x,%d): res=%08x\n",
304 (UINT32)*pFirst, (UINT32)func, type, (UINT32)proc );
305 proc->next = *(WINDOWPROC **)pFirst;
306 *(WINDOWPROC **)pFirst = proc;
307 return TRUE;
311 /**********************************************************************
312 * WINPROC_FreeProc
314 * Free a list of win procs.
316 void WINPROC_FreeProc( HWINDOWPROC proc )
318 while (proc)
320 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
321 dprintf_win( stddeb, "WINPROC_FreeProc: freeing %08x\n", (UINT32)proc);
322 HeapFree( WinProcHeap, 0, proc );
323 proc = next;
328 /**********************************************************************
329 * WINPROC_GetProcType
331 * Return the window procedure type.
333 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
335 if (!proc ||
336 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
337 return WIN_PROC_INVALID;
338 return ((WINDOWPROC *)proc)->type;
342 /**********************************************************************
343 * WINPROC_MapMsg32ATo32W
345 * Map a message from Ansi to Unicode.
346 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
348 INT32 WINPROC_MapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
350 switch(msg)
352 case WM_GETTEXT:
354 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
355 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
356 if (!ptr) return -1;
357 *ptr++ = *plparam; /* Store previous lParam */
358 *plparam = (LPARAM)ptr;
360 return 1;
361 case WM_SETTEXT:
362 *plparam = (LPARAM)STRING32_DupAnsiToUni( (LPCSTR)*plparam );
363 return (*plparam ? 1 : -1);
364 case WM_NCCREATE:
365 case WM_CREATE:
367 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
368 sizeof(*cs) );
369 if (!cs) return -1;
370 *cs = *(CREATESTRUCT32W *)*plparam;
371 if (HIWORD(cs->lpszName))
372 cs->lpszName = STRING32_DupAnsiToUni( (LPCSTR)cs->lpszName );
373 if (HIWORD(cs->lpszClass))
374 cs->lpszClass = STRING32_DupAnsiToUni( (LPCSTR)cs->lpszClass );
375 *plparam = (LPARAM)cs;
377 return 1;
378 case WM_MDICREATE:
380 MDICREATESTRUCT32W *cs =
381 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
382 if (!cs) return -1;
383 *cs = *(MDICREATESTRUCT32W *)*plparam;
384 if (HIWORD(cs->szClass))
385 cs->szClass = STRING32_DupAnsiToUni( (LPCSTR)cs->szClass );
386 if (HIWORD(cs->szTitle))
387 cs->szTitle = STRING32_DupAnsiToUni( (LPCSTR)cs->szTitle );
388 *plparam = (LPARAM)cs;
390 return 1;
391 case WM_ASKCBFORMATNAME:
392 case WM_COMPAREITEM:
393 case WM_DELETEITEM:
394 case WM_DEVMODECHANGE:
395 case WM_MDIACTIVATE:
396 case WM_MEASUREITEM:
397 case WM_PAINTCLIPBOARD:
398 case WM_SIZECLIPBOARD:
399 case WM_WININICHANGE:
400 fprintf( stderr, "MapMsg32ATo32W: message %04x needs translation\n",
401 msg );
402 return -1;
403 default: /* No translation needed */
404 return 0;
409 /**********************************************************************
410 * WINPROC_UnmapMsg32ATo32W
412 * Unmap a message that was mapped from Ansi to Unicode.
414 void WINPROC_UnmapMsg32ATo32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
416 switch(msg)
418 case WM_GETTEXT:
420 LPARAM *ptr = (LPARAM *)lParam - 1;
421 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)(ptr + 1), wParam );
422 HeapFree( SystemHeap, 0, ptr );
424 break;
425 case WM_SETTEXT:
426 free( (void *)lParam );
427 break;
428 case WM_NCCREATE:
429 case WM_CREATE:
431 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
432 if (HIWORD(cs->lpszName)) free( (LPVOID)cs->lpszName );
433 if (HIWORD(cs->lpszClass)) free( (LPVOID)cs->lpszClass );
434 HeapFree( SystemHeap, 0, cs );
436 break;
437 case WM_MDICREATE:
439 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
440 if (HIWORD(cs->szTitle)) free( (LPVOID)cs->szTitle );
441 if (HIWORD(cs->szClass)) free( (LPVOID)cs->szClass );
442 HeapFree( SystemHeap, 0, cs );
444 break;
449 /**********************************************************************
450 * WINPROC_MapMsg32WTo32A
452 * Map a message from Unicode to Ansi.
453 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
455 INT32 WINPROC_MapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM *plparam )
457 switch(msg)
459 case WM_GETTEXT:
461 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
462 wParam + sizeof(LPARAM) );
463 if (!ptr) return -1;
464 *ptr++ = *plparam; /* Store previous lParam */
465 *plparam = (LPARAM)ptr;
467 return 1;
468 case WM_SETTEXT:
469 *plparam = (LPARAM)STRING32_DupUniToAnsi( (LPCWSTR)*plparam );
470 return (*plparam ? 1 : -1);
471 case WM_NCCREATE:
472 case WM_CREATE:
474 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
475 sizeof(*cs) );
476 if (!cs) return -1;
477 *cs = *(CREATESTRUCT32A *)*plparam;
478 if (HIWORD(cs->lpszName))
479 cs->lpszName = STRING32_DupUniToAnsi( (LPCWSTR)cs->lpszName );
480 if (HIWORD(cs->lpszClass))
481 cs->lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs->lpszClass);
482 *plparam = (LPARAM)cs;
484 return 1;
485 case WM_MDICREATE:
487 MDICREATESTRUCT32A *cs =
488 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
489 if (!cs) return -1;
490 *cs = *(MDICREATESTRUCT32A *)*plparam;
491 if (HIWORD(cs->szTitle))
492 cs->szTitle = STRING32_DupUniToAnsi( (LPCWSTR)cs->szTitle );
493 if (HIWORD(cs->szClass))
494 cs->szClass = STRING32_DupUniToAnsi( (LPCWSTR)cs->szClass );
495 *plparam = (LPARAM)cs;
497 return 1;
498 case WM_ASKCBFORMATNAME:
499 case WM_COMPAREITEM:
500 case WM_DELETEITEM:
501 case WM_DEVMODECHANGE:
502 case WM_MDIACTIVATE:
503 case WM_MEASUREITEM:
504 case WM_PAINTCLIPBOARD:
505 case WM_SIZECLIPBOARD:
506 case WM_WININICHANGE:
507 fprintf( stderr, "MapMsg32WTo32A: message %04x needs translation\n",
508 msg );
509 return -1;
510 default: /* No translation needed */
511 return 0;
516 /**********************************************************************
517 * WINPROC_UnmapMsg32WTo32A
519 * Unmap a message that was mapped from Unicode to Ansi.
521 void WINPROC_UnmapMsg32WTo32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
523 switch(msg)
525 case WM_GETTEXT:
527 LPARAM *ptr = (LPARAM *)lParam - 1;
528 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)(ptr + 1), wParam );
529 HeapFree( SystemHeap, 0, ptr );
531 break;
532 case WM_SETTEXT:
533 free( (void *)lParam );
534 break;
535 case WM_NCCREATE:
536 case WM_CREATE:
538 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
539 if (HIWORD(cs->lpszName)) free( (LPVOID)cs->lpszName );
540 if (HIWORD(cs->lpszClass)) free( (LPVOID)cs->lpszClass );
541 HeapFree( SystemHeap, 0, cs );
543 break;
544 case WM_MDICREATE:
546 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
547 if (HIWORD(cs->szTitle)) free( (LPVOID)cs->szTitle );
548 if (HIWORD(cs->szClass)) free( (LPVOID)cs->szClass );
549 HeapFree( SystemHeap, 0, cs );
551 break;
556 /**********************************************************************
557 * WINPROC_MapMsg16To32A
559 * Map a message from 16- to 32-bit Ansi.
560 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
562 INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
563 WPARAM32 *pwparam32, LPARAM *plparam )
565 *pmsg32 = (UINT32)msg16;
566 *pwparam32 = (WPARAM32)wParam16;
567 switch(msg16)
569 case WM_ACTIVATE:
570 case WM_CHARTOITEM:
571 case WM_COMMAND:
572 case WM_HSCROLL:
573 case WM_VKEYTOITEM:
574 case WM_VSCROLL:
575 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
576 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
577 return 0;
578 case WM_CTLCOLOR:
579 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
580 *pwparam32 = (WPARAM32)(HDC32)wParam16;
581 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
582 return 0;
583 case WM_DRAWITEM:
585 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
586 DRAWITEMSTRUCT32 *dis = (DRAWITEMSTRUCT32*)HeapAlloc(SystemHeap, 0,
587 sizeof(*dis));
588 if (!dis) return -1;
589 dis->CtlType = dis16->CtlType;
590 dis->CtlID = dis16->CtlID;
591 dis->itemID = dis16->itemID;
592 dis->itemAction = dis16->itemAction;
593 dis->itemState = dis16->itemState;
594 dis->hwndItem = dis16->hwndItem;
595 dis->hDC = dis16->hDC;
596 dis->itemData = dis16->itemData;
597 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
598 *plparam = (LPARAM)dis;
600 return 1;
601 case WM_GETMINMAXINFO:
603 MINMAXINFO32 *mmi = (MINMAXINFO32 *)HeapAlloc( SystemHeap, 0,
604 sizeof(*mmi) + sizeof(LPARAM));
605 if (!mmi) return -1;
606 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
607 mmi );
608 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
609 *plparam = (LPARAM)mmi;
611 return 1;
612 case WM_GETTEXT:
613 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
614 return 0;
615 case WM_MDICREATE:
617 MDICREATESTRUCT16 *cs16 =
618 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
619 MDICREATESTRUCT32A *cs =
620 (MDICREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
621 sizeof(*cs) + sizeof(LPARAM) );
622 if (!cs) return -1;
623 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
624 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
625 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
626 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
627 *plparam = (LPARAM)cs;
629 return 1;
630 case WM_MDISETMENU:
631 *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
632 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
633 return 0;
634 case WM_MENUCHAR:
635 case WM_MENUSELECT:
636 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
637 *plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
638 return 0;
639 case WM_NCCALCSIZE:
641 NCCALCSIZE_PARAMS16 *nc16;
642 NCCALCSIZE_PARAMS32 *nc;
644 nc = (NCCALCSIZE_PARAMS32 *)HeapAlloc( SystemHeap, 0,
645 sizeof(*nc) + sizeof(LPARAM) );
646 if (!nc) return -1;
647 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
648 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
649 if (wParam16)
651 nc->lppos = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
652 sizeof(*nc->lppos) );
653 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
654 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
655 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
657 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
658 *plparam = (LPARAM)nc;
660 return 1;
661 case WM_NCCREATE:
662 case WM_CREATE:
664 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
665 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)HeapAlloc( SystemHeap, 0,
666 sizeof(*cs) + sizeof(LPARAM) );
667 if (!cs) return -1;
668 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
669 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
670 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
671 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
672 *plparam = (LPARAM)cs;
674 return 1;
675 case WM_PARENTNOTIFY:
676 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
678 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
679 *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
681 else
683 *pwparam32 = MAKEWPARAM( wParam16, 0 /* FIXME? */ );
685 return 0;
686 case WM_SETTEXT:
687 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
688 return 0;
689 case WM_WINDOWPOSCHANGING:
690 case WM_WINDOWPOSCHANGED:
692 WINDOWPOS32 *wp = (WINDOWPOS32 *)HeapAlloc( SystemHeap, 0,
693 sizeof(*wp) + sizeof(LPARAM) );
694 if (!wp) return -1;
695 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
696 wp );
697 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
698 *plparam = (LPARAM)wp;
700 return 1;
701 case WM_ASKCBFORMATNAME:
702 case WM_COMPAREITEM:
703 case WM_DELETEITEM:
704 case WM_DEVMODECHANGE:
705 case WM_MDIACTIVATE:
706 case WM_MEASUREITEM:
707 case WM_PAINTCLIPBOARD:
708 case WM_SIZECLIPBOARD:
709 case WM_WININICHANGE:
710 fprintf( stderr, "MapMsg16To32A: message %04x needs translation\n",
711 msg16 );
712 return -1;
714 default: /* No translation needed */
715 return 0;
720 /**********************************************************************
721 * WINPROC_UnmapMsg16To32A
723 * Unmap a message that was mapped from 16- to 32-bit Ansi.
725 void WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
727 switch(msg)
729 case WM_DRAWITEM:
730 HeapFree( SystemHeap, 0, (LPVOID)lParam );
731 break;
732 case WM_GETMINMAXINFO:
734 MINMAXINFO32 *mmi = (MINMAXINFO32 *)lParam;
735 lParam = *(LPARAM *)(mmi + 1);
736 STRUCT32_MINMAXINFO32to16( mmi,
737 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
738 HeapFree( SystemHeap, 0, mmi );
740 break;
741 case WM_MDICREATE:
743 MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
744 lParam = *(LPARAM *)(cs + 1);
745 STRUCT32_MDICREATESTRUCT32Ato16( cs,
746 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
747 HeapFree( SystemHeap, 0, cs );
749 break;
750 case WM_NCCALCSIZE:
752 NCCALCSIZE_PARAMS16 *nc16;
753 NCCALCSIZE_PARAMS32 *nc = (NCCALCSIZE_PARAMS32 *)lParam;
754 lParam = *(LPARAM *)(nc + 1);
755 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
756 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
757 if (wParam)
759 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
760 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
761 if (nc->lppos)
763 STRUCT32_WINDOWPOS32to16( nc->lppos,
764 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
765 HeapFree( SystemHeap, 0, nc->lppos );
768 HeapFree( SystemHeap, 0, nc );
770 break;
771 case WM_NCCREATE:
772 case WM_CREATE:
774 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
775 lParam = *(LPARAM *)(cs + 1);
776 STRUCT32_CREATESTRUCT32Ato16( cs,
777 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
778 HeapFree( SystemHeap, 0, cs );
780 break;
781 case WM_WINDOWPOSCHANGING:
782 case WM_WINDOWPOSCHANGED:
784 WINDOWPOS32 *wp = (WINDOWPOS32 *)lParam;
785 lParam = *(LPARAM *)(wp + 1);
786 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
787 HeapFree( SystemHeap, 0, wp );
789 break;
794 /**********************************************************************
795 * WINPROC_MapMsg16To32W
797 * Map a message from 16- to 32-bit Unicode.
798 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
800 INT32 WINPROC_MapMsg16To32W( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32,
801 WPARAM32 *pwparam32, LPARAM *plparam )
803 switch(msg16)
805 case WM_GETTEXT:
806 case WM_SETTEXT:
807 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
808 return WINPROC_MapMsg32ATo32W( *pmsg32, *pwparam32, plparam );
809 case WM_NCCREATE:
810 case WM_CREATE:
812 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
813 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
814 sizeof(*cs) + sizeof(LPARAM) );
815 if (!cs) return -1;
816 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCT32A *)cs );
817 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
818 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
819 if (HIWORD(cs->lpszName))
820 cs->lpszName = STRING32_DupAnsiToUni( (LPCSTR)cs->lpszName );
821 if (HIWORD(cs->lpszClass))
822 cs->lpszClass = STRING32_DupAnsiToUni( (LPCSTR)cs->lpszClass );
823 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
824 *plparam = (LPARAM)cs;
826 return 1;
827 case WM_MDICREATE:
829 MDICREATESTRUCT16 *cs16 =
830 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
831 MDICREATESTRUCT32W *cs =
832 (MDICREATESTRUCT32W *)HeapAlloc( SystemHeap, 0,
833 sizeof(*cs) + sizeof(LPARAM) );
834 if (!cs) return -1;
835 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCT32A *)cs );
836 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
837 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
838 if (HIWORD(cs->szTitle))
839 cs->szTitle = STRING32_DupAnsiToUni( (LPCSTR)cs->szTitle );
840 if (HIWORD(cs->szClass))
841 cs->szClass = STRING32_DupAnsiToUni( (LPCSTR)cs->szClass );
842 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
843 *plparam = (LPARAM)cs;
845 return 1;
846 default: /* No Unicode translation needed */
847 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
848 pwparam32, plparam );
853 /**********************************************************************
854 * WINPROC_UnmapMsg16To32W
856 * Unmap a message that was mapped from 16- to 32-bit Unicode.
858 void WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
860 switch(msg)
862 case WM_GETTEXT:
863 case WM_SETTEXT:
864 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
865 break;
866 case WM_NCCREATE:
867 case WM_CREATE:
869 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
870 lParam = *(LPARAM *)(cs + 1);
871 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
872 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
873 if (HIWORD(cs->lpszName)) free( (LPVOID)cs->lpszName );
874 if (HIWORD(cs->lpszClass)) free( (LPVOID)cs->lpszClass );
875 HeapFree( SystemHeap, 0, cs );
877 break;
878 case WM_MDICREATE:
880 MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
881 lParam = *(LPARAM *)(cs + 1);
882 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
883 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
884 if (HIWORD(cs->szTitle)) free( (LPVOID)cs->szTitle );
885 if (HIWORD(cs->szClass)) free( (LPVOID)cs->szClass );
886 HeapFree( SystemHeap, 0, cs );
888 break;
889 default:
890 WINPROC_UnmapMsg16To32A( msg, wParam, lParam );
891 break;
896 /**********************************************************************
897 * WINPROC_MapMsg32ATo16
899 * Map a message from 32-bit Ansi to 16-bit.
900 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
902 INT32 WINPROC_MapMsg32ATo16( UINT32 msg32, WPARAM32 wParam32, UINT16 *pmsg16,
903 WPARAM16 *pwparam16, LPARAM *plparam )
905 *pmsg16 = (UINT16)msg32;
906 *pwparam16 = (WPARAM16)LOWORD(wParam32);
907 switch(msg32)
909 case WM_ACTIVATE:
910 case WM_CHARTOITEM:
911 case WM_COMMAND:
912 case WM_VKEYTOITEM:
913 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
914 return 0;
915 case WM_HSCROLL:
916 case WM_VSCROLL:
917 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
918 return 0;
919 case WM_CTLCOLORMSGBOX:
920 case WM_CTLCOLOREDIT:
921 case WM_CTLCOLORLISTBOX:
922 case WM_CTLCOLORBTN:
923 case WM_CTLCOLORDLG:
924 case WM_CTLCOLORSCROLLBAR:
925 case WM_CTLCOLORSTATIC:
926 *pmsg16 = WM_CTLCOLOR;
927 *plparam = MAKELPARAM( (HWND16)*plparam,
928 (WORD)msg32 - WM_CTLCOLORMSGBOX );
929 return 0;
930 case WM_DRAWITEM:
932 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)*plparam;
933 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
934 if (!dis) return -1;
935 dis->CtlType = (UINT16)dis32->CtlType;
936 dis->CtlID = (UINT16)dis32->CtlID;
937 dis->itemID = (UINT16)dis32->itemID;
938 dis->itemAction = (UINT16)dis32->itemAction;
939 dis->itemState = (UINT16)dis32->itemState;
940 dis->hwndItem = (HWND16)dis32->hwndItem;
941 dis->hDC = (HDC16)dis32->hDC;
942 dis->itemData = dis32->itemData;
943 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
944 *plparam = (LPARAM)SEGPTR_GET(dis);
946 return 1;
947 case WM_GETMINMAXINFO:
949 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
950 sizeof(LPARAM) );
951 if (!mmi) return -1;
952 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)*plparam, mmi );
953 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
954 *plparam = (LPARAM)SEGPTR_GET(mmi);
956 return 1;
957 case WM_GETTEXT:
959 LPSTR str;
960 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
961 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
962 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
963 *plparam = (LPARAM)SEGPTR_GET(str);
965 return 1;
966 case WM_MDICREATE:
968 MDICREATESTRUCT16 *cs;
969 MDICREATESTRUCT32A *cs32 = (MDICREATESTRUCT32A *)*plparam;
970 LPSTR name, cls;
972 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
973 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
974 name = SEGPTR_STRDUP( cs32->szTitle );
975 cls = SEGPTR_STRDUP( cs32->szClass );
976 cs->szTitle = SEGPTR_GET(name);
977 cs->szClass = SEGPTR_GET(cls);
978 *plparam = (LPARAM)SEGPTR_GET(cs);
980 return 1;
981 case WM_MDISETMENU:
982 *pwparam16 = TRUE; /* FIXME? */
983 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
984 (HMENU16)LOWORD(*plparam) );
985 return 0;
986 case WM_MENUCHAR:
987 case WM_MENUSELECT:
988 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
989 return 0;
990 case WM_NCCALCSIZE:
992 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
993 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
994 if (!nc) return -1;
996 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
997 if (wParam32)
999 WINDOWPOS16 *wp;
1000 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1001 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1002 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1004 SEGPTR_FREE(nc);
1005 return -1;
1007 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1008 nc->lppos = SEGPTR_GET(wp);
1010 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1011 *plparam = (LPARAM)SEGPTR_GET(nc);
1013 return 1;
1014 case WM_NCCREATE:
1015 case WM_CREATE:
1017 CREATESTRUCT16 *cs;
1018 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)*plparam;
1019 LPSTR name, cls;
1021 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1022 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1023 name = SEGPTR_STRDUP( cs32->lpszName );
1024 cls = SEGPTR_STRDUP( cs32->lpszClass );
1025 cs->lpszName = SEGPTR_GET(name);
1026 cs->lpszClass = SEGPTR_GET(cls);
1027 *plparam = (LPARAM)SEGPTR_GET(cs);
1029 return 1;
1030 case WM_PARENTNOTIFY:
1031 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1032 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1033 /* else nothing to do */
1034 return 0;
1035 case WM_SETTEXT:
1037 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1038 if (!str) return -1;
1039 *plparam = (LPARAM)SEGPTR_GET(str);
1041 return 1;
1042 case WM_WINDOWPOSCHANGING:
1043 case WM_WINDOWPOSCHANGED:
1045 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1046 sizeof(LPARAM) );
1047 if (!wp) return -1;
1048 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)*plparam, wp );
1049 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1050 *plparam = (LPARAM)SEGPTR_GET(wp);
1052 return 1;
1053 case WM_ASKCBFORMATNAME:
1054 case WM_COMPAREITEM:
1055 case WM_DELETEITEM:
1056 case WM_DEVMODECHANGE:
1057 case WM_MDIACTIVATE:
1058 case WM_MEASUREITEM:
1059 case WM_PAINTCLIPBOARD:
1060 case WM_SIZECLIPBOARD:
1061 case WM_WININICHANGE:
1062 fprintf( stderr, "MapMsg32ATo16: message %04x needs translation\n",
1063 msg32 );
1064 return -1;
1066 default: /* No translation needed */
1067 return 0;
1072 /**********************************************************************
1073 * WINPROC_UnmapMsg32ATo16
1075 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1077 void WINPROC_UnmapMsg32ATo16( UINT16 msg, WPARAM16 wParam, LPARAM lParam )
1079 switch(msg)
1081 case WM_DRAWITEM:
1082 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
1083 break;
1084 case WM_GETMINMAXINFO:
1086 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam);
1087 lParam = *(LPARAM *)(mmi + 1);
1088 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)lParam );
1089 SEGPTR_FREE(mmi);
1091 break;
1092 case WM_GETTEXT:
1094 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(lParam);
1095 lParam = *((LPARAM *)str - 1);
1096 strcpy( (LPSTR)lParam, str );
1097 SEGPTR_FREE( (LPARAM *)str - 1 );
1099 break;
1100 case WM_MDICREATE:
1102 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(lParam);
1103 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1104 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1105 SEGPTR_FREE( cs );
1107 break;
1108 case WM_NCCALCSIZE:
1110 NCCALCSIZE_PARAMS32 *nc32;
1111 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
1112 lParam = *(LPARAM *)(nc + 1);
1113 nc32 = (NCCALCSIZE_PARAMS32 *)lParam;
1114 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1115 if (wParam)
1117 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1118 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1119 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1120 nc32->lppos );
1121 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1123 SEGPTR_FREE(nc);
1125 break;
1126 case WM_NCCREATE:
1127 case WM_CREATE:
1129 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
1130 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1131 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1132 SEGPTR_FREE( cs );
1134 break;
1135 case WM_SETTEXT:
1136 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
1137 break;
1138 case WM_WINDOWPOSCHANGING:
1139 case WM_WINDOWPOSCHANGED:
1141 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam);
1142 lParam = *(LPARAM *)(wp + 1);
1143 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)lParam );
1144 SEGPTR_FREE(wp);
1146 break;
1151 /**********************************************************************
1152 * WINPROC_MapMsg32WTo16
1154 * Map a message from 32-bit Unicode to 16-bit.
1155 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1157 INT32 WINPROC_MapMsg32WTo16( UINT32 msg32, WPARAM32 wParam32, UINT16 *pmsg16,
1158 WPARAM16 *pwparam16, LPARAM *plparam )
1160 switch(msg32)
1162 case WM_NCCREATE:
1163 case WM_CREATE:
1165 CREATESTRUCT16 *cs;
1166 CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
1168 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1169 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
1170 if (HIWORD(cs32->lpszName))
1172 LPSTR name = SEGPTR_ALLOC( lstrlen32W(cs32->lpszName) + 1 );
1173 STRING32_UniToAnsi( name, cs32->lpszName );
1174 cs->lpszName = SEGPTR_GET(name);
1176 else cs->lpszName = (SEGPTR)cs32->lpszName;
1177 if (HIWORD(cs32->lpszClass))
1179 LPSTR name = SEGPTR_ALLOC( lstrlen32W(cs32->lpszClass) + 1 );
1180 STRING32_UniToAnsi( name, cs32->lpszClass );
1181 cs->lpszClass = SEGPTR_GET(name);
1183 else cs->lpszClass = (SEGPTR)cs32->lpszClass;
1184 *pmsg16 = (UINT16)msg32;
1185 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1186 *plparam = (LPARAM)SEGPTR_GET(cs);
1188 return 1;
1189 case WM_MDICREATE:
1191 MDICREATESTRUCT16 *cs;
1192 MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
1194 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1195 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
1196 if (HIWORD(cs32->szTitle))
1198 LPSTR name = SEGPTR_ALLOC( lstrlen32W(cs32->szTitle) + 1 );
1199 STRING32_UniToAnsi( name, cs32->szTitle );
1200 cs->szTitle = SEGPTR_GET(name);
1202 else cs->szTitle = (SEGPTR)cs32->szTitle;
1203 if (HIWORD(cs32->szClass))
1205 LPSTR name = SEGPTR_ALLOC( lstrlen32W(cs32->szClass) + 1 );
1206 STRING32_UniToAnsi( name, cs32->szClass );
1207 cs->szClass = SEGPTR_GET(name);
1209 else cs->szClass = (SEGPTR)cs32->szClass;
1210 *pmsg16 = (UINT16)msg32;
1211 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1212 *plparam = (LPARAM)SEGPTR_GET(cs);
1214 return 1;
1215 case WM_SETTEXT:
1217 LPSTR str = SEGPTR_ALLOC( lstrlen32W((LPWSTR)*plparam) + 1 );
1218 if (!str) return -1;
1219 STRING32_UniToAnsi( str, (LPWSTR)*plparam );
1220 *pmsg16 = (UINT16)msg32;
1221 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1222 *plparam = (LPARAM)SEGPTR_GET(str);
1224 return 1;
1225 default: /* No Unicode translation needed */
1226 return WINPROC_MapMsg32ATo16( msg32, wParam32, pmsg16,
1227 pwparam16, plparam );
1232 /**********************************************************************
1233 * WINPROC_UnmapMsg32WTo16
1235 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1237 void WINPROC_UnmapMsg32WTo16( UINT16 msg, WPARAM16 wParam, LPARAM lParam )
1239 switch(msg)
1241 case WM_GETTEXT:
1243 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(lParam);
1244 lParam = *((LPARAM *)str - 1);
1245 STRING32_AnsiToUni( (LPWSTR)lParam, str );
1246 SEGPTR_FREE( (LPARAM *)str - 1 );
1248 break;
1249 default:
1250 WINPROC_UnmapMsg32ATo16( msg, wParam, lParam );
1251 break;
1256 /**********************************************************************
1257 * WINPROC_CallProc32ATo32W
1259 * Call a window procedure, translating args from Ansi to Unicode.
1261 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
1262 UINT32 msg, WPARAM32 wParam,
1263 LPARAM lParam )
1265 LRESULT result;
1267 if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
1268 result = CallWndProc32( func, hwnd, msg, wParam, lParam );
1269 WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
1270 return result;
1274 /**********************************************************************
1275 * WINPROC_CallProc32WTo32A
1277 * Call a window procedure, translating args from Unicode to Ansi.
1279 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
1280 UINT32 msg, WPARAM32 wParam,
1281 LPARAM lParam )
1283 LRESULT result;
1285 if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
1286 result = CallWndProc32( func, hwnd, msg, wParam, lParam );
1287 WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
1288 return result;
1292 /**********************************************************************
1293 * WINPROC_CallProc16To32A
1295 * Call a 32-bit window procedure, translating the 16-bit args.
1297 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
1298 WPARAM16 wParam, LPARAM lParam,
1299 WNDPROC32 func )
1301 LRESULT result;
1302 UINT32 msg32;
1303 WPARAM32 wParam32;
1305 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1306 return 0;
1307 result = CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1308 WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam );
1309 return result;
1313 /**********************************************************************
1314 * WINPROC_CallProc16To32W
1316 * Call a 32-bit window procedure, translating the 16-bit args.
1318 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
1319 WPARAM16 wParam, LPARAM lParam,
1320 WNDPROC32 func )
1322 LRESULT result;
1323 UINT32 msg32;
1324 WPARAM32 wParam32;
1326 if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
1327 return 0;
1328 result = CallWndProc32( func, hwnd, msg32, wParam32, lParam );
1329 WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam );
1330 return result;
1334 /**********************************************************************
1335 * WINPROC_CallProc32ATo16
1337 * Call a 16-bit window procedure, translating the 32-bit args.
1339 static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
1340 UINT32 msg, WPARAM32 wParam,
1341 LPARAM lParam )
1343 LRESULT result;
1344 UINT16 msg16;
1345 WPARAM16 wParam16;
1346 WND *wndPtr = WIN_FindWndPtr( hwnd );
1347 WORD ds = wndPtr ? wndPtr->hInstance : CURRENT_DS;
1349 if (WINPROC_MapMsg32ATo16( msg, wParam, &msg16, &wParam16, &lParam ) == -1)
1350 return 0;
1351 result = CallWndProc16( func, ds, hwnd, msg16, wParam16, lParam );
1352 WINPROC_UnmapMsg32ATo16( msg16, wParam16, lParam );
1353 return result;
1357 /**********************************************************************
1358 * WINPROC_CallProc32WTo16
1360 * Call a 16-bit window procedure, translating the 32-bit args.
1362 static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
1363 UINT32 msg, WPARAM32 wParam,
1364 LPARAM lParam )
1366 LRESULT result;
1367 UINT16 msg16;
1368 WPARAM16 wParam16;
1369 WND *wndPtr = WIN_FindWndPtr( hwnd );
1371 if (WINPROC_MapMsg32WTo16( msg, wParam, &msg16, &wParam16, &lParam ) == -1)
1372 return 0;
1373 result = CallWndProc16( func, wndPtr ? wndPtr->hInstance : CURRENT_DS,
1374 hwnd, msg16, wParam16, lParam );
1375 WINPROC_UnmapMsg32WTo16( msg16, wParam16, lParam );
1376 return result;
1380 /**********************************************************************
1381 * CallWindowProc16 (USER.122)
1383 LRESULT CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
1384 WPARAM16 wParam, LPARAM lParam )
1386 WND *wndPtr;
1387 WINDOWPROC *proc = WINPROC_GetPtr( func );
1389 if (!proc)
1391 wndPtr = WIN_FindWndPtr( hwnd );
1392 return CallWndProc16( (FARPROC16)func,
1393 wndPtr ? wndPtr->hInstance : CURRENT_DS,
1394 hwnd, msg, wParam, lParam );
1396 #if testing
1397 wndPtr = WIN_FindWndPtr( hwnd );
1398 return CallWndProc16( WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16),
1399 wndPtr ? wndPtr->hInstance : CURRENT_DS,
1400 hwnd, msg, wParam, lParam );
1401 #endif
1403 switch(proc->type)
1405 case WIN_PROC_16:
1406 if (!proc->thunk.t_from32.proc) return 0;
1407 wndPtr = WIN_FindWndPtr( hwnd );
1408 #ifndef WINELIB
1409 if ((msg == WM_CREATE) || (msg == WM_NCCREATE))
1411 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
1412 /* Build the CREATESTRUCT on the 16-bit stack. */
1413 /* This is really ugly, but some programs (notably the */
1414 /* "Undocumented Windows" examples) want it that way. */
1415 return CallWndProcNCCREATE16( proc->thunk.t_from32.proc,
1416 wndPtr ? wndPtr->hInstance : CURRENT_DS, cs->dwExStyle,
1417 cs->lpszClass, cs->lpszName, cs->style, cs->x, cs->y,
1418 cs->cx, cs->cy, cs->hwndParent, cs->hMenu, cs->hInstance,
1419 (LONG)cs->lpCreateParams, hwnd, msg, wParam,
1420 MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
1421 IF1632_Saved16_ss ) );
1423 #endif
1424 return CallWndProc16( proc->thunk.t_from32.proc,
1425 wndPtr ? wndPtr->hInstance : CURRENT_DS,
1426 hwnd, msg, wParam, lParam );
1427 case WIN_PROC_32A:
1428 if (!proc->thunk.t_from16.proc) return 0;
1429 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
1430 proc->thunk.t_from16.proc );
1431 case WIN_PROC_32W:
1432 if (!proc->thunk.t_from16.proc) return 0;
1433 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
1434 proc->thunk.t_from16.proc );
1435 default:
1436 fprintf( stderr, "CallWindowProc16: invalid proc %p\n", proc );
1437 return 0;
1442 /**********************************************************************
1443 * CallWindowProc32A (USER32.17)
1445 LRESULT CallWindowProc32A( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1446 WPARAM32 wParam, LPARAM lParam )
1448 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1450 if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam );
1452 #if testing
1453 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
1454 return CallWndProc32( func, hwnd, msg, wParam, lParam );
1455 #endif
1457 switch(proc->type)
1459 case WIN_PROC_16:
1460 if (!proc->thunk.t_from32.proc) return 0;
1461 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
1462 hwnd, msg, wParam, lParam );
1463 case WIN_PROC_32A:
1464 if (!proc->thunk.t_from16.proc) return 0;
1465 return CallWndProc32( proc->thunk.t_from16.proc,
1466 hwnd, msg, wParam, lParam );
1467 case WIN_PROC_32W:
1468 if (!proc->thunk.t_from16.proc) return 0;
1469 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
1470 hwnd, msg, wParam, lParam );
1471 default:
1472 fprintf( stderr, "CallWindowProc32A: invalid proc %p\n", proc );
1473 return 0;
1478 /**********************************************************************
1479 * CallWindowProc32W (USER32.18)
1481 LRESULT CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
1482 WPARAM32 wParam, LPARAM lParam )
1484 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
1486 if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam );
1488 #if testing
1489 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
1490 return CallWndProc32( func, hwnd, msg, wParam, lParam );
1491 #endif
1493 switch(proc->type)
1495 case WIN_PROC_16:
1496 if (!proc->thunk.t_from32.proc) return 0;
1497 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
1498 hwnd, msg, wParam, lParam );
1499 case WIN_PROC_32A:
1500 if (!proc->thunk.t_from16.proc) return 0;
1501 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
1502 hwnd, msg, wParam, lParam );
1503 case WIN_PROC_32W:
1504 if (!proc->thunk.t_from16.proc) return 0;
1505 return CallWndProc32( proc->thunk.t_from16.proc,
1506 hwnd, msg, wParam, lParam );
1507 default:
1508 fprintf( stderr, "CallWindowProc32W: invalid proc %p\n", proc );
1509 return 0;