Fixed infinite loop for 0-length wavehdrs.
[wine/multimedia.git] / windows / winproc.c
blob1681dbece242c9635854d1a9cf0a54e0347fa24c
1 /*
2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
6 */
8 #include <string.h>
9 #include "wine/winbase16.h"
10 #include "winuser.h"
11 #include "stackframe.h"
12 #include "builtin16.h"
13 #include "heap.h"
14 #include "selectors.h"
15 #include "struct32.h"
16 #include "win.h"
17 #include "winproc.h"
18 #include "debugtools.h"
19 #include "spy.h"
20 #include "commctrl.h"
21 #include "task.h"
22 #include "thread.h"
24 DECLARE_DEBUG_CHANNEL(msg)
25 DECLARE_DEBUG_CHANNEL(relay)
26 DECLARE_DEBUG_CHANNEL(win)
28 /* Window procedure 16-to-32-bit thunk,
29 * see BuildSpec16Files() in tools/build.c */
31 #include "pshpack1.h"
32 typedef struct
34 WORD pushw_bp; /* pushw %bp */
35 BYTE pushl_func; /* pushl $proc */
36 WNDPROC proc;
37 WORD pushw_ax; /* pushw %ax */
38 BYTE pushl_relay; /* pushl $relay */
39 void (*relay)(); /* WINPROC_Thunk16To32A/W() */
40 BYTE lcall; /* lcall cs:glue */
41 void (*glue)(); /* CallFrom16Long */
42 WORD cs; /* __FLATCS */
43 WORD lret; /* lret $10 */
44 WORD nArgs;
45 } WINPROC_THUNK_FROM16;
46 #include "poppack.h"
48 /* Window procedure 32-to-16-bit thunk,
49 * see BuildSpec32Files() in tools/build.c */
51 typedef struct
53 BYTE popl_eax; /* popl %eax (return address) */
54 BYTE pushl_func; /* pushl $proc */
55 WNDPROC16 proc WINE_PACKED;
56 BYTE pushl_eax; /* pushl %eax */
57 BYTE jmp; /* jmp relay (relative jump)*/
58 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
59 } WINPROC_THUNK_FROM32;
61 /* Simple jmp to call 32-bit procedure directly */
62 typedef struct
64 BYTE jmp; /* jmp proc (relative jump) */
65 WNDPROC proc WINE_PACKED;
66 } WINPROC_JUMP;
68 typedef union
70 WINPROC_THUNK_FROM16 t_from16;
71 WINPROC_THUNK_FROM32 t_from32;
72 } WINPROC_THUNK;
74 typedef struct tagWINDOWPROC
76 WINPROC_THUNK thunk; /* Thunk */
77 WINPROC_JUMP jmp; /* Jump */
78 struct tagWINDOWPROC *next; /* Next window proc */
79 UINT magic; /* Magic number */
80 WINDOWPROCTYPE type; /* Function type */
81 WINDOWPROCUSER user; /* Function user */
82 } WINDOWPROC;
84 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
86 #define WINPROC_THUNKPROC(pproc) \
87 (((pproc)->type == WIN_PROC_16) ? \
88 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
89 (WNDPROC16)((pproc)->thunk.t_from16.proc))
91 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
92 UINT msg, WPARAM wParam,
93 LPARAM lParam );
94 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
95 UINT msg, WPARAM wParam,
96 LPARAM lParam );
97 static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args );
98 static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args );
100 static HANDLE WinProcHeap;
103 /**********************************************************************
104 * WINPROC_Init
106 BOOL WINPROC_Init(void)
108 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
109 if (!WinProcHeap)
111 WARN_(relay)("Unable to create winproc heap\n" );
112 return FALSE;
114 return TRUE;
118 /**********************************************************************
119 * WINPROC_CallWndProc32
121 * Call a 32-bit WndProc.
123 static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
124 WPARAM wParam, LPARAM lParam )
126 LRESULT retvalue;
127 int iWndsLocks;
129 TRACE_(relay)("(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
130 proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
131 /* To avoid any deadlocks, all the locks on the windows structures
132 must be suspended before the control is passed to the application */
133 iWndsLocks = WIN_SuspendWndsLock();
134 retvalue = proc( hwnd, msg, wParam, lParam );
135 WIN_RestoreWndsLock(iWndsLocks);
136 return retvalue;
139 /***********************************************************************
140 * WINPROC_CallWndProc16
142 * Call a 16-bit window procedure
144 static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
145 UINT16 msg, WPARAM16 wParam,
146 LPARAM lParam )
148 CONTEXT86 context;
149 LRESULT ret;
150 WORD *args;
151 WND *wndPtr = WIN_FindWndPtr( hwnd );
152 DWORD offset = 0;
153 TEB *teb = NtCurrentTeb();
154 int iWndsLocks;
156 /* Window procedures want ax = hInstance, ds = es = ss */
158 memset(&context, '\0', sizeof(context));
159 DS_reg(&context) = SELECTOROF(teb->cur_stack);
160 ES_reg(&context) = DS_reg(&context);
161 EAX_reg(&context) = wndPtr ? wndPtr->hInstance : DS_reg(&context);
162 CS_reg(&context) = SELECTOROF(proc);
163 EIP_reg(&context) = OFFSETOF(proc);
164 EBP_reg(&context) = OFFSETOF(teb->cur_stack)
165 + (WORD)&((STACK16FRAME*)0)->bp;
167 WIN_ReleaseWndPtr(wndPtr);
169 if (lParam)
171 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
172 work if structures passed in lParam are placed in the stack/data
173 segment. Programmers easily make the mistake of converting lParam
174 to a near rather than a far pointer, since Windows apparently
175 allows this. We copy the structures to the 16 bit stack; this is
176 ugly but makes these programs work. */
177 switch (msg)
179 case WM_CREATE:
180 case WM_NCCREATE:
181 offset = sizeof(CREATESTRUCT16); break;
182 case WM_DRAWITEM:
183 offset = sizeof(DRAWITEMSTRUCT16); break;
184 case WM_COMPAREITEM:
185 offset = sizeof(COMPAREITEMSTRUCT16); break;
187 if (offset)
189 void *s = PTR_SEG_TO_LIN(lParam);
190 lParam = stack16_push( offset );
191 memcpy( PTR_SEG_TO_LIN(lParam), s, offset );
195 iWndsLocks = WIN_SuspendWndsLock();
197 args = (WORD *)THREAD_STACK16(teb) - 5;
198 args[0] = LOWORD(lParam);
199 args[1] = HIWORD(lParam);
200 args[2] = wParam;
201 args[3] = msg;
202 args[4] = hwnd;
204 ret = CallTo16RegisterShort( &context, 5 * sizeof(WORD) );
205 if (offset) stack16_pop( offset );
207 WIN_RestoreWndsLock(iWndsLocks);
209 return ret;
213 /**********************************************************************
214 * WINPROC_GetPtr
216 * Return a pointer to the win proc.
218 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
220 BYTE *ptr;
221 WINDOWPROC *proc;
223 /* Check for a linear pointer */
225 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
227 ptr = (BYTE *)handle;
228 /* First check if it is the jmp address */
229 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
230 (int)&((WINDOWPROC *)0)->thunk;
231 /* Now it must be the thunk address */
232 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
233 /* Now we have a pointer to the WINDOWPROC struct */
234 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
235 return (WINDOWPROC *)ptr;
238 /* Check for a segmented pointer */
240 if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
242 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
243 if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
244 /* It must be the thunk address */
245 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
246 /* Now we have a pointer to the WINDOWPROC struct */
247 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
248 return (WINDOWPROC *)ptr;
251 return NULL;
255 /**********************************************************************
256 * WINPROC_AllocWinProc
258 * Allocate a new window procedure.
260 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
261 WINDOWPROCUSER user )
263 WINDOWPROC *proc, *oldproc;
265 /* Allocate a window procedure */
267 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
269 /* Check if the function is already a win proc */
271 if ((oldproc = WINPROC_GetPtr( func )))
273 *proc = *oldproc;
275 else
277 switch(type)
279 case WIN_PROC_16:
280 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
281 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
282 proc->thunk.t_from32.proc = func;
283 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
284 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
285 proc->thunk.t_from32.relay = /* relative jump */
286 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
287 (DWORD)(&proc->thunk.t_from32.relay + 1));
288 break;
289 case WIN_PROC_32A:
290 case WIN_PROC_32W:
291 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
292 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
293 proc->thunk.t_from16.proc = (FARPROC)func;
294 proc->thunk.t_from16.pushw_ax = 0x5066; /* pushw %ax */
295 proc->thunk.t_from16.pushl_relay = 0x68; /* pushl $relay */
296 proc->thunk.t_from16.relay = (type == WIN_PROC_32A) ?
297 (void(*)())WINPROC_Thunk16To32A :
298 (void(*)())WINPROC_Thunk16To32W;
299 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:glue */
300 proc->thunk.t_from16.glue = (void*)CallFrom16Long;
301 GET_CS(proc->thunk.t_from16.cs);
302 proc->thunk.t_from16.lret = 0xca66;
303 proc->thunk.t_from16.nArgs = 10;
304 proc->jmp.jmp = 0xe9;
305 /* Fixup relative jump */
306 proc->jmp.proc = (WNDPROC)((DWORD)func -
307 (DWORD)(&proc->jmp.proc + 1));
308 break;
309 default:
310 /* Should not happen */
311 break;
313 proc->magic = WINPROC_MAGIC;
314 proc->type = type;
315 proc->user = user;
317 proc->next = NULL;
318 TRACE_(win)("(%08x,%d): returning %08x\n",
319 (UINT)func, type, (UINT)proc );
320 return proc;
324 /**********************************************************************
325 * WINPROC_GetProc
327 * Get a window procedure pointer that can be passed to the Windows program.
329 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
331 if (!proc) return NULL;
332 if (type == WIN_PROC_16) /* We want a 16:16 address */
334 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
335 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
336 else
337 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
338 &((WINDOWPROC *)proc)->thunk );
340 else /* We want a 32-bit address */
342 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
343 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
344 else if (type != ((WINDOWPROC *)proc)->type)
345 /* Have to return the jmp address if types don't match */
346 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
347 else
348 /* Some Win16 programs want to get back the proc they set */
349 return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc;
354 /**********************************************************************
355 * WINPROC_SetProc
357 * Set the window procedure for a window or class. There are
358 * three tree classes of winproc callbacks:
360 * 1) class -> wp - not subclassed
361 * class -> wp -> wp -> wp -> wp - SetClassLong()
362 * / /
363 * 2) window -' / - not subclassed
364 * window -> wp -> wp ' - SetWindowLong()
366 * 3) timer -> wp - SetTimer()
368 * Initially, winproc of the window points to the current winproc
369 * thunk of its class. Subclassing prepends a new thunk to the
370 * window winproc chain at the head of the list. Thus, window thunk
371 * list includes class thunks and the latter are preserved when the
372 * window is destroyed.
375 BOOL WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
376 WINDOWPROCTYPE type, WINDOWPROCUSER user )
378 BOOL bRecycle = FALSE;
379 WINDOWPROC *proc, **ppPrev;
381 /* Check if function is already in the list */
383 ppPrev = (WINDOWPROC **)pFirst;
384 proc = WINPROC_GetPtr( func );
385 while (*ppPrev)
387 if (proc)
389 if (*ppPrev == proc)
391 if ((*ppPrev)->user != user)
393 /* terminal thunk is being restored */
395 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
396 *(WINDOWPROC **)pFirst = *ppPrev;
397 return TRUE;
399 bRecycle = TRUE;
400 break;
403 else
405 if (((*ppPrev)->type == type) &&
406 (func == WINPROC_THUNKPROC(*ppPrev)))
408 bRecycle = TRUE;
409 break;
413 /* WPF_CLASS thunk terminates window thunk list */
414 if ((*ppPrev)->user != user) break;
415 ppPrev = &(*ppPrev)->next;
418 if (bRecycle)
420 /* Extract this thunk from the list */
421 proc = *ppPrev;
422 *ppPrev = proc->next;
424 else /* Allocate a new one */
426 if (proc) /* Was already a win proc */
428 type = proc->type;
429 func = WINPROC_THUNKPROC(proc);
431 proc = WINPROC_AllocWinProc( func, type, user );
432 if (!proc) return FALSE;
435 /* Add the win proc at the head of the list */
437 TRACE_(win)("(%08x,%08x,%d): res=%08x\n",
438 (UINT)*pFirst, (UINT)func, type, (UINT)proc );
439 proc->next = *(WINDOWPROC **)pFirst;
440 *(WINDOWPROC **)pFirst = proc;
441 return TRUE;
445 /**********************************************************************
446 * WINPROC_FreeProc
448 * Free a list of win procs.
450 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
452 while (proc)
454 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
455 if (((WINDOWPROC *)proc)->user != user) break;
456 TRACE_(win)("freeing %08x\n", (UINT)proc);
457 HeapFree( WinProcHeap, 0, proc );
458 proc = next;
463 /**********************************************************************
464 * WINPROC_GetProcType
466 * Return the window procedure type.
468 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
470 if (!proc ||
471 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
472 return WIN_PROC_INVALID;
473 return ((WINDOWPROC *)proc)->type;
475 /**********************************************************************
476 * WINPROC_TestCBForStr
478 * Return TRUE if the lparam is a string
480 static BOOL WINPROC_TestCBForStr ( HWND hwnd )
482 BOOL retvalue;
483 WND * wnd = WIN_FindWndPtr(hwnd);
484 retvalue = ( !(LOWORD(wnd->dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
485 (LOWORD(wnd->dwStyle) & CBS_HASSTRINGS) );
486 WIN_ReleaseWndPtr(wnd);
487 return retvalue;
489 /**********************************************************************
490 * WINPROC_TestLBForStr
492 * Return TRUE if the lparam is a string
494 static BOOL WINPROC_TestLBForStr ( HWND hwnd )
496 BOOL retvalue;
497 WND * wnd = WIN_FindWndPtr(hwnd);
498 retvalue = ( !(LOWORD(wnd->dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) ||
499 (LOWORD(wnd->dwStyle) & LBS_HASSTRINGS) );
500 WIN_ReleaseWndPtr(wnd);
501 return retvalue;
504 /**********************************************************************
505 * WINPROC_MapMsg32ATo32W
507 * Map a message from Ansi to Unicode.
508 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
510 * FIXME:
511 * WM_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR, WM_SYSDEADCHAR
513 * FIXME:
514 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
515 * the first four bytes are the handle of the icon
516 * when the WM_SETTEXT message has been used to set the icon
518 INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
520 switch(msg)
522 case WM_GETTEXT:
524 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
525 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
526 if (!ptr) return -1;
527 *ptr++ = *plparam; /* Store previous lParam */
528 *plparam = (LPARAM)ptr;
530 return 1;
531 /* lparam is string (0-terminated) */
532 case WM_SETTEXT:
533 case WM_WININICHANGE:
534 case CB_DIR:
535 case CB_FINDSTRING:
536 case CB_FINDSTRINGEXACT:
537 case CB_SELECTSTRING:
538 case LB_DIR:
539 case LB_ADDFILE:
540 case LB_FINDSTRING:
541 case LB_SELECTSTRING:
542 case EM_REPLACESEL:
543 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
544 return (*plparam ? 1 : -1);
546 case WM_NCCREATE:
547 case WM_CREATE:
549 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
550 sizeof(*cs) );
551 if (!cs) return -1;
552 *cs = *(CREATESTRUCTW *)*plparam;
553 if (HIWORD(cs->lpszName))
554 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
555 (LPCSTR)cs->lpszName );
556 if (HIWORD(cs->lpszClass))
557 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
558 (LPCSTR)cs->lpszClass );
559 *plparam = (LPARAM)cs;
561 return 1;
562 case WM_MDICREATE:
564 MDICREATESTRUCTW *cs =
565 (MDICREATESTRUCTW *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
566 if (!cs) return -1;
567 *cs = *(MDICREATESTRUCTW *)*plparam;
568 if (HIWORD(cs->szClass))
569 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
570 (LPCSTR)cs->szClass );
571 if (HIWORD(cs->szTitle))
572 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
573 (LPCSTR)cs->szTitle );
574 *plparam = (LPARAM)cs;
576 return 1;
578 /* Listbox */
579 case LB_ADDSTRING:
580 case LB_INSERTSTRING:
581 if ( WINPROC_TestLBForStr( hwnd ))
582 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
583 return (*plparam ? 1 : -1);
585 case LB_GETTEXT: /* fixme: fixed sized buffer */
586 { if ( WINPROC_TestLBForStr( hwnd ))
587 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
588 if (!ptr) return -1;
589 *ptr++ = *plparam; /* Store previous lParam */
590 *plparam = (LPARAM)ptr;
593 return 1;
595 /* Combobox */
596 case CB_ADDSTRING:
597 case CB_INSERTSTRING:
598 if ( WINPROC_TestCBForStr( hwnd ))
599 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
600 return (*plparam ? 1 : -1);
602 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
603 { if ( WINPROC_TestCBForStr( hwnd ))
604 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
605 if (!ptr) return -1;
606 *ptr++ = *plparam; /* Store previous lParam */
607 *plparam = (LPARAM)ptr;
610 return 1;
612 /* Multiline edit */
613 case EM_GETLINE:
614 { WORD len = (WORD)*plparam;
615 LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
616 if (!ptr) return -1;
617 *ptr++ = *plparam; /* Store previous lParam */
618 *((WORD *) ptr) = len; /* Store the length */
619 *plparam = (LPARAM)ptr;
621 return 1;
623 case WM_ASKCBFORMATNAME:
624 case WM_DEVMODECHANGE:
625 case WM_PAINTCLIPBOARD:
626 case WM_SIZECLIPBOARD:
627 case EM_SETPASSWORDCHAR:
628 FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg), msg );
629 return -1;
630 default: /* No translation needed */
631 return 0;
636 /**********************************************************************
637 * WINPROC_UnmapMsg32ATo32W
639 * Unmap a message that was mapped from Ansi to Unicode.
641 void WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
643 switch(msg)
645 case WM_GETTEXT:
647 LPARAM *ptr = (LPARAM *)lParam - 1;
648 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)lParam, wParam );
649 HeapFree( SystemHeap, 0, ptr );
651 break;
653 case WM_NCCREATE:
654 case WM_CREATE:
656 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
657 if (HIWORD(cs->lpszName))
658 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
659 if (HIWORD(cs->lpszClass))
660 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
661 HeapFree( SystemHeap, 0, cs );
663 break;
665 case WM_MDICREATE:
667 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
668 if (HIWORD(cs->szTitle))
669 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
670 if (HIWORD(cs->szClass))
671 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
672 HeapFree( SystemHeap, 0, cs );
674 break;
676 case WM_SETTEXT:
677 case WM_WININICHANGE:
678 case CB_DIR:
679 case CB_FINDSTRING:
680 case CB_FINDSTRINGEXACT:
681 case CB_SELECTSTRING:
682 case LB_DIR:
683 case LB_ADDFILE:
684 case LB_FINDSTRING:
685 case LB_SELECTSTRING:
686 case EM_REPLACESEL:
687 HeapFree( SystemHeap, 0, (void *)lParam );
688 break;
690 /* Listbox */
691 case LB_ADDSTRING:
692 case LB_INSERTSTRING:
693 if ( WINPROC_TestLBForStr( hwnd ))
694 HeapFree( SystemHeap, 0, (void *)lParam );
695 break;
697 case LB_GETTEXT:
698 { if ( WINPROC_TestLBForStr( hwnd ))
699 { LPARAM *ptr = (LPARAM *)lParam - 1;
700 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
701 HeapFree( SystemHeap, 0, ptr );
704 break;
706 /* Combobox */
707 case CB_ADDSTRING:
708 case CB_INSERTSTRING:
709 if ( WINPROC_TestCBForStr( hwnd ))
710 HeapFree( SystemHeap, 0, (void *)lParam );
711 break;
713 case CB_GETLBTEXT:
714 { if ( WINPROC_TestCBForStr( hwnd ))
715 { LPARAM *ptr = (LPARAM *)lParam - 1;
716 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
717 HeapFree( SystemHeap, 0, ptr );
720 break;
722 /* Multiline edit */
723 case EM_GETLINE:
724 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
725 WORD len = *(WORD *) lParam;
726 lstrcpynWtoA( (LPSTR)*ptr , (LPWSTR)lParam, len );
727 HeapFree( SystemHeap, 0, ptr );
729 break;
734 /**********************************************************************
735 * WINPROC_MapMsg32WTo32A
737 * Map a message from Unicode to Ansi.
738 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
740 INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
741 { switch(msg)
743 case WM_GETTEXT:
745 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
746 wParam + sizeof(LPARAM) );
747 if (!ptr) return -1;
748 *ptr++ = *plparam; /* Store previous lParam */
749 *plparam = (LPARAM)ptr;
751 return 1;
753 case WM_SETTEXT:
754 case WM_WININICHANGE:
755 case CB_DIR:
756 case CB_FINDSTRING:
757 case CB_FINDSTRINGEXACT:
758 case CB_SELECTSTRING:
759 case LB_DIR:
760 case LB_ADDFILE:
761 case LB_FINDSTRING:
762 case LB_SELECTSTRING:
763 case EM_REPLACESEL:
764 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
765 return (*plparam ? 1 : -1);
767 case WM_NCCREATE:
768 case WM_CREATE:
770 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
771 sizeof(*cs) );
772 if (!cs) return -1;
773 *cs = *(CREATESTRUCTA *)*plparam;
774 if (HIWORD(cs->lpszName))
775 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
776 (LPCWSTR)cs->lpszName );
777 if (HIWORD(cs->lpszClass))
778 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
779 (LPCWSTR)cs->lpszClass);
780 *plparam = (LPARAM)cs;
782 return 1;
783 case WM_MDICREATE:
785 MDICREATESTRUCTA *cs =
786 (MDICREATESTRUCTA *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
787 if (!cs) return -1;
788 *cs = *(MDICREATESTRUCTA *)*plparam;
789 if (HIWORD(cs->szTitle))
790 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
791 (LPCWSTR)cs->szTitle );
792 if (HIWORD(cs->szClass))
793 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
794 (LPCWSTR)cs->szClass );
795 *plparam = (LPARAM)cs;
797 return 1;
799 /* Listbox */
800 case LB_ADDSTRING:
801 case LB_INSERTSTRING:
802 if ( WINPROC_TestLBForStr( hwnd ))
803 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
804 return (*plparam ? 1 : -1);
806 case LB_GETTEXT: /* fixme: fixed sized buffer */
807 { if ( WINPROC_TestLBForStr( hwnd ))
808 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
809 if (!ptr) return -1;
810 *ptr++ = *plparam; /* Store previous lParam */
811 *plparam = (LPARAM)ptr;
814 return 1;
816 /* Combobox */
817 case CB_ADDSTRING:
818 case CB_INSERTSTRING:
819 if ( WINPROC_TestCBForStr( hwnd ))
820 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
821 return (*plparam ? 1 : -1);
823 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
824 { if ( WINPROC_TestCBForStr( hwnd ))
825 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
826 if (!ptr) return -1;
827 *ptr++ = *plparam; /* Store previous lParam */
828 *plparam = (LPARAM)ptr;
831 return 1;
833 /* Multiline edit */
834 case EM_GETLINE:
835 { WORD len = (WORD)*plparam;
836 LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
837 if (!ptr) return -1;
838 *ptr++ = *plparam; /* Store previous lParam */
839 *((WORD *) ptr) = len; /* Store the length */
840 *plparam = (LPARAM)ptr;
842 return 1;
844 case WM_ASKCBFORMATNAME:
845 case WM_DEVMODECHANGE:
846 case WM_PAINTCLIPBOARD:
847 case WM_SIZECLIPBOARD:
848 case EM_SETPASSWORDCHAR:
849 FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg),msg );
850 return -1;
851 default: /* No translation needed */
852 return 0;
857 /**********************************************************************
858 * WINPROC_UnmapMsg32WTo32A
860 * Unmap a message that was mapped from Unicode to Ansi.
862 void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
864 switch(msg)
866 case WM_GETTEXT:
868 LPARAM *ptr = (LPARAM *)lParam - 1;
869 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)lParam, wParam );
870 HeapFree( SystemHeap, 0, ptr );
872 break;
874 case WM_SETTEXT:
875 case WM_WININICHANGE:
876 case CB_DIR:
877 case CB_FINDSTRING:
878 case CB_FINDSTRINGEXACT:
879 case CB_SELECTSTRING:
880 case LB_DIR:
881 case LB_ADDFILE:
882 case LB_FINDSTRING:
883 case LB_SELECTSTRING:
884 case EM_REPLACESEL:
885 HeapFree( SystemHeap, 0, (void *)lParam );
886 break;
888 case WM_NCCREATE:
889 case WM_CREATE:
891 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
892 if (HIWORD(cs->lpszName))
893 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
894 if (HIWORD(cs->lpszClass))
895 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
896 HeapFree( SystemHeap, 0, cs );
898 break;
900 case WM_MDICREATE:
902 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
903 if (HIWORD(cs->szTitle))
904 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
905 if (HIWORD(cs->szClass))
906 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
907 HeapFree( SystemHeap, 0, cs );
909 break;
911 /* Listbox */
912 case LB_ADDSTRING:
913 case LB_INSERTSTRING:
914 if ( WINPROC_TestLBForStr( hwnd ))
915 HeapFree( SystemHeap, 0, (void *)lParam );
916 break;
918 case LB_GETTEXT:
919 { if ( WINPROC_TestLBForStr( hwnd ))
920 { LPARAM *ptr = (LPARAM *)lParam - 1;
921 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
922 HeapFree( SystemHeap, 0, ptr );
925 break;
927 /* Combobox */
928 case CB_ADDSTRING:
929 case CB_INSERTSTRING:
930 if ( WINPROC_TestCBForStr( hwnd ))
931 HeapFree( SystemHeap, 0, (void *)lParam );
932 break;
934 case CB_GETLBTEXT:
935 { if ( WINPROC_TestCBForStr( hwnd ))
936 { LPARAM *ptr = (LPARAM *)lParam - 1;
937 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
938 HeapFree( SystemHeap, 0, ptr );
941 break;
943 /* Multiline edit */
944 case EM_GETLINE:
945 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lparam */
946 WORD len = *(WORD *)ptr;
947 lstrcpynAtoW( (LPWSTR) *ptr, (LPSTR)lParam, len );
948 HeapFree( SystemHeap, 0, ptr );
950 break;
955 /**********************************************************************
956 * WINPROC_MapMsg16To32A
958 * Map a message from 16- to 32-bit Ansi.
959 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
961 INT WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
962 WPARAM *pwparam32, LPARAM *plparam )
964 *pmsg32 = (UINT)msg16;
965 *pwparam32 = (WPARAM)wParam16;
966 switch(msg16)
968 case WM_ACTIVATE:
969 case WM_CHARTOITEM:
970 case WM_COMMAND:
971 case WM_VKEYTOITEM:
972 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
973 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
974 return 0;
975 case WM_HSCROLL:
976 case WM_VSCROLL:
977 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
978 *plparam = (LPARAM)(HWND)HIWORD(*plparam);
979 return 0;
980 case WM_CTLCOLOR:
981 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
982 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
983 *pwparam32 = (WPARAM)(HDC)wParam16;
984 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
985 return 0;
986 case WM_COMPAREITEM:
988 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
989 COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)
990 HeapAlloc(SystemHeap, 0, sizeof(*cis));
991 if (!cis) return -1;
992 cis->CtlType = cis16->CtlType;
993 cis->CtlID = cis16->CtlID;
994 cis->hwndItem = cis16->hwndItem;
995 cis->itemID1 = cis16->itemID1;
996 cis->itemData1 = cis16->itemData1;
997 cis->itemID2 = cis16->itemID2;
998 cis->itemData2 = cis16->itemData2;
999 cis->dwLocaleId = 0; /* FIXME */
1000 *plparam = (LPARAM)cis;
1002 return 1;
1003 case WM_DELETEITEM:
1005 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1006 DELETEITEMSTRUCT *dis = (DELETEITEMSTRUCT *)
1007 HeapAlloc(SystemHeap, 0, sizeof(*dis));
1008 if (!dis) return -1;
1009 dis->CtlType = dis16->CtlType;
1010 dis->CtlID = dis16->CtlID;
1011 dis->hwndItem = dis16->hwndItem;
1012 dis->itemData = dis16->itemData;
1013 *plparam = (LPARAM)dis;
1015 return 1;
1016 case WM_MEASUREITEM:
1018 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1019 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)
1020 HeapAlloc(SystemHeap, 0,
1021 sizeof(*mis) + sizeof(LPARAM));
1022 if (!mis) return -1;
1023 mis->CtlType = mis16->CtlType;
1024 mis->CtlID = mis16->CtlID;
1025 mis->itemID = mis16->itemID;
1026 mis->itemWidth = mis16->itemWidth;
1027 mis->itemHeight = mis16->itemHeight;
1028 mis->itemData = mis16->itemData;
1029 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1030 *plparam = (LPARAM)mis;
1032 return 1;
1033 case WM_DRAWITEM:
1035 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1036 DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)HeapAlloc(SystemHeap, 0,
1037 sizeof(*dis));
1038 if (!dis) return -1;
1039 dis->CtlType = dis16->CtlType;
1040 dis->CtlID = dis16->CtlID;
1041 dis->itemID = dis16->itemID;
1042 dis->itemAction = dis16->itemAction;
1043 dis->itemState = dis16->itemState;
1044 dis->hwndItem = dis16->hwndItem;
1045 dis->hDC = dis16->hDC;
1046 dis->itemData = dis16->itemData;
1047 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
1048 *plparam = (LPARAM)dis;
1050 return 1;
1051 case WM_GETMINMAXINFO:
1053 MINMAXINFO *mmi = (MINMAXINFO *)HeapAlloc( SystemHeap, 0,
1054 sizeof(*mmi) + sizeof(LPARAM));
1055 if (!mmi) return -1;
1056 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
1057 mmi );
1058 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1059 *plparam = (LPARAM)mmi;
1061 return 1;
1062 case WM_GETTEXT:
1063 case WM_SETTEXT:
1064 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1065 return 0;
1066 case WM_MDICREATE:
1068 MDICREATESTRUCT16 *cs16 =
1069 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1070 MDICREATESTRUCTA *cs =
1071 (MDICREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
1072 sizeof(*cs) + sizeof(LPARAM) );
1073 if (!cs) return -1;
1074 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
1075 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1076 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
1077 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1078 *plparam = (LPARAM)cs;
1080 return 1;
1081 case WM_MDIGETACTIVE:
1082 *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL) );
1083 *(BOOL*)(*plparam) = 0;
1084 return 1;
1085 case WM_MDISETMENU:
1086 if(wParam16==TRUE)
1087 *pmsg32=WM_MDIREFRESHMENU;
1088 *pwparam32 = (WPARAM)(HMENU)LOWORD(*plparam);
1089 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1090 return 0;
1091 case WM_MENUCHAR:
1092 case WM_MENUSELECT:
1093 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1094 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1095 return 0;
1096 case WM_MDIACTIVATE:
1097 if( *plparam )
1099 *pwparam32 = (WPARAM)(HWND)HIWORD(*plparam);
1100 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1102 else /* message sent to MDI client */
1103 *pwparam32 = wParam16;
1104 return 0;
1105 case WM_NCCALCSIZE:
1107 NCCALCSIZE_PARAMS16 *nc16;
1108 NCCALCSIZE_PARAMS *nc;
1110 nc = (NCCALCSIZE_PARAMS *)HeapAlloc( SystemHeap, 0,
1111 sizeof(*nc) + sizeof(LPARAM) );
1112 if (!nc) return -1;
1113 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
1114 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
1115 if (wParam16)
1117 nc->lppos = (WINDOWPOS *)HeapAlloc( SystemHeap, 0,
1118 sizeof(*nc->lppos) );
1119 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
1120 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
1121 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
1123 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1124 *plparam = (LPARAM)nc;
1126 return 1;
1127 case WM_NCCREATE:
1128 case WM_CREATE:
1130 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1131 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
1132 sizeof(*cs) + sizeof(LPARAM) );
1133 if (!cs) return -1;
1134 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
1135 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1136 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1137 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1138 *plparam = (LPARAM)cs;
1140 return 1;
1141 case WM_PARENTNOTIFY:
1142 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1144 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1145 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1147 return 0;
1148 case WM_WINDOWPOSCHANGING:
1149 case WM_WINDOWPOSCHANGED:
1151 WINDOWPOS *wp = (WINDOWPOS *)HeapAlloc( SystemHeap, 0,
1152 sizeof(*wp) + sizeof(LPARAM) );
1153 if (!wp) return -1;
1154 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
1155 wp );
1156 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1157 *plparam = (LPARAM)wp;
1159 return 1;
1160 case WM_GETDLGCODE:
1161 if (*plparam)
1163 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1164 LPMSG msg32 = (LPMSG)HeapAlloc( SystemHeap, 0, sizeof(MSG) );
1166 if (!msg32) return -1;
1167 msg32->hwnd = msg16->hwnd;
1168 msg32->lParam = msg16->lParam;
1169 msg32->time = msg16->time;
1170 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1171 /* this is right, right? */
1172 if (WINPROC_MapMsg16To32A(msg16->message,msg16->wParam,
1173 &msg32->message,&msg32->wParam,
1174 &msg32->lParam)<0) {
1175 HeapFree( SystemHeap, 0, msg32 );
1176 return -1;
1178 *plparam = (LPARAM)msg32;
1179 return 1;
1181 else return 0;
1182 case WM_NOTIFY:
1183 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1184 return 1;
1185 case WM_ACTIVATEAPP:
1186 if (*plparam)
1187 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1188 a 32bit window. Might be superflous with 32bit interprocess
1189 message queues.
1191 HTASK16 htask = (HTASK16) *plparam;
1192 DWORD idThread = (DWORD)((TDB*)GlobalLock16(htask))->teb->tid;
1193 *plparam = (LPARAM) idThread;
1195 return 1;
1196 case WM_ASKCBFORMATNAME:
1197 case WM_DEVMODECHANGE:
1198 case WM_PAINTCLIPBOARD:
1199 case WM_SIZECLIPBOARD:
1200 case WM_WININICHANGE:
1201 FIXME_(msg)("message %04x needs translation\n",msg16 );
1202 return -1;
1204 default: /* No translation needed */
1205 return 0;
1210 /**********************************************************************
1211 * WINPROC_UnmapMsg16To32A
1213 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1215 LRESULT WINPROC_UnmapMsg16To32A( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1216 LRESULT result )
1218 switch(msg)
1220 case WM_COMPAREITEM:
1221 case WM_DELETEITEM:
1222 case WM_DRAWITEM:
1223 HeapFree( SystemHeap, 0, (LPVOID)lParam );
1224 break;
1225 case WM_MEASUREITEM:
1227 MEASUREITEMSTRUCT16 *mis16;
1228 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1229 lParam = *(LPARAM *)(mis + 1);
1230 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
1231 mis16->itemWidth = (UINT16)mis->itemWidth;
1232 mis16->itemHeight = (UINT16)mis->itemHeight;
1233 HeapFree( SystemHeap, 0, mis );
1235 break;
1236 case WM_GETMINMAXINFO:
1238 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1239 lParam = *(LPARAM *)(mmi + 1);
1240 STRUCT32_MINMAXINFO32to16( mmi,
1241 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
1242 HeapFree( SystemHeap, 0, mmi );
1244 break;
1245 case WM_MDICREATE:
1247 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1248 lParam = *(LPARAM *)(cs + 1);
1249 STRUCT32_MDICREATESTRUCT32Ato16( cs,
1250 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1251 HeapFree( SystemHeap, 0, cs );
1253 break;
1254 case WM_MDIGETACTIVE:
1255 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1256 HeapFree( SystemHeap, 0, (BOOL *)lParam );
1257 break;
1258 case WM_NCCALCSIZE:
1260 NCCALCSIZE_PARAMS16 *nc16;
1261 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1262 lParam = *(LPARAM *)(nc + 1);
1263 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
1264 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
1265 if (wParam)
1267 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
1268 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
1269 if (nc->lppos)
1271 STRUCT32_WINDOWPOS32to16( nc->lppos,
1272 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
1273 HeapFree( SystemHeap, 0, nc->lppos );
1276 HeapFree( SystemHeap, 0, nc );
1278 break;
1279 case WM_NCCREATE:
1280 case WM_CREATE:
1282 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1283 lParam = *(LPARAM *)(cs + 1);
1284 STRUCT32_CREATESTRUCT32Ato16( cs,
1285 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1286 HeapFree( SystemHeap, 0, cs );
1288 break;
1289 case WM_WINDOWPOSCHANGING:
1290 case WM_WINDOWPOSCHANGED:
1292 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1293 lParam = *(LPARAM *)(wp + 1);
1294 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
1295 HeapFree( SystemHeap, 0, wp );
1297 break;
1298 case WM_GETDLGCODE:
1299 if (lParam)
1301 LPMSG msg32 = (LPMSG)lParam;
1303 WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1304 result);
1305 HeapFree( SystemHeap, 0, msg32 );
1307 break;
1309 return result;
1313 /**********************************************************************
1314 * WINPROC_MapMsg16To32W
1316 * Map a message from 16- to 32-bit Unicode.
1317 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1319 INT WINPROC_MapMsg16To32W( HWND16 hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1320 WPARAM *pwparam32, LPARAM *plparam )
1322 switch(msg16)
1324 case WM_GETTEXT:
1325 case WM_SETTEXT:
1326 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1327 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, *pwparam32, plparam );
1328 case WM_NCCREATE:
1329 case WM_CREATE:
1331 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1332 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
1333 sizeof(*cs) + sizeof(LPARAM) );
1334 if (!cs) return -1;
1335 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1336 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1337 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1338 if (HIWORD(cs->lpszName))
1339 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
1340 (LPCSTR)cs->lpszName );
1341 if (HIWORD(cs->lpszClass))
1342 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
1343 (LPCSTR)cs->lpszClass );
1344 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1345 *plparam = (LPARAM)cs;
1347 return 1;
1348 case WM_MDICREATE:
1350 MDICREATESTRUCT16 *cs16 =
1351 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1352 MDICREATESTRUCTW *cs =
1353 (MDICREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
1354 sizeof(*cs) + sizeof(LPARAM) );
1355 if (!cs) return -1;
1356 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1357 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1358 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
1359 if (HIWORD(cs->szTitle))
1360 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
1361 (LPCSTR)cs->szTitle );
1362 if (HIWORD(cs->szClass))
1363 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
1364 (LPCSTR)cs->szClass );
1365 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1366 *plparam = (LPARAM)cs;
1368 return 1;
1369 case WM_GETDLGCODE:
1370 if (*plparam)
1372 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1373 LPMSG msg32 = (LPMSG)HeapAlloc( SystemHeap, 0, sizeof(MSG) );
1375 if (!msg32) return -1;
1376 msg32->hwnd = msg16->hwnd;
1377 msg32->lParam = msg16->lParam;
1378 msg32->time = msg16->time;
1379 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1380 /* this is right, right? */
1381 if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
1382 &msg32->message,&msg32->wParam,
1383 &msg32->lParam)<0) {
1384 HeapFree( SystemHeap, 0, msg32 );
1385 return -1;
1387 *plparam = (LPARAM)msg32;
1388 return 1;
1390 else return 0;
1391 default: /* No Unicode translation needed */
1392 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1393 pwparam32, plparam );
1398 /**********************************************************************
1399 * WINPROC_UnmapMsg16To32W
1401 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1403 LRESULT WINPROC_UnmapMsg16To32W( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1404 LRESULT result )
1406 switch(msg)
1408 case WM_GETTEXT:
1409 case WM_SETTEXT:
1410 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
1411 break;
1412 case WM_NCCREATE:
1413 case WM_CREATE:
1415 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1416 lParam = *(LPARAM *)(cs + 1);
1417 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs,
1418 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1419 if (HIWORD(cs->lpszName))
1420 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1421 if (HIWORD(cs->lpszClass))
1422 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1423 HeapFree( SystemHeap, 0, cs );
1425 break;
1426 case WM_MDICREATE:
1428 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1429 lParam = *(LPARAM *)(cs + 1);
1430 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs,
1431 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1432 if (HIWORD(cs->szTitle))
1433 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1434 if (HIWORD(cs->szClass))
1435 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1436 HeapFree( SystemHeap, 0, cs );
1438 break;
1439 case WM_GETDLGCODE:
1440 if (lParam)
1442 LPMSG msg32 = (LPMSG)lParam;
1444 WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1445 result);
1446 HeapFree( SystemHeap, 0, msg32 );
1448 break;
1449 default:
1450 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1452 return result;
1456 /**********************************************************************
1457 * WINPROC_MapMsg32ATo16
1459 * Map a message from 32-bit Ansi to 16-bit.
1460 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1462 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1463 UINT16 *pmsg16, WPARAM16 *pwparam16,
1464 LPARAM *plparam )
1466 *pmsg16 = (UINT16)msg32;
1467 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1468 switch(msg32)
1470 case BM_GETCHECK:
1471 case BM_SETCHECK:
1472 case BM_GETSTATE:
1473 case BM_SETSTATE:
1474 case BM_SETSTYLE:
1475 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1476 return 0;
1478 case EM_GETSEL:
1479 case EM_GETRECT:
1480 case EM_SETRECT:
1481 case EM_SETRECTNP:
1482 case EM_SCROLL:
1483 case EM_LINESCROLL:
1484 case EM_SCROLLCARET:
1485 case EM_GETMODIFY:
1486 case EM_SETMODIFY:
1487 case EM_GETLINECOUNT:
1488 case EM_LINEINDEX:
1489 case EM_SETHANDLE:
1490 case EM_GETHANDLE:
1491 case EM_GETTHUMB:
1492 case EM_LINELENGTH:
1493 case EM_REPLACESEL:
1494 case EM_GETLINE:
1495 case EM_LIMITTEXT:
1496 case EM_CANUNDO:
1497 case EM_UNDO:
1498 case EM_FMTLINES:
1499 case EM_LINEFROMCHAR:
1500 case EM_SETTABSTOPS:
1501 case EM_SETPASSWORDCHAR:
1502 case EM_EMPTYUNDOBUFFER:
1503 case EM_GETFIRSTVISIBLELINE:
1504 case EM_SETREADONLY:
1505 case EM_SETWORDBREAKPROC:
1506 case EM_GETWORDBREAKPROC:
1507 case EM_GETPASSWORDCHAR:
1508 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1509 return 0;
1511 case LB_CARETOFF:
1512 case LB_CARETON:
1513 case LB_DELETESTRING:
1514 case LB_GETANCHORINDEX:
1515 case LB_GETCARETINDEX:
1516 case LB_GETCOUNT:
1517 case LB_GETCURSEL:
1518 case LB_GETHORIZONTALEXTENT:
1519 case LB_GETITEMDATA:
1520 case LB_GETITEMHEIGHT:
1521 case LB_GETSEL:
1522 case LB_GETSELCOUNT:
1523 case LB_GETTEXTLEN:
1524 case LB_GETTOPINDEX:
1525 case LB_RESETCONTENT:
1526 case LB_SELITEMRANGE:
1527 case LB_SELITEMRANGEEX:
1528 case LB_SETANCHORINDEX:
1529 case LB_SETCARETINDEX:
1530 case LB_SETCOLUMNWIDTH:
1531 case LB_SETCURSEL:
1532 case LB_SETHORIZONTALEXTENT:
1533 case LB_SETITEMDATA:
1534 case LB_SETITEMHEIGHT:
1535 case LB_SETSEL:
1536 case LB_SETTOPINDEX:
1537 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1538 return 0;
1539 case CB_DELETESTRING:
1540 case CB_GETCOUNT:
1541 case CB_GETLBTEXTLEN:
1542 case CB_LIMITTEXT:
1543 case CB_RESETCONTENT:
1544 case CB_SETEDITSEL:
1545 case CB_GETCURSEL:
1546 case CB_SETCURSEL:
1547 case CB_SHOWDROPDOWN:
1548 case CB_SETITEMDATA:
1549 case CB_SETITEMHEIGHT:
1550 case CB_GETITEMHEIGHT:
1551 case CB_SETEXTENDEDUI:
1552 case CB_GETEXTENDEDUI:
1553 case CB_GETDROPPEDSTATE:
1554 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1555 return 0;
1556 case CB_GETEDITSEL:
1557 *pmsg16 = CB_GETEDITSEL16;
1558 return 1;
1560 case LB_ADDSTRING:
1561 case LB_FINDSTRING:
1562 case LB_FINDSTRINGEXACT:
1563 case LB_INSERTSTRING:
1564 case LB_SELECTSTRING:
1565 case LB_DIR:
1566 case LB_ADDFILE:
1568 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1569 if (!str) return -1;
1570 *plparam = (LPARAM)SEGPTR_GET(str);
1572 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1573 return 1;
1575 case CB_ADDSTRING:
1576 case CB_FINDSTRING:
1577 case CB_FINDSTRINGEXACT:
1578 case CB_INSERTSTRING:
1579 case CB_SELECTSTRING:
1580 case CB_DIR:
1582 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1583 if (!str) return -1;
1584 *plparam = (LPARAM)SEGPTR_GET(str);
1586 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1587 return 1;
1589 case LB_GETITEMRECT:
1591 RECT16 *rect;
1592 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1593 if (!rect) return -1;
1594 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1595 *plparam = (LPARAM)SEGPTR_GET(rect);
1597 *pmsg16 = LB_GETITEMRECT16;
1598 return 1;
1599 case LB_GETSELITEMS:
1601 LPINT16 items;
1602 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1603 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1604 + sizeof(LPARAM)))) return -1;
1605 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1606 *plparam = (LPARAM)SEGPTR_GET(items);
1608 *pmsg16 = LB_GETSELITEMS16;
1609 return 1;
1610 case LB_SETTABSTOPS:
1611 if (wParam32)
1613 INT i;
1614 LPINT16 stops;
1615 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1616 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1617 + sizeof(LPARAM)))) return -1;
1618 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1619 *plparam = (LPARAM)SEGPTR_GET(stops);
1620 return 1;
1622 *pmsg16 = LB_SETTABSTOPS16;
1623 return 0;
1625 case CB_GETDROPPEDCONTROLRECT:
1627 RECT16 *rect;
1628 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1629 if (!rect) return -1;
1630 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1631 *plparam = (LPARAM)SEGPTR_GET(rect);
1633 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1634 return 1;
1636 case LB_GETTEXT:
1637 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1638 *pmsg16 = LB_GETTEXT16;
1639 return 1;
1641 case CB_GETLBTEXT:
1642 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1643 *pmsg16 = CB_GETLBTEXT16;
1644 return 1;
1646 case EM_SETSEL:
1647 *pwparam16 = 0;
1648 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
1649 *pmsg16 = EM_SETSEL16;
1650 return 0;
1652 case WM_ACTIVATE:
1653 case WM_CHARTOITEM:
1654 case WM_COMMAND:
1655 case WM_VKEYTOITEM:
1656 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1657 return 0;
1658 case WM_HSCROLL:
1659 case WM_VSCROLL:
1660 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1661 return 0;
1662 case WM_CTLCOLORMSGBOX:
1663 case WM_CTLCOLOREDIT:
1664 case WM_CTLCOLORLISTBOX:
1665 case WM_CTLCOLORBTN:
1666 case WM_CTLCOLORDLG:
1667 case WM_CTLCOLORSCROLLBAR:
1668 case WM_CTLCOLORSTATIC:
1669 *pmsg16 = WM_CTLCOLOR;
1670 *plparam = MAKELPARAM( (HWND16)*plparam,
1671 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1672 return 0;
1673 case WM_COMPAREITEM:
1675 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
1676 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1677 if (!cis) return -1;
1678 cis->CtlType = (UINT16)cis32->CtlType;
1679 cis->CtlID = (UINT16)cis32->CtlID;
1680 cis->hwndItem = (HWND16)cis32->hwndItem;
1681 cis->itemID1 = (UINT16)cis32->itemID1;
1682 cis->itemData1 = cis32->itemData1;
1683 cis->itemID2 = (UINT16)cis32->itemID2;
1684 cis->itemData2 = cis32->itemData2;
1685 *plparam = (LPARAM)SEGPTR_GET(cis);
1687 return 1;
1688 case WM_DELETEITEM:
1690 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
1691 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1692 if (!dis) return -1;
1693 dis->CtlType = (UINT16)dis32->CtlType;
1694 dis->CtlID = (UINT16)dis32->CtlID;
1695 dis->itemID = (UINT16)dis32->itemID;
1696 dis->hwndItem = (HWND16)dis32->hwndItem;
1697 dis->itemData = dis32->itemData;
1698 *plparam = (LPARAM)SEGPTR_GET(dis);
1700 return 1;
1701 case WM_DRAWITEM:
1703 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
1704 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1705 if (!dis) return -1;
1706 dis->CtlType = (UINT16)dis32->CtlType;
1707 dis->CtlID = (UINT16)dis32->CtlID;
1708 dis->itemID = (UINT16)dis32->itemID;
1709 dis->itemAction = (UINT16)dis32->itemAction;
1710 dis->itemState = (UINT16)dis32->itemState;
1711 dis->hwndItem = (HWND16)dis32->hwndItem;
1712 dis->hDC = (HDC16)dis32->hDC;
1713 dis->itemData = dis32->itemData;
1714 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1715 *plparam = (LPARAM)SEGPTR_GET(dis);
1717 return 1;
1718 case WM_MEASUREITEM:
1720 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
1721 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1722 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1723 if (!mis) return -1;
1724 mis->CtlType = (UINT16)mis32->CtlType;
1725 mis->CtlID = (UINT16)mis32->CtlID;
1726 mis->itemID = (UINT16)mis32->itemID;
1727 mis->itemWidth = (UINT16)mis32->itemWidth;
1728 mis->itemHeight = (UINT16)mis32->itemHeight;
1729 mis->itemData = mis32->itemData;
1730 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1731 *plparam = (LPARAM)SEGPTR_GET(mis);
1733 return 1;
1734 case WM_GETMINMAXINFO:
1736 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1737 sizeof(LPARAM) );
1738 if (!mmi) return -1;
1739 STRUCT32_MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
1740 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1741 *plparam = (LPARAM)SEGPTR_GET(mmi);
1743 return 1;
1744 case WM_GETTEXT:
1746 LPSTR str;
1747 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1748 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1749 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1750 *plparam = (LPARAM)SEGPTR_GET(str);
1752 return 1;
1753 case WM_MDICREATE:
1755 MDICREATESTRUCT16 *cs;
1756 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
1757 LPSTR name, cls;
1759 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1760 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1761 name = SEGPTR_STRDUP( cs32->szTitle );
1762 cls = SEGPTR_STRDUP( cs32->szClass );
1763 cs->szTitle = SEGPTR_GET(name);
1764 cs->szClass = SEGPTR_GET(cls);
1765 *plparam = (LPARAM)SEGPTR_GET(cs);
1767 return 1;
1768 case WM_MDIGETACTIVE:
1769 return 1;
1770 case WM_MDISETMENU:
1771 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1772 (HMENU16)LOWORD(*plparam) );
1773 *pwparam16 = (*plparam == 0);
1774 return 0;
1775 case WM_MENUCHAR:
1776 case WM_MENUSELECT:
1777 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1778 return 0;
1779 case WM_MDIACTIVATE:
1781 WND *tempWnd = WIN_FindWndPtr(hwnd);
1782 if( WIDGETS_IsControl(tempWnd, BIC32_MDICLIENT) )
1784 *pwparam16 = (HWND)wParam32;
1785 *plparam = 0;
1787 else
1789 *pwparam16 = ((HWND)*plparam == hwnd);
1790 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1791 (HWND16)LOWORD(wParam32) );
1793 WIN_ReleaseWndPtr(tempWnd);
1795 return 0;
1796 case WM_NCCALCSIZE:
1798 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
1799 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1800 if (!nc) return -1;
1802 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1803 if (wParam32)
1805 WINDOWPOS16 *wp;
1806 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1807 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1808 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1810 SEGPTR_FREE(nc);
1811 return -1;
1813 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1814 nc->lppos = SEGPTR_GET(wp);
1816 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1817 *plparam = (LPARAM)SEGPTR_GET(nc);
1819 return 1;
1820 case WM_NCCREATE:
1821 case WM_CREATE:
1823 CREATESTRUCT16 *cs;
1824 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
1825 LPSTR name, cls;
1827 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1828 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1829 name = SEGPTR_STRDUP( cs32->lpszName );
1830 cls = SEGPTR_STRDUP( cs32->lpszClass );
1831 cs->lpszName = SEGPTR_GET(name);
1832 cs->lpszClass = SEGPTR_GET(cls);
1833 *plparam = (LPARAM)SEGPTR_GET(cs);
1835 return 1;
1836 case WM_PARENTNOTIFY:
1837 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1838 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1839 /* else nothing to do */
1840 return 0;
1841 case WM_NOTIFY:
1842 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
1843 return 1;
1844 case WM_SETTEXT:
1846 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1847 if (!str) return -1;
1848 *plparam = (LPARAM)SEGPTR_GET(str);
1850 return 1;
1851 case WM_WINDOWPOSCHANGING:
1852 case WM_WINDOWPOSCHANGED:
1854 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1855 sizeof(LPARAM) );
1856 if (!wp) return -1;
1857 STRUCT32_WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
1858 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1859 *plparam = (LPARAM)SEGPTR_GET(wp);
1861 return 1;
1862 case WM_GETDLGCODE:
1863 if (*plparam) {
1864 LPMSG msg32 = (LPMSG) *plparam;
1865 LPMSG16 msg16 = (LPMSG16) SEGPTR_NEW( MSG16 );
1867 if (!msg16) return -1;
1868 msg16->hwnd = msg32->hwnd;
1869 msg16->lParam = msg32->lParam;
1870 msg16->time = msg32->time;
1871 CONV_POINT32TO16(&msg32->pt,&msg16->pt);
1872 /* this is right, right? */
1873 if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
1874 &msg16->message,&msg16->wParam, &msg16->lParam)<0) {
1875 SEGPTR_FREE( msg16 );
1876 return -1;
1878 *plparam = (LPARAM)SEGPTR_GET(msg16);
1879 return 1;
1881 return 0;
1883 case WM_ACTIVATEAPP:
1884 if (*plparam) {
1885 *plparam = (LPARAM)THREAD_IdToTEB((DWORD) *plparam)->htask16;
1887 return 1;
1888 case WM_ASKCBFORMATNAME:
1889 case WM_DEVMODECHANGE:
1890 case WM_PAINTCLIPBOARD:
1891 case WM_SIZECLIPBOARD:
1892 case WM_WININICHANGE:
1893 FIXME_(msg)("message %04x needs translation\n", msg32 );
1894 return -1;
1895 default: /* No translation needed */
1896 return 0;
1901 /**********************************************************************
1902 * WINPROC_UnmapMsg32ATo16
1904 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1906 void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1907 MSGPARAM16* p16 )
1909 switch(msg)
1911 case LB_ADDFILE:
1912 case LB_ADDSTRING:
1913 case LB_DIR:
1914 case LB_FINDSTRING:
1915 case LB_FINDSTRINGEXACT:
1916 case LB_INSERTSTRING:
1917 case LB_SELECTSTRING:
1918 case LB_SETTABSTOPS:
1919 case CB_ADDSTRING:
1920 case CB_FINDSTRING:
1921 case CB_FINDSTRINGEXACT:
1922 case CB_INSERTSTRING:
1923 case CB_SELECTSTRING:
1924 case CB_DIR:
1925 case WM_COMPAREITEM:
1926 case WM_DELETEITEM:
1927 case WM_DRAWITEM:
1928 case WM_SETTEXT:
1929 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1930 break;
1932 case CB_GETDROPPEDCONTROLRECT:
1933 case LB_GETITEMRECT:
1935 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1936 p16->lParam = *(LPARAM *)(rect + 1);
1937 CONV_RECT16TO32( rect, (RECT *)(p16->lParam));
1938 SEGPTR_FREE( rect );
1940 break;
1941 case LB_GETSELITEMS:
1943 INT i;
1944 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1945 p16->lParam = *((LPARAM *)items - 1);
1946 for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
1947 SEGPTR_FREE( (LPARAM *)items - 1 );
1949 break;
1951 case CB_GETEDITSEL:
1952 if( wParam )
1953 *((LPUINT)(wParam)) = LOWORD(p16->lResult);
1954 if( lParam )
1955 *((LPUINT)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1956 break;
1958 case LB_GETTEXT:
1959 case CB_GETLBTEXT:
1960 UnMapLS( (SEGPTR)(p16->lParam) );
1961 break;
1963 case WM_MEASUREITEM:
1965 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1966 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
1967 mis32->itemWidth = mis->itemWidth;
1968 mis32->itemHeight = mis->itemHeight;
1969 SEGPTR_FREE(mis);
1971 break;
1972 case WM_GETMINMAXINFO:
1974 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1975 p16->lParam = *(LPARAM *)(mmi + 1);
1976 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
1977 SEGPTR_FREE(mmi);
1979 break;
1980 case WM_GETTEXT:
1982 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1983 p16->lParam = *((LPARAM *)str - 1);
1984 lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
1985 SEGPTR_FREE( (LPARAM *)str - 1 );
1987 break;
1988 case WM_MDICREATE:
1990 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1991 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1992 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1993 SEGPTR_FREE( cs );
1995 break;
1996 case WM_MDIGETACTIVE:
1997 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
1998 p16->lResult = (HWND)LOWORD(p16->lResult);
1999 break;
2000 case WM_NCCALCSIZE:
2002 NCCALCSIZE_PARAMS *nc32;
2003 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
2004 p16->lParam = *(LPARAM *)(nc + 1);
2005 nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
2006 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
2007 if (p16->wParam)
2009 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
2010 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
2011 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
2012 nc32->lppos );
2013 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
2015 SEGPTR_FREE(nc);
2017 break;
2018 case WM_NCCREATE:
2019 case WM_CREATE:
2021 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
2022 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
2023 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
2024 SEGPTR_FREE( cs );
2026 break;
2027 case WM_WINDOWPOSCHANGING:
2028 case WM_WINDOWPOSCHANGED:
2030 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
2031 p16->lParam = *(LPARAM *)(wp + 1);
2032 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
2033 SEGPTR_FREE(wp);
2035 break;
2036 case WM_NOTIFY:
2037 UnMapLS(p16->lParam);
2038 break;
2039 case WM_GETDLGCODE:
2040 if (p16->lParam)
2042 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(p16->lParam);
2043 MSGPARAM16 msgp16;
2044 msgp16.wParam=msg16->wParam;
2045 msgp16.lParam=msg16->lParam;
2046 WINPROC_UnmapMsg32ATo16(((LPMSG)lParam)->hwnd, ((LPMSG)lParam)->message,
2047 ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam,
2048 &msgp16 );
2049 SEGPTR_FREE(msg16);
2051 break;
2056 /**********************************************************************
2057 * WINPROC_MapMsg32WTo16
2059 * Map a message from 32-bit Unicode to 16-bit.
2060 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2062 INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
2063 UINT16 *pmsg16, WPARAM16 *pwparam16,
2064 LPARAM *plparam )
2066 switch(msg32)
2068 case LB_ADDSTRING:
2069 case LB_FINDSTRING:
2070 case LB_FINDSTRINGEXACT:
2071 case LB_INSERTSTRING:
2072 case LB_SELECTSTRING:
2073 case LB_DIR:
2074 case LB_ADDFILE:
2076 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2077 if (!str) return -1;
2078 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2079 *plparam = (LPARAM)SEGPTR_GET(str);
2081 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2082 return 1;
2084 case CB_ADDSTRING:
2085 case CB_FINDSTRING:
2086 case CB_FINDSTRINGEXACT:
2087 case CB_INSERTSTRING:
2088 case CB_SELECTSTRING:
2089 case CB_DIR:
2091 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2092 if (!str) return -1;
2093 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2094 *plparam = (LPARAM)SEGPTR_GET(str);
2096 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2097 return 1;
2099 case WM_NCCREATE:
2100 case WM_CREATE:
2102 CREATESTRUCT16 *cs;
2103 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2104 LPSTR name, cls;
2106 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
2107 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2108 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
2109 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
2110 cs->lpszName = SEGPTR_GET(name);
2111 cs->lpszClass = SEGPTR_GET(cls);
2112 *pmsg16 = (UINT16)msg32;
2113 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2114 *plparam = (LPARAM)SEGPTR_GET(cs);
2116 return 1;
2117 case WM_MDICREATE:
2119 MDICREATESTRUCT16 *cs;
2120 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2121 LPSTR name, cls;
2123 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
2124 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2125 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
2126 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
2127 cs->szTitle = SEGPTR_GET(name);
2128 cs->szClass = SEGPTR_GET(cls);
2129 *pmsg16 = (UINT16)msg32;
2130 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2131 *plparam = (LPARAM)SEGPTR_GET(cs);
2133 return 1;
2134 case WM_SETTEXT:
2136 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2137 if (!str) return -1;
2138 *pmsg16 = (UINT16)msg32;
2139 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2140 *plparam = (LPARAM)SEGPTR_GET(str);
2142 return 1;
2143 default: /* No Unicode translation needed */
2144 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2145 pwparam16, plparam );
2150 /**********************************************************************
2151 * WINPROC_UnmapMsg32WTo16
2153 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2155 void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2156 MSGPARAM16* p16 )
2158 switch(msg)
2160 case WM_GETTEXT:
2162 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
2163 p16->lParam = *((LPARAM *)str - 1);
2164 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
2165 SEGPTR_FREE( (LPARAM *)str - 1 );
2167 break;
2168 default:
2169 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2170 break;
2175 /**********************************************************************
2176 * WINPROC_CallProc32ATo32W
2178 * Call a window procedure, translating args from Ansi to Unicode.
2180 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
2181 UINT msg, WPARAM wParam,
2182 LPARAM lParam )
2184 LRESULT result;
2186 if (WINPROC_MapMsg32ATo32W( hwnd, msg, wParam, &lParam ) == -1) return 0;
2187 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2188 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
2189 return result;
2193 /**********************************************************************
2194 * WINPROC_CallProc32WTo32A
2196 * Call a window procedure, translating args from Unicode to Ansi.
2198 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
2199 UINT msg, WPARAM wParam,
2200 LPARAM lParam )
2202 LRESULT result;
2204 if (WINPROC_MapMsg32WTo32A( hwnd, msg, wParam, &lParam ) == -1) return 0;
2205 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2206 WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
2207 return result;
2211 /**********************************************************************
2212 * WINPROC_CallProc16To32A
2214 * Call a 32-bit window procedure, translating the 16-bit args.
2216 static LRESULT WINPROC_CallProc16To32A( WNDPROC func, HWND16 hwnd,
2217 UINT16 msg, WPARAM16 wParam,
2218 LPARAM lParam )
2220 LRESULT result;
2221 UINT msg32;
2222 WPARAM wParam32;
2224 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2225 return 0;
2226 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2227 return WINPROC_UnmapMsg16To32A( hwnd, msg32, wParam32, lParam, result );
2230 /**********************************************************************
2231 * WINPROC_Thunk16To32A
2233 static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args )
2235 HWND16 hwnd = *(HWND16 *)( args+8 );
2236 UINT16 msg = *(HWND16 *)( args+6 );
2237 WPARAM16 wParam = *(HWND16 *)( args+4 );
2238 LPARAM lParam = *(LPARAM *)( args+0 );
2240 return WINPROC_CallProc16To32A( func, hwnd, msg, wParam, lParam );
2244 /**********************************************************************
2245 * WINPROC_CallProc16To32W
2247 * Call a 32-bit window procedure, translating the 16-bit args.
2249 static LRESULT WINPROC_CallProc16To32W( WNDPROC func, HWND16 hwnd,
2250 UINT16 msg, WPARAM16 wParam,
2251 LPARAM lParam )
2253 LRESULT result;
2254 UINT msg32;
2255 WPARAM wParam32;
2257 if (WINPROC_MapMsg16To32W( hwnd, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2258 return 0;
2260 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2262 return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result );
2265 /**********************************************************************
2266 * WINPROC_Thunk16To32W
2268 static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args )
2270 HWND16 hwnd = *(HWND16 *)( args+8 );
2271 UINT16 msg = *(HWND16 *)( args+6 );
2272 WPARAM16 wParam = *(HWND16 *)( args+4 );
2273 LPARAM lParam = *(LPARAM *)( args+0 );
2275 return WINPROC_CallProc16To32W( func, hwnd, msg, wParam, lParam );
2278 /**********************************************************************
2279 * WINPROC_CallProc32ATo16
2281 * Call a 16-bit window procedure, translating the 32-bit args.
2283 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
2284 UINT msg, WPARAM wParam,
2285 LPARAM lParam )
2287 UINT16 msg16;
2288 MSGPARAM16 mp16;
2290 mp16.lParam = lParam;
2291 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
2292 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
2293 return 0;
2294 mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
2295 mp16.wParam, mp16.lParam );
2296 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
2297 return mp16.lResult;
2301 /**********************************************************************
2302 * WINPROC_CallProc32WTo16
2304 * Call a 16-bit window procedure, translating the 32-bit args.
2306 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
2307 UINT msg, WPARAM wParam,
2308 LPARAM lParam )
2310 UINT16 msg16;
2311 MSGPARAM16 mp16;
2313 mp16.lParam = lParam;
2314 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
2315 &mp16.lParam ) == -1)
2316 return 0;
2317 mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
2318 mp16.wParam, mp16.lParam );
2319 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
2320 return mp16.lResult;
2324 /**********************************************************************
2325 * CallWindowProc16 (USER.122)
2327 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
2328 WPARAM16 wParam, LPARAM lParam )
2330 WINDOWPROC *proc = WINPROC_GetPtr( func );
2332 if (!proc)
2333 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2335 #if testing
2336 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
2337 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2338 #endif
2340 switch(proc->type)
2342 case WIN_PROC_16:
2343 if (!proc->thunk.t_from32.proc) return 0;
2344 return WINPROC_CallWndProc16( proc->thunk.t_from32.proc,
2345 hwnd, msg, wParam, lParam );
2346 case WIN_PROC_32A:
2347 if (!proc->thunk.t_from16.proc) return 0;
2348 return WINPROC_CallProc16To32A( proc->thunk.t_from16.proc,
2349 hwnd, msg, wParam, lParam );
2350 case WIN_PROC_32W:
2351 if (!proc->thunk.t_from16.proc) return 0;
2352 return WINPROC_CallProc16To32W( proc->thunk.t_from16.proc,
2353 hwnd, msg, wParam, lParam );
2354 default:
2355 WARN_(relay)("Invalid proc %p\n", proc );
2356 return 0;
2361 /**********************************************************************
2362 * CallWindowProc32A (USER32.18)
2364 * The CallWindowProc() function invokes the windows procedure _func_,
2365 * with _hwnd_ as the target window, the message specified by _msg_, and
2366 * the message parameters _wParam_ and _lParam_.
2368 * Some kinds of argument conversion may be done, I'm not sure what.
2370 * CallWindowProc() may be used for windows subclassing. Use
2371 * SetWindowLong() to set a new windows procedure for windows of the
2372 * subclass, and handle subclassed messages in the new windows
2373 * procedure. The new windows procedure may then use CallWindowProc()
2374 * with _func_ set to the parent class's windows procedure to dispatch
2375 * the message to the superclass.
2377 * RETURNS
2379 * The return value is message dependent.
2381 * CONFORMANCE
2383 * ECMA-234, Win32
2385 LRESULT WINAPI CallWindowProcA(
2386 WNDPROC func, /* window procedure */
2387 HWND hwnd, /* target window */
2388 UINT msg, /* message */
2389 WPARAM wParam, /* message dependent parameter */
2390 LPARAM lParam /* message dependent parameter */
2392 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2394 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2396 #if testing
2397 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2398 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2399 #endif
2401 switch(proc->type)
2403 case WIN_PROC_16:
2404 if (!proc->thunk.t_from32.proc) return 0;
2405 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2406 hwnd, msg, wParam, lParam );
2407 case WIN_PROC_32A:
2408 if (!proc->thunk.t_from16.proc) return 0;
2409 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2410 hwnd, msg, wParam, lParam );
2411 case WIN_PROC_32W:
2412 if (!proc->thunk.t_from16.proc) return 0;
2413 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2414 hwnd, msg, wParam, lParam );
2415 default:
2416 WARN_(relay)("Invalid proc %p\n", proc );
2417 return 0;
2422 /**********************************************************************
2423 * CallWindowProc32W (USER32.19)
2425 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
2426 WPARAM wParam, LPARAM lParam )
2428 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2430 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2432 #if testing
2433 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2434 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2435 #endif
2437 switch(proc->type)
2439 case WIN_PROC_16:
2440 if (!proc->thunk.t_from32.proc) return 0;
2441 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2442 hwnd, msg, wParam, lParam );
2443 case WIN_PROC_32A:
2444 if (!proc->thunk.t_from16.proc) return 0;
2445 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2446 hwnd, msg, wParam, lParam );
2447 case WIN_PROC_32W:
2448 if (!proc->thunk.t_from16.proc) return 0;
2449 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2450 hwnd, msg, wParam, lParam );
2451 default:
2452 WARN_(relay)("Invalid proc %p\n", proc );
2453 return 0;